Website는 어떻게 보여주게 될까? — (2)

박성룡 ( Andrew park )
7 min readJul 31, 2017

--

웹페이지가 렌더링되는 과정에 대해 설명해보고자 합니다.

들어가기전에

  1. 브라우저는 어떻게 문서를 표현할까?
  2. 브라우저 구조를 알아보자.
  3. DOM 트리를 구축하자.
  4. 렌더링 트리를 만들어보자.
  5. 실제로 그려보자.
  6. 느낀점

1. 브라우저는 어떻게 문서를 표현할까?

앞서 우리는 브라우저에서 서버로 Request를 요청하여 서버에서 브라우저에서 Response로 웹사이트 문서 정보를 받아오는것에 대해 알아보았습니다. 그렇다면 브라우저는 <HTML> 문서를 어떻게 화면에 표현하게 되는것일까요?

익스플로러 화면

먼저 브라우저는 서버에서 받아온 HTML 문서를 W3C(World Wide Web Consortium)에서 정한 명세를 따라 HTML를 해석합니다. 그리고 해석된 문서는 브라우저 렌더링 엔진에 따라서 브라우저에 사용자가 볼 수 있도록 그리기 시작합니다. 하지만 브라우저 별로 화면에 그리는 방식은 다릅니다. 대표적으로 Chrome과 Safari는 Webkit 엔진을 사용하며, 파이어폭스는 Gecko 엔진을 사용합니다.

브라우저마다 그리는 법은 달라도 비슷하게 보여줄수 있는 까닭은 W3C에서 정한 웹 표준 명세가 있기 때문입니다. 때문에 파어폭스/사파리/크롬/익스플로러가 비슷한 형태로 구현이 가능합니다. 하지만 표준 명세이기 때문에, 특정 기능의 경우 브라우저 별로 차이가 있을 수 있습니다.

그렇다면 브라우저는 문서를 어떻게 그리게 되는것일까요? 해당 과정을 알기위해서는 먼저 브라우저의 기본 구조를 알아야 합니다.

2. 브라우저 구조를 알아보자.

http://taligarsiel.com/Projects/howbrowserswork1.htm

브라우저는 크게 화면을 조정하는 영역과 데이터를 조작하는 영역으로 구분할 수 있습니다.

  1. 사용자 인터페이스 : 사용자가 브라우저에서 직접조작 할 수 있는 영역입니다. (앞으로가기, 뒤로가기, 즐겨찾기 등등)
  2. 브라우저엔진 : 사용자 인터페이스가 렌더링 엔진에 쿼리를 전달할 수 있게 조작을 담당합니다.
  3. 렌더링 엔진 : html과 css 문서를 파싱 / 해석 하여 화면에 표현합니다.
  4. Networking : Http 요청을 할 수 있으며, 네트워크 호출할 수 있습니다.
  5. Javascript 해석기 : Javascript 코드를 해석하고 실행 합니다.
  6. UI Backend: select / input 등 기본적인 위젯을 그리는 인터페이스 입니다.
  7. 자료 저장소 : Cookie, Local storage등 모든 자료를 저장하는 영역입니다.

먼저, 브라우저는 서버로부터 HTML 문서를 모두 다운로드 받습니다. 다운로드가 완료되면, 렌더링 엔진이 HTML 문서를 파싱해 렌더링 트리를 생성합니다. 렌더링 트리 생성이 완료되면, UI Backend에서 각노드를 확인하며, 화면에 그리기 시작합니다.

Webkit main flow

웹킷과 게코의 렌더링 방식은 크게 차이가 없습니다.

Mozilla’s Gecko rendering engine main flow

게코에 콘텐츠 싱크는 과정이 있지만 DOM 요소를 생성함에 있어 웹킷과 큰 차이는 없습니다.

3. DOM 트리를 구축하자.

HTML문서를 받아오면, 렌더링엔진이 HTML파서를 이용해 파싱을 시작합니다. 그리고 파싱이 완료되면 문서 구조는 parse tree로 생성됩니다. 파싱하는 문서는 어휘 분석과 구문 분석으로 해석합니다. 어휘 분석은 자료의 유요한 토큰(의미없는 문자와 공백)을 분해하고, 구문 규칙으로 문서 구조를 분석합니다. 어휘 분석으로 html 태그를 토큰으로 파싱합니다. 해당 과정을 통해 파서트리가 만들어 집니다.

