브라우저 렌더링 과정 & 최적화

이준희·2023년 7월 23일
0


최근 모달 공통 모듈 작업을 하며 브라우저 렌더링 성능에 관한 이슈를 마주쳐서 다시 한번 브라우저 렌더링 과정을 공부하고 상기하는 목적으로 글을 정리해보려고 한다.

팀원들이 사용할 공통 모달 모듈을 만들어보자.

💻 브라우저

브라우저 렌더링 과정을 알아보기전에 브라우저가 무엇인지 먼저 알아보자. 우선 브라우저는 우리가 흔히 인터넷에 접속할 때 사용하는 Chrome, Safari, Firefox, Internet Explorer 등을 말한다.

MDN에서는 브라우저에 대해 웹에서 페이지를 찾아서 보여주고, 사용자가 하이퍼링크를 통해 다른 페이지로 이동할 수 있도록 하는 프로그램이라고 설명하고 있다. 여기서 중요하다고 생각하는 부분은 찾아서 보여준다는 것이다.

브라우저는 유저가 선택한 자원을 서버로 부터 받아와서 유저에게 보여준다. 이 자원은 페이지 외에도 이미지, 비디오 등의 컨텐츠들도 포함된다. 받아온 자원들을 렌더링 과정을 통해 유저에게 보여주게 된다.

🪜 브라우저 렌더링 과정

렌더링의 기본적인 동작 과정은 다음과 같다.

  1. HTML 파일과 CSS 파일을 파싱해서 각각 Tree를 만든다. (Javascript)

  2. 두 Tree를 결합하여 Rendering Tree를 만든다. (Style)

  3. Rendering Tree에서 각 노드의 위치와 크기를 계산한다. (Layout)

  4. 계산된 값을 이용해 각 노드를 화면상의 실제 픽셀로 변환하고, 레이어를 만든다. (Paint)

  5. 레이어를 합성하여 실제 화면에 나타낸다. (Composite)

각 단계를 좀 더 자세하게 알아보자.

Javascript

브라우저가 페이지를 렌더링하려면 가장 먼저 받아온 HTML 파일을 해석해야한다. Parsing 단계는 HTML 파일을 해석하여 DOM(Document Object Model) Tree를 구성하는 단계이다.

파싱 중 HTML에 CSS가 포함되어 있다면 CSSOM(CSS Object Model) Tree 구성 작업도 함께 진행한다.

Style

Style 단계에서는 Parsing 단계에서 생성된 DOM Tree와 CSSOM Tree를 매칭시켜서 Render Tree를 구성한다. Render Tree는 실제로 화면에 그려질 Tree이다.

예를 들면 Render Tree를 구성할때 visibility: hidden은 요소가 공간을 차지하고, 보이지만 않기 때문에 Render Tree에 포함이 되지만, display: none 의 경우 Render Tree에서 제외된다.

Layout

Layout 단계에서는 Render Tree를 화면에 어떻게 배치해야 할 것인지 노드의 정확한 위치와 크기를 계산한다.

루트부터 노드를 순회하면서 노드의 정확한 크기와 위치를 계산하고 Render Tree에 반영한다. 만약 크기 값을 %로 지정하였다면, Layout 단계에서 % 값을 계산해서 픽셀 단위로 변환한다.

Paint

Paint 단계에서는 Layout 단계에서 계산된 값을 이용해 Render Tree의 각 노드를 화면상의 실제 픽셀로 변환한다. 이때 픽셀로 변환된 결과는 하나의 레이어가 아니라 여러 개의 레이어로 관리된다.

당연한 말이지만 스타일이 복잡할수록 Paint 시간도 늘어난다. 예를 들어, 단색 배경의 경우 시간과 작업이 적게 필요하지만, 그림자 효과는 시간과 작업이 더 많이 필요하다.

Composite

Composite 단계에서는 Paint 단계에서 생성된 레이어를 합성하여 실제 화면에 나타낸다. 우리는 화면에서 웹 페이지를 볼 수 있다.

🛠 브라우저 렌더링 최적화 - Reflow, Repaint 줄이기

Reflow (Layout)

