[웹] 브라우저의 렌더링 과정 with CRP (feat. HTML 로봇을 움직이게 하는 리모컨, DOM)

Woonil·2025년 2월 26일
0

목록 보기
3/6
post-thumbnail

브라우저 렌더링 과정을 알아보기 전에 먼저 DOM에 대해 알 필요가 있다.

HTML, XML과 같은 마크업 언어를 로봇에 비유한다면, 이런 로봇의 팔, 다리를 리모컨(자바스크립트와 같은 프로그래밍 언어)으로 조작할 수 있게끔 하는 인터페이스를 DOM(Document Object Model)이라 할 수 있다.

내가 좋아하는 개발자 유투버인 얄코님께서 DOM을 로봇을 조종하는 리모컨에 비유했다. 이 말을 듣고 DOM을 이해해버렸다. 확실히 누군가 이해하기 쉽게 알려주는 것도 재능의 영역인 듯 하다ㅎ. MDN이 소개하는 DOM을 살펴보자.

문서 객체 모델(The Document Object Model)은 HTML, XML 문서의 프로그래밍 인터페이스로서 문서의 구조화된 표현(structured representation)과 자바스크립트와 같은 프로그래밍 언어가 문서에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다. DOM은 계층적 구조를 가진 노드 트리로 구성된다.

🤔개념

window

Global Object(브라우저에서 현재 열려있는 창을 의미)로서 DOM, BOM, JavaScript의 모든 오브젝트들을 포함하는 가장 기본적인 오브젝트로 아래 두 가지 역할을 수행한다.

  • 자바스크립트 코드의 전역 객체
  • 브라우저 창을 대변하며, 이를 제어하는 메서드 제공

    호스트 환경이 웹 브라우저인 경우

    호스트와 호스트 환경
    자바스크립트가 돌아가는 플랫폼을 호스트(host)라고 부르며, 브라우저, 웹서버 등 다양한 것들이 호스트가 될 수 있다. 각 플랫폼은 해당 플랫폼에 특정되는 기능을 제공하는데, 자바스크립트 명세서에서는 이를 호스트 환경이라고 부른다.
    호스트 환경은 랭귀지 코어(ECMAScript)에 더해 플랫폼 종속적인 객체 및 함수를 제공한다. 예를 들어, 웹브라우저는 웹페이지를 제어하기 위한 수단을 제공하고, Node.js는 서버 사이드 기능을 제공한다.

DOM

Document Object(문서 객체)란 html, head, body와 같은 태그들을 javascript가 이용할 수 있는 (메모리에 보관할 수 있는) 객체를 의미하며, 페이지의 기본 진입점 역할을 한다. 웹 페이지 내의 모든 콘텐츠를 객체로 나타내며, 이 객체를 이용해 페이지 내 모든 요소를 변경, 특정 요소를 생성할 수 있다.

브라우저의 html 파일로의 접근

프로그래머가 작성한 html 파일을 브라우저가 읽게 되며, html 내 태그들을 각각의 노드(브라우저가 이해할 수 있는 오브젝트)로 변환하는 과정을 수행한다.

DOM tree

HTML을 지탱하는 것은 태그(tag)이다. DOM에 따르면 모든 html 태그는 객체이며, 태그 내의 문자 역시 객체이다. 이런 모든 객체는 자바스크립트를 통해 접근할 수 있고, 페이지를 조작할 때 이 객체를 사용한다. html 태그는 그에 상응하는 DOM tree 요소를 지닌다.

CSSOM

브라우저에서 DOM과 프로그래머가 정의한 CSS를 병합하여 만든 Object Model

Render Tree

DOM + CSSOM 후, 브라우저에서 사용자에게 직접 보여지는 태그들만 선별하여 렌더링한 것이다. (head태그, display: none인 태그 등의 요소들은 제외된다.)

opacity: 0, visibility: hidden VS display: none

앞의 두 가지의 경우 렌더 트리에 포함되지만, 마지막의 경우는 포함되지 않는다. 따라서 상황에 맞는 속성을 적용해야 렌더링 과정에서 불필요한 성능 저하가 일어나지 않는다. (이 부분은 프론트엔드 단골 면접 질문이니 잘 알고 넘어가자. 실제로 받은적 있다..ㅎ)

BOM

브라우저 객체 모델(Browser Object Model, BOM)은 문서 이외의 모든 것을 제어하기 위해 브라우저(호스트 환경)가 제공하는 추가 객체를 나타낸다.

  • navigator: 브라우저와 운영체제에 대한 정보 제공
    • navigator.userAgent 현재 사용 중인 브라우저 정보 제공
    • navigator.platform 브라우저가 실행 중인 운영체제 정보 제공
  • location: 현재 URL을 읽을 수 있게 해주며, 새로운 URL로 변경할 수 있게 한다.

CRP(Critical Rendering Path)

CPR이란 브라우저가 HTML, CSS, Javascipt를 화면에 픽셀로 변화하는 일련의 단계로, 픽셀 파이프라인(Pixel Pipeline)이라고도 한다. 한마디로 '브라우저가 웹 애플리케이션을 사용자에게 보여주기까지의 과정'라 할 수 있다.

Construction🔧

