브라우저 렌더링 과정을 알아보기 전에 먼저 DOM에 대해 알 필요가 있다.
HTML, XML과 같은 마크업 언어를 로봇에 비유한다면, 이런 로봇의 팔, 다리를 리모컨(자바스크립트와 같은 프로그래밍 언어)으로 조작할 수 있게끔 하는 인터페이스를 DOM(Document Object Model)이라 할 수 있다.
내가 좋아하는 개발자 유투버인 얄코님께서 DOM을 로봇을 조종하는 리모컨에 비유했다. 이 말을 듣고 DOM을 이해해버렸다. 확실히 누군가 이해하기 쉽게 알려주는 것도 재능의 영역인 듯 하다ㅎ. MDN이 소개하는 DOM을 살펴보자.
문서 객체 모델(The Document Object Model)은 HTML, XML 문서의 프로그래밍 인터페이스로서 문서의 구조화된 표현(structured representation)과 자바스크립트와 같은 프로그래밍 언어가 문서에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다. DOM은 계층적 구조를 가진 노드 트리로 구성된다.
Global Object(브라우저에서 현재 열려있는 창을 의미)로서 DOM, BOM, JavaScript의 모든 오브젝트들을 포함하는 가장 기본적인 오브젝트로 아래 두 가지 역할을 수행한다.
호스트 환경이 웹 브라우저인 경우
호스트와 호스트 환경
자바스크립트가 돌아가는 플랫폼을 호스트(host)라고 부르며, 브라우저, 웹서버 등 다양한 것들이 호스트가 될 수 있다. 각 플랫폼은 해당 플랫폼에 특정되는 기능을 제공하는데, 자바스크립트 명세서에서는 이를 호스트 환경이라고 부른다.
호스트 환경은 랭귀지 코어(ECMAScript)에 더해 플랫폼 종속적인 객체 및 함수를 제공한다. 예를 들어, 웹브라우저는 웹페이지를 제어하기 위한 수단을 제공하고, Node.js는 서버 사이드 기능을 제공한다.
Document Object(문서 객체)란 html, head, body와 같은 태그들을 javascript가 이용할 수 있는 (메모리에 보관할 수 있는) 객체를 의미하며, 페이지의 기본 진입점 역할을 한다. 웹 페이지 내의 모든 콘텐츠를 객체로 나타내며, 이 객체를 이용해 페이지 내 모든 요소를 변경, 특정 요소를 생성할 수 있다.
프로그래머가 작성한 html 파일을 브라우저가 읽게 되며, html 내 태그들을 각각의 노드(브라우저가 이해할 수 있는 오브젝트)로 변환하는 과정을 수행한다.
HTML을 지탱하는 것은 태그(tag)이다. DOM에 따르면 모든 html 태그는 객체이며, 태그 내의 문자 역시 객체이다. 이런 모든 객체는 자바스크립트를 통해 접근할 수 있고, 페이지를 조작할 때 이 객체를 사용한다. html 태그는 그에 상응하는 DOM tree 요소를 지닌다.
브라우저에서 DOM과 프로그래머가 정의한 CSS를 병합하여 만든 Object Model
DOM + CSSOM 후, 브라우저에서 사용자에게 직접 보여지는 태그들만 선별하여 렌더링한 것이다. (head태그, display: none인 태그 등의 요소들은 제외된다.)
opacity: 0, visibility: hidden
VSdisplay: none
앞의 두 가지의 경우 렌더 트리에 포함되지만, 마지막의 경우는 포함되지 않는다. 따라서 상황에 맞는 속성을 적용해야 렌더링 과정에서 불필요한 성능 저하가 일어나지 않는다. (이 부분은 프론트엔드 단골 면접 질문이니 잘 알고 넘어가자. 실제로 받은적 있다..ㅎ)
브라우저 객체 모델(Browser Object Model, BOM)은 문서 이외의 모든 것을 제어하기 위해 브라우저(호스트 환경)가 제공하는 추가 객체를 나타낸다.
navigator.userAgent
현재 사용 중인 브라우저 정보 제공navigator.platform
브라우저가 실행 중인 운영체제 정보 제공💡 프로그래머가 작성한 웹 애플리케이션을 브라우저가 사용자에게 보여주기까지의 과정
CRP(Critical Rendering Path)은 브라우저가 HTML, CSS, Javascipt를 화면에 픽셀로 변화하는 일련의 단계로, 픽셀 파이프라인(Pixel Pipeline)이라고도 한다.
HTML 파일을 브라우저가 이해할 수 있는 파일로 변환하는 단계
requests/response
브라우저가 서버에 HTML 파일을 요청 후 응답을 받는다.
loading
HTML 파일(데이터)을 받아온다.
scripting
HTML 파일을 한 줄씩 읽는 과정이며(파싱), HTML 중간에 스크립트나 css, 이미지가 존재하는 경우에는 HTML 파싱이 중단된다.
HTML→DOM
과정: 바이트→문자(html의 meta의 charset을 참조)→토큰→노드→DOM
CSS→CSSOM
Javascript→AST(Abstract Syntax Tree)
스크립트 파싱 과정에 대해서 더 알고 싶다면 다음 포스팅을 참고해주세요.
rendering
DOM과 CSSOM을 결합하여 render tree(렌더 트리)를 생성한다. 이는 화면에 표시되는 각 요소의 레이아웃을 계산하는 데 사용된다.
layout
각각의 요소들이 어느 위치에 얼마나 크게 표시될 것인지를 결정한다.
=> layout이 자주 일어나면 성능 저하가 일어난다.
painting
브라우저는 성능개선을 위해서 구성 요소를 여러 개의 레이어로 나눈 후, 레이어별로 paint를 준비한다.
composition
각 레이어를 합성한다.
reflow와 repaint가 브라우저 성능과의 관계
reflow는 브라우저 주요 렌더링 경로의 모든 단계를 모두 재실행하고, repaint의 경우도 레이아웃을 제외하고 재실행한다. 따라서 reflow와 repaint 모두 렌더링 성능에 영향을 줄 수 있다.
하드웨어 가속
CPU에서 처리해야 할 작업을 GPU에 위임하여 더욱 효율적으로 처리하는 방법이다. transform, opacity와 같은 css 속성을 사용하면, 요소를 별도의 레이어로 분리하고 작업을 GPU에 위임하여 처리함으로써 레이아웃 단계와 페인트 단계를 건너뛸 수 있다. 단, 레이어가 많아지면 그만큼 메모리 소모가 많아진다는 점을 유의해야 한다.
참고자료
DOM 소개 - Web API | MDN
The HTML DOM API - Web API | MDN
[10분 테코톡] 러기의 브라우저의 동작
Render-tree Construction, Layout, and Paint | Web Fundamentals