
이전 포스트르 작성하며 관련된 자료를 추가하다보니 렌더링 과정에 대해 더 다룰 내용이 많아
2편을 작성하게 되었다.
이번 포스팅에서는
Rendering Blocking과 JavaScript실행 Reflow와 RepaintCRP 최적화를 중점으로 살펴보고자 한다.
이전에 살펴본 렌더링 과정 및 CRP에서 위와 같은 차례로 렌더링이 진행된다고 했었는데,
사실 렌더링은 순서대로 착착 진행되지 않는다.
Rendering Blocking 이란 웹 페이지의 렌더링을 지연시키는 요인을 의미한다.
웹 브라우저가 웹 페이지를 로드할 때 HTML, CSS, JavaScript를 다운로드하고 처리할 때
특정 리소스(특히 CSS, JavaScript)가 로드 및 처리되기 전까지 페이지가 화면에 제대로 표시되지 않으면,
해당 리소스는 Rendering Blocking 요소가 된다.
웹 브라우저는 서버로부터
HTML을 다운로드하고, 이를 바탕으로DOM을 생성한다.
웹 브라우저는 CSS파일이 완전히 다운로드되고, 파싱될 때까지 DOM의 렌더링을 중단한다.
따라서 CSS파일이 큰 경우나 네트워크 속도가 느린 경우 CSS파일의 로드가 지연되면
DOM의 완전한 렌더링도 지연된다.
웹 브라우저는 HTML을 파싱해 DOM 트리를 생성하는데,
생성 과정에서는 CSS파일의 로드 상태와는 상관없이 DOM 트리는 만들어진다.
브라우저는 DOM이 완성된 이후, 이를 화면에 그리기 위해 CSSOM과 DOM을 결합해
Render Tree를 생성해야하는데, CSSOM이 완성되기 전까지 브라우저는 렌더트리를 생성하지 않는다.
따라서 CSS 파일이 모두 로드되고 완료될 때까지 렌더링이 지연될 수 있다.
즉, 브라우저는 DOM을 다 만들어도 CSSOM이 준비되지 않으면 화면에 요소를 그리지 않는다.
웹 브라우저가 HTML을 파싱하는 도중 <script> 태그를 만나면,
브라우저는 HTML 파싱을 중단하고 해당 JavaScript파일을 다운로드해 실행한다.
(렌더링 엔진이 자바스크립트 엔진에게 제어권을 넘긴다.)
JavaScript는 브라우저에서 실행되고 페이지 동작 방식에 대한 거의 모든 측면을 변경할 수 있다.
즉, DOM을 조작하거나 CSSOM에 영향을 줄 수 있기 때문에
JavaScript 실행이 완료되기 전까지 DOM 구축이 완료되지 않을 수 있다.
<script> 태그로 인해 HTML 파싱이 중단되면 DOM 생성이 지연된다.
JavaScript 파일이 크거나 네트워크 속도가 느릴 경우, 이로 인해 전체 렌더링이 지연될 수 있다.
기본적으로 <script> 태그는 동기적으로 로드된다.
스크립트가 로드되고 실행될 때까지 브라우저는 HTML의 나머지 부분을 파싱하지 않는다.
async 속성이 있는 <script> 태그를 사용하는 경우
스크립트는 비동기적으로 로드되고, 로드가 완료되는 즉시 실행된다.
이 경우 HTML 파싱과 스크립트 로딩이 동시에 진행될 수 있다.
defer 속성이 있는 <script> 태그를 사용하는 경우
스크립트는 HTML 문서 파싱이 완료된 후 실행된다.
이 방식은 HTML 문서 구조에 영향을 미치지 않도록 한다.
Rendering은 한 번만 발생하지 않는다.
렌더링 과정을 거쳐 최종적으로 웹 페이지가 표시된 후
사용자가 브라우저 화면의 크기를 조절하거나, 화면의 요소가 추가 또는 삭제 되는 경우
화면에 있는 요소들의 크기가 바뀌게 된다.
✅ 이 때, 화면에 나타나는 모습이 바뀌기 위해서는 모든 요소의 위치와 크기를 다시 계산하고 다시 그려서 보여줘야 한다.
Reflow 란 브라우저가 HTML 문서의 구조와 CSS 스타일을 기반으로 요소들의 크기, 위치, 모양을 다시 계산하는 과정이다.
width, height) margin, padding, border)Reflow는 DOM의 일부 또는 전체를 다시 계산해야 하므로 성능에 큰 영향을 미칠 수 있다.
Repaint 란 브라우저가 요소의 시각적 속성(색상, 테두리, 그림자)을 다시 그리는 과정이다.
Reflow와 달리 요소의 위치나 크기에는 영향을 미치지 않으며, 화면에 보이는 요소의 모양만 변경된다.
Repaint는 요소의 시각적 속성만 변경하므로 비교적 비용이 덜 들지만,
빈번한 작업은 성능에 영향을 미칠 수 있다.
⚙️ CSS, JavaScript의 크기 축소 및 압축
⚙️ 이미지 최적화 - 압축 적용, WebP 사용
⚙️ CSS를 최상단에 배치해 렌더링 차단 최소화 - <head> 섹션에 배치
⚙️ JavaScript 비동기/지연 로드 - async, defer 속성 사용
⚙️ Critical CSS 인라인 삽입 - 초기 렌더링에 필요한 최소한의 CSS 인라인 삽입, 나머지 CSS는 비동기 로드
⚙️ JavaScript 비동기/지연 로드 - 초기 렌더링을 차단하지 않도록
⚙️ 이미지와 비디오의 지연 로드
-사용자가 스크롤하기 전까지 미디어 리소스를 로드하지 않도록 설정해 초기 로드 시간 단축