본문 바로가기

개발 이야기/front-end

[Browser] 브라우저가 화면을 그리는 법 Render Tree, layout, paint | Browser Rendering

이번 포스팅은 파싱에 이어 렌더 트리구축, 배치, 페인팅 단계에 대해 다룹니다. 

 

Gecko source: scientificamerican

 

 

 

[Browser] 브라우저가 화면을 그리는 법#1 파싱 | Browser Rendering - Parsing

1990년대 초 World Wide Web을 시작으로 IE, Mosaic, Netscape 등 여러 브라우저가 나오면서 브라우저 시장은 춘추전국시대를 맞았습니다. *WordSideStory 데이터에 따르면 2002년에 IE는 약 95%의 사용점유율을..

another-light.tistory.com

 


 

"렌더링 과정"

 

아래는 렌더링 엔진이 렌더링하는 과정입니다. 저번에는 parser를 통해서 파싱하고, DOM Tree를 구축하는 단계까지 알아보았습니다. 브라우저는 DOM 트리를 구축하면서 브라우저는 렌더 트리를 구축합니다. 웹킷과 게코에서는 렌더 트리를 구성하는 엘리먼트 각각을 renderer(reder object) 또는 frame이라고 부르며 이들은 시각적인 요소를 담당합니다.

 

 

(좌) webkit, (우) gecko source: html5rocks

 

1. 스타일 속성 계산

 

웹킷과 게코에서는 DOM 트리와 Render 트리 사이에 각각 Attachment, Frame Constructor 단계가 있는걸 보실 수 있습니다. 

이는 DOM 트리에 있는 엘리먼트의 스타일 속성을 계산하기 위함입니다. 태그의 인라인 스타일 속성이나 스타일 시트를 로드하여 스타일을 계산합니다. 

 

 

 

2. 렌더 트리 구축

 

html, body 태그를 렌더 트리의 루트 오브젝트로 생성합니다. 이것을 웹킷에서는 rederview, 게코에서는 viewport frame이라고 부릅니다.이후 하위 오브젝트는 나머지 DOM 노드로 구성합니다. 이때 렌더 트리와 DOM 트리가 일대일 관계가 아니라는 것에 주목하셔야 합니다. 

 

- DOM 트리에 있어도 display: none 속성이 있거나 head 등 표시되지 않는 태그의 경우 화면에 표시되지 않을 수 있습니다.

- 또한 position이 absolute 또는 fixed인 경우 렌더 트리에서의 오브젝트의 위치는 DOM 트리에서의 위치와는 달라질 수 있습니다.

 

 

 

3. 배치

 

렌더 오브젝트가 트리에 추가될 때, 화면에 그려질 크기와 위치 정보가 없습니다. 이런 값을 계산하는 것을 웹킷에선 layout, 게코에서는 reflow라고 합니다. 아래의 영상을 보면 게코의 배치 과정을 볼 수 있습니다. 

 

 

source :mozila's gecko reflow process, from youtube

 

 

렌더 오브젝트는 아래와 같은 형태로 구성되어있습니다. 배치를 위해 위치, 너비, 높이 등의 정보를 갖고 있으며, layout, paint 메서드를 갖고 있습니다. rect는 시각적 요소에 따라 배치될 css 박스를 말합니다.

 

class RenderObject{
  virtual void layout();
  virtual void paint(PaintInfo);
  virtual void rect repaintRect();
  Node* node;  //the DOM node
  RenderStyle* style;  // the computed style
  RenderLayer* containgLayer; //the containing z-index layer
}

 

배치 과정은 아래와 같습니다.

 

- 부모 오브젝트가 자신의 너비를 계산

- 자식 오브젝트들의 x, y 좌표를 구해 위치 계산. 만약 자식 오브젝트가 *dirty-bit 상태라면 자식의 layout 메서드를 호출합니다.

- 패딩, 마진 등을 계산하여 부모 오브젝트가 자신의 높이 계산 

- dirty-bit 플래그 제거

 

*dirty-bit 시스템: 전체 렌더 트리를 변경하지 않고, 필요한 오브젝트만 변경하기 위해 오브젝트에 dirty 플래그를 표시하는 것을 말합니다.

하지만 폰트 사이즈 변경, 화면 크기 변경 등 전체적으로 변경이 필요한 경우도 있습니다. 크기 변경 또는 위치 변화인 경우 최적화를 위해 캐시를 가져옵니다.

 

 

 

"paint"

 

배치가 끝나면 렌더 오브젝트의 paint 메서드가 호출됩니다. paint는 UI backend layer를 사용하여 그려집니다. paint 역시 전체 또는 필요한 일부만 그리기도 합니다. 렌더링 엔진은 네트워킹을 제외하고 대부분은 단일 스레드로 동작합니다. 크롬은 탭 각각에 프로세스가 독립적으로 존재하는 멀티 프로세스입니다. 이 스레드는 변경 사항이 있으면 바로 반영하기 위해 항상 대기하고 있습니다. 

 

 

source: gecko reflow | 위키피디아 사이트 reflow 과정

 

 

painting은 stacking contexts라는 스택에 명령을 쌓아 실행합니다. 스택은 LIFO(Last-In, First-Out), 즉 후입선출이기 때문에 나중에 들어온 것이 먼저 실행됩니다. stack에는 배경 색 - 배경 이미지 - 테두리 - 자식 - 아웃라인 순으로 명령이 쌓입니다. 즉 실행은 아웃라인 - 자식 - 테두리 - 배경 이미지 - 배경색이 됩니다.

 

 

 

 

"references"

 

브라우저 동작 방식

 

- www.html5rocks.com/en/tutorials/internals/howbrowserswork/#Layout