위에서 언급된 렌더링 과정을 거친 뒤에 최종적으로 페이지가 그려진다고 해서 렌더링 과정이 다 끝난것이 아니다. 어떠한 액션이나 이벤트에 따라 html 요소의 크기나 위치등 레이아웃 수치를 수정하면 그에 영향을 받는 자식 노드나 부모 노드들을 포함하여 Layout 과정을 다시 수행하게 된다. 이렇게 되면 Render Tree와 각 요소들의 크기와 위치를 다시 계산하게 된다. 이러한 과정을 Reflow라고 한다.

Reflow가 일어나는 대표적인 경우는 아래와 같다.

  1. 페이지 초기 렌더링 시(최초 Layout 과정)

  2. 윈도우 리사이징 시 (Viewport 크기 변경시)

  3. 노드 추가 또는 제거

  4. 요소의 위치, 크기 변경 (left, top, margin, padding, border, width, height, 등)

  5. 폰트 변경 과(텍스트 내용) 이미지 크기 변경(크기가 다른 이미지로 변경 시)

Repaint (Paint)

Reflow만 수행되면 실제 화면에 반영되지 않는다. 위에서 언급된 렌더링 과정과 같이 Render Tree를 다시 화면에 그려주는 과정이 필요하다. 결국은 Paint 단계가 다시 수행되는 것이며 이를 Repaint 라고 한다.

하지만 무조건 Reflow가 일어나야 Repaint가 일어나는것은 아니다. background-color, visibility와 같이 레이아웃에는 영향을 주지 않는 스타일 속성이 변경되었을 때는 Reflow를 수행할 필요가 없기 때문에 Repaint만 수행하게 된다.

🌟 Reflow, Repaint 줄이기

1. 사용하지 않는 노드에는 visibilty: invisible 보다 display: none을 사용하기

visibility invisible은 레이아웃 공간을 차지하기 때문에 reflow의 대상이 된다. 하지만 display none은 Layout 공간을 차지하지 않아 Render Tree에서 아예 제외된다.

2. Reflow, Repaint 가 발생하는 속성 사용 피하기

아래는 각각 Reflow, Repaint가 일어나는 CSS 속성들 이다. Reflow가 일어나면 Repaint는 필연적으로 일어나야 하기 때문에 가능하다면 Reflow가 발생하는 속성보다 Repaint 만 발생하는 속성을 사용하는것이 좋다.

Reflow가 일어나는 대표적인 속성

positionwidthheightlefttop
rightbottommarginpaddingborder
border-widthcleardisplayfloatfont-family
font-sizefont-weightline-heightmin-heightoverflow
text-alignvertical-alignwhite-space

Repaint가 일어나는 대표적인 속성

backgroundbackground-imagebackground-positionbackground-repeatbackground-size
border-radiusborder-stylebox-shadowcolorline-style
outlineoutline-coloroutline-styleoutline-widthtext-decoration
visibility

또한 Reflow Repaint가 일어나지 않는 transform, opacitiy와 같은 속성도 있다. 따라서 left, right, width, height 보다 transform을, visibility/display 보다 opacitiy를 사용하는 것이 성능 개선에 도움이 된다.

3. 영향을 주는 노드 줄이기

Javascript + Css를 조합하여 애니메이션이 많거나 레이아웃 변화가 많은 요소의 경우 position을 absolute 또는 fixed를 사용하여 영향을 받는 주변 노드들을 줄일 수 있다. fixed와 같이 영향을 받는 노드가 전혀 없는 경우 reflow과정이 전혀 필요가 없어지기 때문에 Repaint 연산비용만 들게 된다.

또다른 방법은 애니메이션 시작시 요소를 absolute, fixed로 변경 후 애니메이션이 종료되었을 때 원상복구 하는 방법도 Reflow, Repaint 연산을 줄이는데에 도움이 된다.

4. 프레임 줄이기

단순히 생각하면 0.1초에 1px씩 이동하는 요소보다 3px씩 이동하는 요소가 Reflow, Repaint 연산비용이 3배가 줄어든다고 볼 수 있다. 따라서 부드러운 효과를 조금 줄여 성능을 개선할 수 있다.

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

유익한 글이었습니다.

답글 달기