웹 페이지 빌드 과정(CRP)
브라우저가 HTML, CSS, Javascdript를 화면에 픽셀로 변환하는 일련의 단계
브라우저가 서버에서 응답을 받아 하나의 화면을 그려내는 것
- 서버에서 응답으로 받은 HTML 데이터를 파싱
- HTML을 파싱한 결과로 DOM Tree(Document Object Model) 생성
- 파싱하는 중 CSS 파일 링크를 만나면 CSS 파일을 요청해서 받음
- CSS 파일을 읽어서 CSSOM(CSS Object Model) 생성
- DOM Tree와 CSSOM이 모두 만들어지면 이 둘을 사용해 Render Tree 생성
- Render Tree에 있는 각각의 노드들이 화면의 어디에 어떻게 위치할 지를 계산
- 화면에 실제 픽셀을 Paint
1. DOM Tree(Document Object Model Tree)
- DOM
- HTML 문서의 객체 표현
- JavaScript와 같은 프로그래밍 언어와 HTML 문서의 연결 지점(인터페이스)
- 트리의 최상위 객체는 문서
- DOM Tree는 완전하게 파싱된 HTML 페이지의 Object 표현이다.
- 문서 마크업의 속성 및 관계를 포함
- 요소가 렌더링될 때 어떻게 표시될지에 대해서는 알려주지 않음
- html로부터 시작해 각 element, text에 대한 node가 만들어진다.
- 엘리먼트 내에 중첩된 엘리먼트는 자식 노드로 생성
- 각 노드는 해당 엘리먼트에 대한 속성이 포함
- DOM Tree 생성은 점진적으로 진행된다. 페이지에 내용을 표시하기 위해 문서 전체를 로드할 필요가 없음.
- CSS와 javascript 로드시에 페이지의 렌더링을 차단
- 불필요한 tag나 wrapper는 사용하지 않고, div를 남용하는 대신 sementic 태그를 이용하는 것이 성능에 좋음.
2. CSSOM Tree(Cascading Style Sheets Object Model Tree)
- DOM을 스타일링 하기 위한 페이지의 모든 스타일 정보
- JavaScript와 같은 프로그래밍 언어가 CSS를 조작 할 수 있게 해주는 API 세트
- CSSOM Tree는 DOM Tree와 관련된 스타일 객체를 Tree구조로 생성
- 각 노드는 관련된 스타일을 포함
- Style Sheet를 파싱하면 위와 같은 CSSOM Tree가 생성
- 계단식 상속
- CSS는 상속과 덮어쓰기가 가능
- CSS 전체가 파싱되기 전에 사용하면 잘못된 스타일이 적용
- 따라서 브라우저는 모든 CSS를 수신하고 처리할 때까지 페이지 렌더링을 막는다.
- = 렌더링 차단 리소스 ( CSSOM Tree가 완전히 구성될 때 까지 )
- 구체적인 선택자보다 덜 구체적인 선택자가 더 빠르지만 성능차이가 크지는 않다.
3. JavaScript
- 첫 번째 단계인 DOM 구성 중에 일어날 수 있음
- 웹 브라우저는 CRP과정을 거치며 DOM Tree를 구성하는데 이때 <script>또는 외부 script참조 구문을 만나면, DOM Tree를 구성하던 작업이 중지되고 script가 먼저 실행
- 따라서 TML 작성 시 <script>는 각 엘리먼트에 대한 정의가 모두 끝난 뒤 마지막에 작성하는것을 권장
4. Render Tree
- DOM과 CSSOM이 합쳐진 것으로 페이지에서 최종적으로 렌더링할 내용을 나타내는 Tree
- 브라우저가 화면에 픽셀을 렌더링
- 실제 웹 브라우저에 표현되는 정보
- Render Tree는 오직 보여지는 node만 캡쳐한다.
- 예] display:none 속성은 렌더트리에 포함되지 않는다.(visible:hidden은 포함됨)
5. Layout
- 뷰포트 내에서 각 요소의 정확한 위치와 크기를 정확하게 캡처하는 상자 모델 출력
- 모든 상대적인 측정값은 화면에서 절대적인 픽셀로 변환
- 영역에를 통해 viewport의 크기를 정의
- 정의되지 않은 경우 viewport의 크기는 기본 980px로 지정
- 통상 viewport값은 웹 브라우저를 사용하는 pc 모니터해상도에 따라 설정
<meta name="viewport" content="width=device-width, initial-scale=1">
- 레이아웃은 디바이스가 회전하거나 브라우저의 사이즈가 조정될 때마다 발생
- 레아아웃의 성능은 DOM의 영향을 받으며 노드의 수가 많을수록 레이아웃은 더 길어짐,
- 스크롤링 또는 다른 애니메이션이 있으면 레이아웃에 jank를 일으키는 병목현상이 발생
- 레아아웃 이벤트의 반복과 형성시간을 줄이기 위해서 일괄 업데이트 및 박스 모델 속성을 애니메이션화 자제
- 박스모델 : HTML 요소를 padding, border, margin, content 으로 구분하는 것.
6. Paint
- 화면에 픽셀을 그리는 단계.
- 앞서 구성된 정보를 토대로, 웹 브라우저를 통해 실제 화면에 데이터를 표현
- load시에 전체 화면을 그리고, 이후에는 브라우저가 필요한 최소 영역만 다시 그리도록 최적화
- Layer 단위로 준비(z-index 등). 변화가 있을 때 해당 레이어만 수정하도록 최적화
- Paint단계에서 걸리는 시간은 CSS복잡도와 DOM크기에 따라 차이가 있음
7. Composition
• 준비한 레이어를 화면에 놓는 과정
렌더링 차단 리소스
- HTML
- 렌더링 차단 리소스
- CSS
- 렌더링 차단 리소스
- 미디어 유형과 미디어 쿼리를 통해 일부 CSS 리소스를 렌더링
- 브라우저는 차단 동작이든 비차단 동작이든 관계없이 모든 CSS 리소스를 다운로드
- JavaScript
- 명시적으로 비동기로 선언되지 않은 경우, DOM 생성을 차단
- 자바스크립트 실행은 CSSOM을 차단
CRP 최적화
- 자원 로드 순서 관리
- 파일 사이즈 축소
- 자원 다운로드를 연기함으로써 중요 자원들의 수를 최소화
- Operation 과정에서 layout, paint는 되도록 적게 발생
- element를 이동할 때 top, left 속성을 변경하면 layout+paint+composition 모두 발생
- translate를 이용할 경우 composition만 발생
CRP 최적화 주요 변수
주요 리소스의 수
- 페이지의 초기 렌더링을 차단할 수 있는 리소스
- 리소스가 적을수록 브라우저, CPU 및 기타 리소스의 작업 감소
주요 경로 길이
- 주요 리소스와 해당 바이트 크기 간의 종속성 그래프를 나타내는 기능
- 일부 리소스 다운로드는 이전 리소스가 처리된 후에만 시작
- 리소스가 클수록 다운로드하는데 걸리는 왕복 수가 증가
주요 바이트의 수
- 브라우저에서 다운로드해야 하는 주요 바이트 수
- 주요 바이트 수가 적을수록 신속하게 콘텐츠를 처리하여 화면에 렌더링
- 리소스를 제거하거나 중요하지 않은 것으로 만들어 리소스 / 바이트 수 감소
- 리소스를 압축하고 최적화하여 전송 크기를 최소화
CRP 최적화 단계
- 주요 경로(리소스 수, 바이트 수, 길이) 분석 및 파악
- 주요 리소스 수를 최소화
- 주요 리소스를 제거
- 리소스에 대한 다운로드를 연기하거나 비동기로 표시
- 주요 바이트 수를 최적화하여 다운로드 시간(왕복 수)을 단축
- 나머지 주요 리소스가 로드되는 순서를 최적화
CRP 최적화 주의 사항
- 렌더링 차단 JavaScript 및 CSS 제거
- JavaScript 사용 최적화
- 비동기 JavaScript 리소스 선호
- 동기식 서버 호출 금지
- JavaScript 파싱 지연
- 장기적으로 실행되는 JavaScript 피하기
- CSS 사용 최적화
- CSS를 문서 헤드에 넣기
- CSS 가져오기(@import) 피하기
- 렌더링 차단 CSS를 인라인 처리
참고 사이트
https://velog.io/@ouo_yoonk/CRP-브라우저-렌더링-순서
https://blog.smilecat.dev/posts/critical-rendering-path-optimization#crp-최적화