- 브라우저의 렌더링(작동)원리에 대해서 이해한다.
- Reflow가 발생하는 이유와 방지 방법에 대해서 이해한다.
- 렌더링 최적화에 대해서 고민해본다.
브라우저의 작동 원리에 대해서 알아보기 전에 먼저 웹 브라우저의 구조를 살펴보았다. 이 중에서도 HTML과 CSS를 파싱하여 요청한 웹 페이지를 표시하는 렌더링 엔진에 대해서 더 알아볼 예정이다.
렌더링 엔진은 다음과 같은 목표를 가진다.
나는 보통 웹 페이지에 들어가기 위해 주소 url에 웹 페이지 주소를 입력하고 엔터를 누른다. 그러면 어떤 일이 발생할까?
먼저 웹 페이지 해당 서버에 요청(request)를 보내게 된다.
그러면 서버는 요청을 받고 응답(response)으로 HTML 데이터를 내려주게 되고 이 HTML 데이터가 브라우저 하나의 화면을 그려내는 과정을 중요 렌더링 경로(Critical Rendering Path)라고 부른다. 그러면 나는 그려내는 과정을 한 번 살펴보자.
그러면 각 단계마다 더 구체적으로 알아보자.
서버에 요청을 하고 응답으로 HTML 데이터를 받아온다고 설명했었다. 그러면 이 HTML을 파싱하게 되는데, 파싱이란 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미한다.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styled.css">
</head>
<body>
<h1>안녕하세요 이우성입니다!</h1>
</body>
</html>
파싱을 하게 되면 이제 HTML표준에 따라 문자열을 토큰(Token)화 한다. 토큰화는 위에 예시 코드안에서 <html>
은 StartTag를 뜻하고, </html>
는 EndTag를 뜻하는 것과 같이 고유 토큰으로 변환되는 것을 말한다. 그리고 이 모든 과정이 끝나면 DOM Tree가 생성이 된다.
HTML을 파싱하다가 CSS 링크를 만나면 CSS파일을 요청해서 CSSOM(CSS Object Model) Tree를 생성한다. CSSOM은 DOM이 화면에 어떻게 표시되는지 알려주는 역할을 한다.
CSSOM을 구성하는 것 까지 끝나야 Rendering 과정을 시작할 수 있다. 즉 Render Tree를 생성할 수 있다는 뜻이다. 그렇기 때문에 CSS는 Rendering의 blocking 요소라고도 부른다.
CSSOM을 만들었으니 이제 DOM과 CSSOM을 결합하여 Render Tree를 생성하게 된다. Render Tree는 화면에 표시되어야 할 모든 노드의 컨텐츠, 스타일 정보를 포함하는 트리이다.
렌더와 관련된 모든 것을 Render Tree에 포함시키는데, 이때 display: none
같이 영향이 가지 않는 것은 Render Tree에 추가되지 않는다. 마찬가지로 화면에 보이지 않는 meta
태그 등도 추가되지 않는다.
Render Tree가 생성되면 이제 Render Tree 배치 과정을 거친다. 이 과정은 view port 내에서 요소들의 정확한 위치와 크기를 계산하는 과정을 일컫는다.
(CSS Box model에 따라 여백이나 높이, 너비 등을 계산할 때를 말한다.)
%
, vh
, vw
와 같이 상대적인 속성들은 실제 화면에 그려지는 px단위로 변환되며 이 과정을 Layout 또는 Reflow라고 한다.
위치나 크기의 계산이 끝났으면 이제 Render Tree의 각 노드들을 사용해서 화면을 그리게 되는데 이 과정을 RePaint라고 하며, 이 때 Render Tree에 포함된 모든 요소들이 실제 픽셀로 그려지게 된다.
지금까지 HTML과 CSS만으로 렌더링 과정이 어떻게 진행되는지 살펴보았다.
그러면 여기서 자바스크립트가 실행되면서 CSS가 변경되거나 애니메이션이 재생되었을 때는 어떻게 될까?
Layout
이 발생하는 경우: 요소의 크기나 브라우저 창이 변경되었을 때Paint
부터 다시 발생되는 경우: 주로 배경 이미지나 텍스트 색상, 그림자 등 Layout의 수치를 변화시키지 않는 스타일의 변경이 일어났을 때 발생Composite
(합성)만 다시 발생하는 경우: Layout과 Paint를 수행하지 않고 레이어의 합성만 발생하기 때문에 성능상으로 가장 큰 이점을 가진다.
그러면 나는 자연스럽게 최적화에 대해서도 생각해볼 수 있었다. 보통 css 작업을 할 때 margin
이나 padding
을 남발하는 것은 좋지 않다는 이야기를 많이 들었지만 구체적으로 왜 남발하지 말라는 이야기는 못들었었다. 오늘 공부를 하고 나서야 이유를 알게 되었다.
아까 배운 Reflow
(또는 Layout)가 발생하는 이유는 요소의 크기나 위치등이 변경되었을 때 Reflow
발생이 일어난다고 하였다.
그렇다면 대표적으로 어떤 속성들이 Reflow
를 발생시킬까? 그리고 다음과 같은 속성들을 최소화로 사용하면 최적화에 영향을 준다.
Reflow 대표적인 속성
position, margin, padding, border, float….
그러면 RePaint
과정에서도 최적화를 할 수 있다. RePaint
는 색상이나 그림자가 변경될 때 RePaint
가 일어난다고 했었다. 그렇다면 대표적인 속성으로는 어떤 것들이 있을까?
RePaint 대표적인 속성
background, background-color, background-repeat, background-position…
자바스크립트와 CSS를 조합해서 애니메이션이나 레이아웃 변화가 많은 요소에 position
을 absolute 또는 fixed를 사용하면 영향을 받는 노드들을 줄일 수 있다고 한다. 그 이유는 Reflow
과정은 전혀 없고 RePaint
과정만 있기 때문이라고 한다.
마지막으로 프레임을 줄여서 성능을 개선할 수 있다고 한다. 0.1초마다 1px
씩 이동하는 것 보다는 0.3초마다 3px
씩 이동하는 요소가 Reflow
연산비용이 3배나 줄어든다고 한다. 이 부분은 처음 들었던 내용이라 정말 신선했다.
참고 자료
브라우저는 웹페이지를 어떻게 그리나요?
브라우저 렌더링과 최적화