HTML 파일을 브라우저가 이해할 수 있는 파일로 변환하는 단계

순서

  1. requests/response: 브라우저가 서버에 HTML 파일을 요청 후 응답을 받는다.

  2. loading: HTML 파일(데이터)을 받아온다.

  3. scripting: HTML 파일을 한 줄씩 바이트(byte) 단위로 읽는 과정이며(파싱), HTML 중간에 스크립트나 css, 이미지가 존재하는 경우에는 HTML 파싱이 중단된다.

    • HTML→DOM: 바이트 → 문자(html의 meta의 charset을 참조) → HTML 토큰(태그와 텍스트 및 속성) → 노드 → DOM 트리

    • CSS→CSSOM: 바이트 -> 문자 -> CSS 규칙, 즉 선택자(selector)와 선언(declaration) -> CSSOM 트리

    • Javascript→AST(Abstract Syntax Tree)

  4. rendering: DOM과 CSSOM을 결합하여 render tree(렌더 트리)를 생성한다. render tree의 각 노드는 DOM 트리의 요소와 연결되며, CSSOM 트리에서 해당 요소에 적용된 스타일 정보를 포함한다. 즉, render tree는 HTML 문서의 구조와 각 요소의 스타일 정보를 모두 포함한 트리이다. render tree는 화면에 표시되는 각 요소의 레이아웃을 계산하는 데 사용된다.

Operation⚙️

순서

  1. layout: 각각의 요소들이 어느 위치에 얼마나 크게 표시될 것인지가 뷰포트 크기를 바탕으로 계산된다. layout이 자주 일어나면 성능 저하가 일어날 수 있다.
  2. painting: 브라우저는 성능개선을 위해서 구성 요소를 여러 개의 레이어로 나눈 후, 레이어별로 paint를 준비한다. 복잡한 그래픽이나 애니메이션이 포함된 경우 paint 작업이 많아져 성능 저하가 일어날 수 있다.
  3. composition: 브라우저는 GPU를 활용하여 각 레이어를 빠르게 합성한다.

reflow✏️ & repaint🎨

  • reflow: 브라우저가 페이지의 레이아웃을 다시 계산하는 과정으로, 생성된 DOM 노드의 레이아웃 수치(너비, 높이, 위치 등) 변경 시에 영향을 받은 모든 노드의 수치를 다시 계산하여 렌더 트리를 재생성한다.
    • 실행 시점
      • DOM 엘리먼트 추가, 제거, 변경
      • CSS 스타일 추가, 제거, 변경 ex) position, display, width, float, height, font-family, top, left, font-size, font-weight, min-height, margin, padding, border 등
      • hover, 텍스트 입력 등의 사용자 상호작용 발생
  • repaint: reflow 과정 이후 재생성된 렌더 트리를 다시 그리는 과정으로, reflow 과정 결과를 화면에 다시 그리는 과정이다.
    • 실행 시점
      • 가시성(opacity, background-color, visibility, outline 등)이 변경되는 순간

reflow, repaint와 브라우저 성능과의 관계

reflow는 브라우저 주요 렌더링 경로의 모든 단계를 모두 재실행하고, repaint의 경우도 레이아웃을 제외하고 재실행하므로 모두 렌더링 성능에 영향을 줄 수 있다. 따라서 reflow와 repaint를 잘 관리하는 것이 성능 최적화에 도움이 되며, 아래와 같은 최적화 방법이 있다.

위에서 살펴본 것과 같이, reflow를 유발하는 CSS 속성 사용을 최소화해야 한다. 가능한 한 CSS 스타일을 미리 설정해 초기 페이지 로드 시에만 계산이 이루어지도록 하고, 이후에는 변경하지 않는 것이 좋다.

CSS 에니메이션 최적화: 하드웨어 가속이란 CPU에서 처리해야 할 작업을 GPU에 위임하여 더욱 효율적으로 처리하는 방법이다. transform, opacity 와 같은 css 속성을 사용하면, 요소를 별도의 레이어로 분리하고 작업을 GPU에 위임하여 처리함으로써 레이아웃 단계와 페인트 단계를 건너뛸 수 있다. 단, 레이어가 많아지면 그만큼 메모리 소모가 많아진다는 점을 유의해야 한다.

will-change 속성 사용: 브라우저에 특정 요소가 변경될 것이라고 미리 알려줄 수 있다. 예를 들어, will-change: transform 으로 미리 GPU에서 요소를 준비하게 하여 reflow와 repaint에 미치는 영향을 줄일 수 있다. 하지만 will-chagne 속성을 너무 자주 사용하면 메모리 낭비가 발생하므로 필요한 요소에만 적용할 필요가 있다.

참고자료

매일메일 (기술면접 메일 서비스) - 'reflow와 repaint의 차이점에 대해서 설명해주세요.', '브라우저 렌더링 파이프라인에 대해서 설명해주세요.'
DOM 소개 - Web API | MDN
The HTML DOM API - Web API | MDN
[10분 테코톡] 러기의 브라우저의 동작
Render-tree Construction, Layout, and Paint | Web Fundamentals

profile
프론트 개발과 클라우드 환경에 관심이 많습니다:)

0개의 댓글