안녕하세요~ RyuWoong 입니다.
저번 포스팅에 브라우저에서 Web을 어떻게 보여주는지에 대해 했었는데요.
이번엔 그 과정 중 핵심인 중요 렌더링 과정에 대해 알아보겠습니다.
중요 렌더링 과정?
브라우저가 HTML, CSS, Javascript를 화면에 픽셀로 변화하는 일련의 단계를 말하며 이를 최적화하는 것은 렌더링 성능을 향상시켜 사용자가 빠르게 웹페이지에 접근하고 사용할 수 있게 해줍니다.
중요 렌더링 과정 최적화는 렌더링 시간을 개선 시켜줍니다. 이는 빠른 사용자 상호과정을 보장하며 버벅거림을 피할수 있도록 해줍니다.
이 과정은 DOM 구성 - CSSOM 구성 - Render Tree 구성 - Layout - Paint로 이루어져 있습니다. 그럼 과정을 하나씩 뜯어보도록 하겠습니다.
Document Object Model(DOM)
HTML 응답은 토큰으로, 토큰은 노드로, 노드는 DOM 트리로 변환됩니다.
여기서 노드의 갯수는 성능에 영향을 미칩니다. 따라서 노드의 갯수를 측정할 필요가 있습니다.
크롬 개발자 도구에 있는 LightHouse로 확인하면 DOM Node 갯수가 800개 이상이면 경고를 1400개 이상이면 오류를 표시합니다.
좋은 방법은, 필요시에만 Node를 만들고 필요 없다면 Node를 제거하는 것입니다.
가상 스크롤을 이용하거나, React의 경우 Re-Rendering을 최소화하는 것으로 최적화를 이룰수 있습니다.
CSS Object Model (CSSOM)
CSSOM은 DOM을 스타일링 하기 위한 페이지의 모든 스타일 정보를 포함한 것입니다.
CSS는 규칙을 덮어쓸수 있기 때문에 브라우저는 모든 CSS를 처리하고 수신할때까지 페이지 렌더링을 막습니다. CSSOM이 완료될때까지 콘텐츠를 렌더링 할 수 없습니다.
하지만 대부분의 브라우저의 CSS 처리속도는 매우 빠르기 때문에 아래와 같은 성능의 차이가 있더라도 극적인 차이를 느끼기 어렵습니다.
선택자 성능 측면에서, 덜 구체적인 선택자는 더 구체적인 선택자보다 더 빠릅니다.
예를 들어, 브라우저가 .foo 찾을때, .foo {} 는 .bar .foo {} 보다 빠릅니다. 왜냐하면 두번째 시나리오에서, .foo 가 부모 객체인 .bar 를 가지고 있는지 확인하기 위해 DOM을 거슬러 올라가기 때문입니다. 규칙이 구체적일수록 DOM 트리 안에서 더 많은 노드들은 지나야 하기 때문에 더 높은 비용이 들지만 비용이 체감 될 정도로 크지 않기 때문에 필요할 때 최적화 하면 됩니다.
Render Tree
DOM과 CSSOM 트리는 렌더 트리에 합쳐집니다. 렌더 트리를 구성하기 위해 브라우저는 DOM 트리의 root에서 시작해 모든 노드는 확인하면서 어떤 CSS 규칙들을 첨부할지 결정합니다. 렌더 트리는 오직 보여지는 콘텐츠만 캡쳐합니다. (일반적으로) 헤드 섹션은 보여지는 정보를 포함하고 있지 않으므로 렌더트리 안에 포함되지 않습니다. 만약 요소에 display: none 이 적용되어 있다면, 해당 요소 또는 하위 요소는 포함되지 않습니다.
Layout
일단 렌더 트리가 생성되고 나면, 레이아웃이 가능해지며 화면의 크기에 의존합니다. 레이아웃 단계는 요소들이 페이지에서 배치되는 위치와 방법, 각 요소의 너비와 높이 그리고 서로 관련된 위치를 결정합니다.
요소의 너비는 무엇일까요? 정의에 따르면, Block의 요소들의 너비는 부모 너비의 100% 입니다. 50%의 너비를 갖는 요소는 부모 요소의 절반일 것입니다. 비록 그렇게 정의되어 있지 않더라도, body 는 뷰포트 너비의 100%를 의미하는 너비 입니다. 디바이스의 너비는 레이아웃에 영향을 미칩니다.
뷰포트 메타 태그는 레이아웃에 영향을 미치는 뷰포트 레이아웃의 너비를 정의합니다. 이 태그 없다면, 브라우저는 뷰포트 기본값을 사용합니다. 브라우저의 full screen 기본값은 일반적으로 960px 입니다. 기본적으로 브라우저의 full screen에서, 스마트폰의 브라우저와 같은 너비는 <meta name="Viewport" content="width=device-witdh"> 로 세팅함으로써 기본 뷰포트 너비 대신에 디바이스의 너비를 사용합니다. 디바이스 너비는 사용자가 디바이스를 가로(landscape) 또는 세로(portrait) 모드 사이로 돌릴때마다 바뀝니다. 레이아웃은 디바이스가 회전하거나 브라우저의 사이즈가 조정될 때마다 발생합니다.
레이아웃 성능은 DOM의 영향을 받습니다. 노드의 수가 많을수록 레이아웃은 더 길어지며 스크롤링 또는 다른 애니메이션들이 필요하다면 레이아웃에 쟁크(jank)를 일으키는 병목현상이 발생할 수 있습니다. 로딩 또는 방향 전환에 20ms 정도 밀릴 수 있지만 애니메이션 또는 스크롤에 쟁크(jank) 유발할 수 있습니다. 노드에 박스 모델 업데이트, 콘텐츠 대체 그리고 노드 추가와 같은 수정은 언제든지 렌더 트리를 수정할 수 있으며 레이아웃을 형성합니다.
레이아웃 이벤트의 반복과 형성시간을 줄이기 위해서 일괄 업데이트 해야하고, 박스 모델 속성을 애니메이션화 하지 말아야 합니다.
Paint
마지막 단계인 화면에 픽셀을 그리는 것입니다. 일단 렌더 트리가 생성되고 레이아웃이 나타나기 시작하면, 화면에 픽셀을 그릴수 있습니다. 로드시, 전체 화면을 그립니다. 그 후에는 브라우저가 필요한 최소 영역만을 다시 그리도록 최적화되어 있기 때문에 영향을 받는 영역만을 화면에 다시 그립니다. 그리는 시간은 렌더 트리에 적용되는 업데이트의 종류가 무엇있냐에 따라 달라집니다. 페인팅은 매우 빠르게 진행되는 과정이기 때문에 성능 향상에 집중해야 하는 가장 큰 영향있는 부분이 아닐 수 있지만, 애니메이션 프레임 소요시간을 측정할때, 레이아웃과 리페인트 시간을 모두 고려하는 것이 중요합니다. 각 노드에 적용된 스타일은 페인트 시간을 증가시키지만 페인트 시간을 0.001ms 증가시키는 스타일을 제거하는 것은 여러분의 최적화 비용이 매우 커지는 것을 막지 못할 수 있습니다. 최적화 전에, 측정을 통해 어느 부분에서 성능에 문제가 발생하는 지 확인하고 최적화 할지 말지를 결정해야 합니다.
일반적으로 최적화 할 수 있는 방법.
자원 로드 순서를 관리하고, 파일 사이즈를 줄이며 어떤 자원을 먼저 로드할지 정함으로써 페이지 로드 속도를 개선할 수 있습니다.
- 중요도가 낮은 자원의 다운로드를 연기함으로써 중요 자원들의 수를 최소화하기
- 각 요청에 대한 파일 사이즈에 따라 필수적인 요청 횟수 최적하하기
- 다운받을 중요 에셋의 우선순위를 정함으로써 중요 자원 불러오는 순서 최적화하고, 중요 경로 길이 최소화하기
참조.
'Programming > Web' 카테고리의 다른 글
Web Perfomance .02 브라우저가 웹페이지를 보여주기까지. (0) | 2023.03.26 |
---|---|
Web Perfomance .01 Latency (0) | 2023.03.24 |
Web Performance .00 시작하기 전에 (0) | 2023.03.23 |
HTTP 그리고 1.0, 1.1, 2.0 (0) | 2023.03.15 |
웹표준과 웹접근성 (Web Standards & Web Accessibility) (0) | 2023.03.11 |
삽질의 기록과 일상을 남기는 블로그입니다. 주로 React Native를 다룹니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!