이번 포스팅에선 브라우저가 화면을 렌더링 하는 과정에 대해서 알아보겠다.
렌더링이란 HTML, CSS, JavaScript 등 개발자가 작성한 문서들을 브라우저가 화면에 그려주는 동작을 말한다.
렌더링에 관해 얘기하기 전에 브라우저 구조에 대해 알아보자.
렌더링 엔진의 역할은 요청받은 내용을 브라우저 화면에 나타내는 일을 한다. HTML, CSS, JavaScript 등의 파일을 브라우저가 화면에 표시할 수 있도록 변환하여 픽셀 단위로 나타낸다.
브라우저마다 사용하는 렌더링 엔진들이 다릅니다.
렌더링 엔진이 브라우저마다 다르기 때문에, 같은 소스가 브라우저마다 다르게 그려지는 크로스 브라우징 이슈가 발생하게 됩니다.(자바스크립트 엔진이 달라 발생하기도 합니다.)
브라우저 | 렌더링 엔진 |
---|---|
IE | Trident |
Edge | EdgeHTML, Blink |
Chrome | Webkit, Blink(버전 28 이후) |
Safari | Webkit |
FireFox | Gecko |
크롬 브라우저는 사파리 브라우저에서 사용하는 Webkit을 사용하다가 버전 28 이후 Webkit 소스를 Fork 하여 Blink 엔진을 만들어 사용하고 있다.
1. HTML을 파싱하여 DOM 트리를 생성한다.
2. CSS를 파싱하여 스타일 규칙( CSSOM )을 생성한다.
3. DOM과 CSSOM을 이용하여 Render 트리를 생성한다.
4. Render 트리를 이용해 노드의 정확한 위치와 크기를 계산하는 과정 (Layout) 작업을 진행한다.
5. Render 트리를 이용해 각 노드를 화면의 실제 픽셀로 나타내는 과정을 Paint 작업을 진행한다.
파싱은 서버로부터 전송받은 문서의 문자열을 브라우저가 이해할 수 있는 구조로 변환하는 과정을 말한다.
아래의 그림은 HTML문서를 전달받아 브라우저가 이해할 수 있는 형태로 파싱하는 과정을 자세하게 나타낸 그림이다.
DOM 트리를 생성하는 과정과 마찬가지로, 수신된 CSS 규칙을 브라우저가 이해하고 처리할 수 있는 형식으로 변환해야 한다. 따라서 HTML 대신 CSS에 대해 HTML 프로세스를 반복합니다.
브라우저는 DOM을 생성하는 동안 외부 CSS를 참조하는 태그를 만나게 되면 브라우저에 리소스를 요청합니다. CSS의 원시 바이트(raw bytes)가 문자열로 변환된 후 차례로 토큰과 노드로 변환되고 마지막으로 CSSOM(CSS Object Model)이라는 트리 구조를 만듭니다.
Attachment에서는 브라우저가 DOM 및 CSSOM을 '렌더링 트리'에 결합하는 작업을 수행한다. 이 과정을 통해 만들어진 Render 트리는 페이지에 표시되는 모든 DOM 콘텐츠와 각 노드에 대한 모든 CSSOM 스타일 정보를 가지고 있다.
Layout 단계는 브라우저의 뷰포트(Viewport) 내에서 각 노드들의 정확한 위치와 크기를 계산한다.
즉, 생성된 Render Tree 노드들이 가지고 있는 스타일과 속성에 따라서 브라우저 화면의 어느위치에 어느크기로 출력될지 계산하는 단계이다. Layout 단계를 통해 %, vh, vw와 같이 상대적인 위치, 크기 속성은 실제 화면에 그려지는 pixel단위로 변환된다.
Layout 계산이 완료되면 이제 요소들을 실제 화면을 그리게 된다. 이전 단계에서 이미 요소들의 위치와 크기, 스타일 계산이 완료된 Render Tree 를 이용해 실제 픽셀 값을 채워넣게 된다. 이 때 텍스트, 색, 이미지, 그림자 효과등이 모두 처리되어 그려진다.
이 때 처리해야 하는 스타일이 복잡할수록 Paint 단계에 소요되는 시간이 늘어나게 된다.
웹 성능을 최적화 할 수 있는 방법에는 어떤 것이 있을까?
Reflow 와 Repaint를 통해 조금이나마 최적화를 진행할 수 있다.
어떤 액션이나 이벤트에 따라 html 요소의 크기나 위치등 레이아웃 수치를 수정하면 그에 영향을 받는 자식 노드나 부모 노드들을 포함하여 Layout 과정을 다시 수행하게 된다. 이렇게 되면 Render Tree와 각 요소들의 크기와 위치를 다시 계산하게 되고, 이 과정을 Reflow라고 합니다.
Reflow가 일어나는 경우
Reflow가 일어나는 대표적인 속성
position, width, height, left, top, right, bottom, margin, padding, border, border-width,
clear, display, float, font-family, font-size, font-weight, line-height, min-height,
overflow, text-align, vertical-align, white-space...
렌더링 과정에서도 알 수 있듯이 Reflow 과정만으론 화면에 실제로 반영되지 않는다. Reflow 과정이 일어난 후, 화면에 다시 그리는 작업을 Repaint라고 한다.
하지만 반드시 Reflow 와 Repaint가 같이 일어나는 것은 아니다. background-color, visibility 등 레이아웃에 영향을 주지 않는 스타일 속성이 변경되었을 경우에는 Repaint만 발생한다.
Repatin가 일어나는 대표적인 속성
background, background-image, background-position, background-repeat, background-size,
border-radius, border-style, box-shadow, color, line-style, outline, outline-color,
outline-style, outline-width, text-decoration, visibilty...
브라우저 렌더링 과정
아직까지 사용자가 많은 대규모 웹 서비스를 운영해본 경험이 없기 때문에 크게 성능 개선을 고려해야할 필요성을 느끼지 못했다.
하지만 앞으로 프론트엔드 개발자로써 다양하고 복잡한 요구사항에 대응해야 하는 경우가 많이 발생하고, 화면이 실시간으로, 수 많은 변경이 빠르게 일어나야 하는 경우를 발생하기 때문에 이러한 기본 지식을 공부해두는 것이 도움이 될 것 같다.
참고자료