대부분의 브라우저는
싱글 쓰레드
입니다.
브라우저의 메인 쓰레드가 요청된 모든 작업을 수행하면서도 유저와의 상호작용에 빠르게 반응 할 수 있도록 보장하기 위해서는 렌더링 시간이 가장 중요합니다.
브라우저의 렌더링은 다음과 같은 순서로 렌더링됩니다.
웹페이지를 로딩하는 가장 첫 번째 단계입니다.
오래 걸리는 작업은 아니지만, 네임 서버와의 거리에 따른 지연 시간
과 대역폭
등이 지연을 일으킬 수 있습니다.
아래 세가지 조건에서 네트워크 요청이 발생합니다.
웹페이지 탐색순서는 다음과 같이 크게 4번의 왕복이 이루어집니다.
캐시
됩니다. 이를 통해 후속 요청 속도를 높입니다.HTML
의 내용을 응답하게 됩니다.렌더링 엔진
을 통해 HTML 문서를 읽고, HTML을 파싱합니다.트리 생성
을 포함하여 진행합니다.async
나 defer
같은 설정이 되어있지 않은 <script>
태그는 렌더링을 막고, HTML의 분석을 중지시킵니다. 따라서 과도한 스크립트 태그는 병목현상을 유발하므로 지양하는게 좋습니다.
CSS 파싱은 기본적으로 매우 빠릅니다. DOM 트리가 생성되는 과정에서 link 태그의 css와 style 태그를 만나면 CSS 파싱이 진행됩니다.
스타일 맵
으로 변환합니다.자바스크립트 파일은 브라우저의 자바스크립트 엔진(크롬의 경우 v8)에 의해 해석, 컴파일, 구문 분석 및 실행됩니다.
CSSOM과 DOM 트리는 구문 분석되는 과정에서 생성되고 렌더 트리로 합성됩니다.
레이아웃 단계에서는 뷰포트(viewport)
내에서 각 요소의 정확한 위치와 크기를 정확하게 캡처하는 Box 모델이 출력됩니다.
이를 바탕으로 레이아웃 트리가 생성됩니다.
모든 상대적인 측정값은 화면에서 절대적인 픽셀로 변환됩니다.
마지막으로 렌더 트리의 각 노드를 화면의 실제 픽셀로 변환하게 됩니다. 레이아웃 단계에서 모든 계산이 완료가 되면, 화면에 요소들을 그리게 됩니다. 이 단계를 “페인트” 또는 “래스터화”라고 합니다.
이미 레이아웃 단계에서 각 노드들이 위치, 크기, 색상 등 스타일이 모두 계산이 되었기 때문에 화면에 실제 픽셀로 변환됩니다.
사용자가 웹 페이지에 처음 접속을 하면, 렌더링 과정을 거쳐서 화면에 모든 요소가 그려지게 됩니다. 이후에 사용자와의 다양한 상호작용으로 인해 새로운 HTML 요소가 추가되거나, 기존 요소의 스타일이 바뀌거나 하는 변경이 일어나게 됩니다.
이런 변경을 통해 영향을 받게되는 모든 노드에 대해서 렌더링 트리 생성과 레이아웃 과정을 다시 수행하게 됩니다. 이러한 과정을 리플로우(Reflow)
라고 함.
리플로우는 단지 변경사항을 반영하기 위해서 렌더링 트리를 생성하고 레이아웃 과정을 다시 수행하는 것이고, 실제 이 결과를 화면에 그려지기 위해서는 다시 페인팅 단계를 수행해야 합니다. 이 과정을 리페인트(Repaint)
라고 함
기존 요소에 변경 사항이 생겼다고 해서 항상 리플로우(Reflow)-리페인트(Repaint)가 일어나는 것은 아니고, 레이아웃에 영향이 미치지 않는 단순한 색상 변경 같은 변경사항은 리플로우(Reflow) 수행 없이 바로 리페인트(Repaint)만 수행하게 됩니다.
여기서 알 수 있듯이 리플로우(Reflow)가 발생하면 리페인트(Repaint)는 반드시 발생합니다.
수정된 요소를 DOM을 바탕으로 DOM 트리 및 CSSOM 트리를 생성하는 일련의 과정을 거치게 됩니다.
이때 수정된 요소가 있는 항목만 기존의 Render 트리와 비교하여 레이아웃을 계산하고 paint 과정을 거치게 됩니다.
position, width, height, margin, padding, border, border-width, font-size, font-weight, line-height, text-align, overflow
background, color, text-decoration, border-style, border-radius