from source document to parse trees

파스트리를 기반으로, DOM 요소와 속성 노드를 가지는 DOM 트리를 생성합니다.

<html>
<body>
<p>Hello World</p>
<div><img /></div>
</body>
</html>

DOM tree of the example markup

트리 생성이 끝나면 브라우저는 화면을 그리기 시작하며, 문서는 ready 상태가 되고 load 이벤트가 발생됩니다. DOM 로드가 완료되면 Javascript를 다운로드하기 시작하며, Javascript도 파싱합니다. 하지만 CSS 파서는 DOM Tree에 영향을 주지 않기 때문에 문서를 파싱하는 동시에 파싱을 진행합니다.

parsing CSS

4.렌더 트리를 만들어보자.

DOM 트리가 구축이되어가는 동안 브라우저는 DOM 트리를 기반으로 렌더 트리를 생성합니다. 문서를 시각적인 구성 요소로 만들어주는 역할을 합니다. 하지만 1:1로 대응되지는 않습니다. 대표적인 예로 <head>나 display:none, hidden 은 렌더 트리에 포함되지 않습니다.

The render tree and the corresponding DOM tree

스타일은 브라우저에서 제공하는 기본 스타일 시트를 따라갑니다. 적용된 스타일 속성에 따라 렌더 트리를 구축합니다.

5. 실제로 그려보자.

렌더트리가 생성되면, 이를 페이지에 배치하기 시작하는데 이를 리플로(reflow)라 부릅니다.

브라우저 창의 0,0 위치부터 시작하여, 각 영역에 해당하는 viewport만큼의 면적을 갖으며 배치됩니다. 만약 일부 영역에 변경이 일어난다면, 전역 배치와 점증 배치가 일어납니다.

전역 배치란 모든 렌더링에 영향을 주는 전역 스타일 변경일 경우 일어나게 되며, 점증 배치란 더티 렌더러가 배치되는 경우 비동기적으로 일어납니다. 더티 렌더러란, 변경 요소를 브라우저가 지정하여 특정 요소만 변경함을 의미합니다. 배치는 부모 렌더러와 자신 렌더러를 함께 판단하여 배치합니다.

브라우저는 렌더트리를 활용해 화면에 그리기 시작하는데, 이때 렌더러의 paint 메서드를 호출하며, UI Backend 요소를 이용해 그리기 시작합니다. 각각의 요소들은 블록 렌더러 순서에 따라 그리기 시작합니다.
1.배경 > 2.배경 이미지 > 3. 테두리 > 4. 자식 > 5. 아웃라인

그리기가 끝난 화면

모든 요소가 그려지고나서 브라우저에서 일부 변경이 생길경우 리플로우(reflow)와 리페인트(repaint)가 발생합니다. 리페인트는 변경된 스타일을 다시 적용하는것을 의미합니다. 크기와 위치가 변경됬다면 리플로우도 발생됩니다.

6. 느낀점

Tail Garsiel의How browsers work의 원문과 이를 해석한 네이버 D2의 브라우저는 어떻게 동작하는가?를 참고하였습니다. 전체적인 내용보다는 렌더링되는 과정에 중점을 두어 요약했습니다. 또 한번 부족함을 많이 느끼게되는 공부였습니다. 다음 공부로 렌더링 성능 개선에 중점이 되는 공부를 써봐야겠습니다.

  1. 태그는 최대 20 중첩만 허용합니다.
  2. 크롬 웹킷의 경우 유효하지 않는 구문도 브라우저가 잘 해석해 줍니다. 때문에 다른브라우저에서는 완전히 다른 문서가 만들어 질 수 있으니 꼼꼼히 파악해야합니다.
  3. 리플로우와 리페인트를 최소화 하기위해서 한번에 처리할 수 있게 만드는것이 중요합니다.

더 많은 팁을 얻게되면 업데이트 하겠습니다.

참고자료

  1. http://taligarsiel.com/Projects/howbrowserswork1.htm
  2. http://d2.naver.com/helloworld/59361

--

--