본문 바로가기

Front-End

성능 최적화

반응형

개발자에게 성능이란 굉장히 중요하다. 

 

최근 웹 애플리케이션에서는 복잡한 기능과 UI를 통해 기능이 더욱 무거워지고 있다. 특히 Instagram, facebook, Pinterest 등의 SNS 플랫폼 같은 경우 빠른 리로딩 시간이 필요하므로 성능 최적화가 더욱 중요하다. 개발자는 끊임없이 구조를 단순화하고 최대한 렌더링 시간을 줄이기 위해 고민해야 한다. 

 

최근 Grid 컴포넌트 성능 개선 작업을 통해 느꼈던 포인트들과 성능 최적화를 위한 사전 지식과 최적화 방법들을 정리해본다.

 

 

브라우저는 웹 페이지에 필요한 리소스를 내려받고 해석한 다음 여러 계산 과정을 거쳐 콘텐츠를 화면에 보여준다. 이를 브라우저의 로딩 과정이라고 하며 다운로드, 파싱, 스타일, 레이아웃, 페인트, 합성으로 나뉜다. 단계마다 어떤 일이 발생하는지 알아보자.

 

 

1. 파싱

브라우저에서 웹 페이지를 로드하면 가장 먼저 HTML 파일을 다운로드한다. 파싱은 다운로드한 HTML을 해석하여 DOM 트리를 구성하는 단계이다. HTML 또는 리소스에 CSS가 포함된 경우에는 CSSOM 트리 구성 작업도 함께 진행된다.

 

2. 스타일

스타일 단계에서는 파싱 단계에서 생성된 DOM, CSSOM 트리를 가지고 스타일을 매칭 시켜주는 과정을 거쳐 렌더 트리를 구성한다.

 

3. 레이아웃

레이아웃 단계에서는 노드의 정확한 위치와 크기를 계산한다. 노드의 정확한 크기와 위치를 파악하기 위해 루트부터 노드를 순회하면서 계산하고, 레이아웃 결과로 각 노드의 정확한 위치와 크기를 픽셀 값으로 렌더 트리에 반영한다.

 

4. 페인트

이전 레이아웃 단계에서 계산된 값을 이용해 렌더트리의 각 노드를 화면상의 실제 픽셀로 변환한다. 이때 위치와 관계없는 CSS 속성(색상, 투명도 등)을 적용한다. transform 속성 등을 사용하면 엘리먼트가 레이어화 되는데, 이 과정을 페인트라고 한다.

 

5. 합성 & 렌더

페인트 단계에서 생성된 레이어를 합성하여 스크린을 업데이트한다. 합성과 렌더 단계가 끝나면 화면에서 웹 페이지를 볼 수 있다.

 

 

 

 

Quantum 엔진 설명

 

 

 

레이아웃과 리페인트

브라우저 로딩 과정 중 스타일 이후의 과정(스타일->레이아웃->페인트->합성)을 렌더링이라고 하는데, 이 렌더링 과정은 상황에 따라 반복하여 발생할 수 있다. 스타일 단계에서 구성되는 렌더 트리는 자바스크립트에 의해 DOM 트리, CSSOM 트리가 변경될 때 다시 재구성된다.

 

DOM이 추가/삭제되거나 *요소에 기하학적인 영향(높이, 넓이, 위치)을 주는 CSS 속성 값을 변경하는 경우, 렌더 트리가 다시 재구성된다. 즉, 레이아웃부터 이후 과정을 다시 수행하며 이것을 레이아웃이라고 한다. (또는 리플로우라고도 한다.)

 

*요소에 기하학적인 영향을 주는 CSS 속성 값 : height, width, left, top, font-size, line-height 등

 

 

 

레이아웃과 반대로 **기하학적인 영향을 주지 않는 CSS 속성 값을 변경하면 레이아웃 과정을 건너뛴다. 페인트부터 수행하며 이를 리페인트라고 한다.

 

**요소에 기하학적인 영향을 주지 않는 CSS 속성 값 : background-color, color, visibility, text-decoration 등

 

 

레이아웃이 일어나면 픽셀을 다시 계산해야 하므로 부하가 크다. 반면 리페인트는 이미 계산된 픽셀 값을 이용해 화면을 그리기 때문에 레이아웃에 비해 부하가 적다. 다음은 어떤 엘리먼트에 레이아웃과 리페인트를 발생시키는 CSS 속성과 해당 속성 값을 변경했을 때 차이를 보여준다.

반응형

'Front-End' 카테고리의 다른 글

SPA (Single-page Application)  (0) 2020.03.09
최상의 웹 앱 성능을 위한 기술, WebAssembly  (0) 2020.03.08
최근 MS가 출시한 gitHub 툴 'Scalar'  (0) 2020.03.06
2020년의 웹 기술 개발 스택  (0) 2020.03.01
첫 포스팅, 2020  (0) 2020.02.27