브라우저 랜더링 최적화
오늘날 웹 사용자는 방문하는 페이지가 대화형으로 원활하게 작동할 것으로 기대하므로 여기에 시간과 노력을 집중해야 한다.
페이지는 빠르게 로드될 뿐만 아니라 전체 수명 주기 동안 사용자 입력에 빠르게 응답해야 한다.
사용자 인터페이스의 시각적 변경은 사용자가 안정적으로 느껴지도록 최대한 빠르게 진행되어야 한다.
사용자 상호작용에 빠르게 응답하는 페이지를 작성하려면 브라우저에서 HTML, 자바스크립트, CSS를 처리하는 방법을 이해하고 작성하는 코드와 포함된 기타 서드 파티 코드가 최대한 효율적으로 실행되도록 해야한다.
그렇다면 웹 성능 최적화를 어떻게 할 수 있을까? 이를 알려면 Reflow와 Repaint에 대해 먼저 짚고 넘어가야 한다.
기기 새로고침 빈도에 관한 참고사항
오늘날 대부분의 기기는 초당 60회의 빈도로 화면을 새로고침합니다. 일반적인 디스플레이가 초당 60회 새로고침된다는 점을 고려할 때 간단한 계산 결과로 브라우저가 각 프레임을 생성하는 데 16.66밀리초의 시간이 남았음을 알 수 있습니다. 하지만 실제로는 브라우저에 각 프레임에 대한 자체 오버헤드가 있으므로 모든 작업을 10밀리초 내에 완료해야 합니다. 이 예산을 충족하지 못하면 프레임 속도가 떨어지고 화면에서 페이지 콘텐츠가 떨리게 됩니다. 이 현상을 버벅거림이라고 합니다.
Reflow, Repaint
Reflow
어떠한 액션이나 이벤트에 따라 html 요소의 크기나 위치등 레이아웃 수치를 수정하면 그에 영향을 받는 자식 노드나 부모 노드들을 포함하여 Layout 과정을 다시 수행하게 됩니다.
이렇게 되면 Render Tree와 각 요소들의 크기와 위치를 다시 계산하게 됩니다. 이러한 과정을 Reflow라고 합니다.
1
2
3
4
// reflow 발생 예제
function reflow() {
document.getElementById("content").style.width = "600px";
}
Reflow가 일어나는 대표적인 경우
페이지 초기 렌더링 시(최초 Layout 과정)
윈도우 리사이징 시 (Viewport 크기 변경시)
노드 추가 또는 제거
요소의 위치, 크기 변경 (left, top, margin, padding, border, width, height, 등..)
폰트 변경 과(텍스트 내용) 이미지 크기 변경(크기가 다른 이미지로 변경 시)
Repaint
Reflow만 수행되면 실제 화면에 반영되지 않고 Render Tree를 다시 화면에 그려주는 과정이 필요하다.
결국은 Paint 단계가 다시 수행되는 것이며 이를 Repaint 라고 한다.
예시
1
document.getElementById("box").style.height = "100px";
요소의 스타일을 변경하기 위해 위의 그림처럼 JavaScript가 실행되고 Style변경, 계산이 다시일어난다.
그 후 Reflow(Layout) 와 Repaint(Paint) 단계를 거치게 된다.
그렇다면 맨 마지막에 실행되는 Composite은 무엇일까?
이전 게시글에서는 Composite에 대한 개념은 배우지 않았기에 살펴보도록 하자.
Compositer
Paint 단계에서 여러 Layer로 나눠 픽셀을 채워넣는다.
Paint 단계에서는 전체 Render Tree를 한번에 처리하여 것이 아니라 특수한 알고리즘에 따라 Layer를 나눠서 처리한다.
이렇게 Layer를 분리함으로써 특정 요소가 수정되어 다시 Paint를 해야하는 일이 발생했을 때 변경된 Layer 만 다시 그려주면 되는 이점을 얻을 수 있다.
이렇게 여러 Layer로 나눠진 Raster 픽셀들을 우리가 실제로 보는 화면처럼 합성해주는 단계가 Composite 단계이다.
Paint 단계에서 그려진 여러개의 Layer를 정확한 순서에 따라 합성하여 디스플레이에 출력되는 최종 결과물을 만들어낸다.
본론으로 돌아와서 브라우저 랜더링 최적화를 어떻게 할 수 있는지에 대해 알아보자.
브라우저 랜더링 최적화 - 개선 전략
CPU
스크립트가 들어왔을 때 스타일을 다시 계산
layout 과정 실행
layout 업데이트 후 메인 메모리에 저장
paint를 통해 비디오 메모리에 저장
GPU
- 여러 layout을 병합
여기서 알아야할 점은 CPU가 연산되기 위해 필요한 컴퓨팅 파워보다 GPU가 훨씬 적다는 것이다.
따라서 렌더링 성능을 개선하기 위해서는 layout, paint를 동작시키는 것 보다 composite을 동작 시키는게 좋다.
Layout, Paint를 줄이고, 최적의 Layer를 구성해야 한다.
브라우저 랜더링 최적화 - Reflow, Repaint 줄이기
JS / CSS > 스타일 > 페인트 > 합성
‘Paint Only’ 속성을 사용하면 Layout 과정을 건너뛰고 바로 Paint 과정으로 넘어가게 된다.
Layout 단계를 건너뛰면 앞에서 설명했듯이 연산하는 양이 줄어들기 때문에 렌더링 속도가 개선된다.
따라서 Layout을 발생시키는 속성을 Paint만 발생시키는 속성으로 대체하며 렌더링 성능을 개선하는 방법이 있다.
JS / CSS > 스타일 > 합성
Layout 과 Paint 둘 다 거치지 않는 속성들이 있다. transform, opacitiy, cursor, orphans, perspective 등이 해당된다.
Reflow와 Repaint를 모두 건너뛰게 되면 연산이 절대적으로 줄어들기 때문에 ‘Paint Only’ 속성보다도 렌더링 속도가 더 빠르다고 할 수 있다.
📑 참고 자료