브라우저는 파싱
> 스타일
> 레이아웃
> 페인트
의 과정을 거쳐 렌더링 된다.
HTML 파일을 해석하여 DOM 트리와 CSSOM 트리를 구성하는 단계
<script />
, <link />
, <img />
를 발견하면 각 리소스를 요청하고 다운로드한다.DOM 트리와 CSSOM 트리를 매칭시켜 렌더 트리를 구성하는 단계
display: none
인 경우 포함되지 않음)노드의 정확한 크기와 위치를 계산하여 픽셀 값으로 반영하는 단계
요소를 실제 화면에 그리는 단계
페인트 단계에서 생성된 레이어를 합성하여 스크린을 업데이트하는 단계
스타일 단계에서 구성되는 렌더 트리는 자바스크립트에 의해 DOM 트리, CSSOM 트리가 변경될 때 다시 재구성된다.
즉, 레이아웃
> 페인트
> 합성
을 다시 수행하는 것이 리플로우다.
페인트
> 합성
의 과정을 다시 수행하는 것
리플로우와 리페인트는 시간이 오래 걸리는 작업이다. 당연히 리플로우가 리페인트보다 더 많은 시간이 걸린다.
따라서 최대한 리플로우와 리페인트가 발생하지 않도록, 어쩔 수 없는 상황이라면 리페인트만 발생할 수 있도록 코드를 작성하는 것이 중요하다.
<head>
아래에서 CSS 파일 로드
DOM 트리는 파싱 중에 태그를 발견할 때마다 순차적으로 구성할 수 있지만, CSSOM 트리는 CSS를 모두 해석해야 구성할 수 있다.
즉, CSSOM 트리가 구성되지 않으면 렌더 트리를 만들지 못하고 렌더링이 차단된다.
이러한 이유로 CSS는 렌더링 차단 리소스라고 하며, 렌더링이 차단되지 않도록 CSS는 항상 HTML 문서 최상단( 아래)에 배치한다.
<body />
직전에 JS 파일 로드
자바스크립트는 DOM 트리와 CSSOM 트리를 동적으로 변경할 수 있기 때문에 HTML 파싱을 차단하는 블록 리소스이다.
<script>
태그를 만나면 스크립트가 실행되며 그 이전까지 생성된 DOM에만 접근할 수 있다. 그리고 스크립트 실행이 완료될 때까지 DOM 트리 생성이 중단된다. 외부에서 가져오는 자바스크립트의 경우에는 모든 스크립트가 다운로드되고 실행될 때까지 DOM 트리 생성이 중단된다.
이러한 이유로 자바스크립트도 렌더링 차단 리소스라고 하며, HTML 문서 최하단( 직전)에 배치한다.
display: none
이용 사용하지 않는 노드를 화면에서 감추는 방법은 visibility: invisible
과 display: none
이 있다.
visibility: invisible
은 레이아웃 공간을 차지하기 때문에 리플로우의 대상이 되나 display: none
은 레이아웃 공간을 차지하지 않아 렌더 트리에서 제외된다.
응용하여 여러 속성을 변경할 때 해당 요소를 display: none
으로 변경 후 작업하는 방법도 고려할 수 있다.