면접 질문으로 나왔지만 한마디도 하지못했다🥲
정말 기본적인 지식인데 이것도 모르다니.. 시간내서 꼼꼼하게 정리해야겠다.
출처 : https://youtube.com/watch?v=sJ14cWjrNis&feature=share
주소 표시줄, 이전/다음/새로고침 버튼 등 웹 페이지를 제외하고 사용자와 상호작용 하는 사용자 인터페이스
HTML 과 CSS를 파싱하여 요청한 웹 페이지를 표시하는 렌더링 엔진
유저 인터페이스와 렌더링 엔진을 연결하는 브라우저 엔진
각종 네트워크 요청을 수행하는 네트워킹 파트
체크박스나 버튼과 같은 기본적인 위젯을 그려주는 UI 백엔드 파트
localStorage나 Cookie와 같이 보조 기억장치에 데이터를 저장하는 파트
자바스크립트 코드를 실행하는 인터프리터
여기서 우리는 브라우저의 렌더링을 보기위해서 Rendering Engine 에 대해서 알아볼까한다.
웹 브라우저마다 다른 렌더링 엔진을 사용한다.
safari = Webkit
Firefox = Gecko
Chrom = Blink ( 원래 Webkit을 사용하다가 2013년에 Webkit에서 갈라져 나온 Blink를 사용하고있다 )
HTML, CSS, JS, 이미지 등 웹 페이지에 포함된 모든 요소들을 화면에 보여준다.
업데이트가 필요할 때 효율적으로 렌더링을 할 수 있도록 자료 구조를 생성한다.
→ 업데이트 : 사용자 동작으로 인한 입력 발생, 스크롤, 애니메이션 동작, 비동기 요청으로 인한 데이터 로딩 등
브라우저가 하나의 화면을 그려내는 과정 또는 순서를 말한다.
출처 : https://www.dbswebsite.com/blog/understanding-the-critical-rendering-path/
간단하게 과정을 설명해보자면
1-1. HTML을 파싱해서 DOM을 만든다
1-2. CSS를 파싱해서 CSSOM을 만든다.
1. DOM과 CSSOM을 활용해서 Render Tree를 만든다.
2. Render Tree에서 Layout(reflow)을 실행해 각 노드의 형태를 계산한다.
3. Render Tree의 노드가 Paint(repaint) 과정을 거쳐서 화면에 웹 사이트가 렌더링된다.
→ 즉, 사용자가 웹 사이트를 볼 수 있게된다.
1-1. 파싱
브라우저에서 사용자가 요청한 웹 페이지의 문서를 불러오고 파싱한다.
파싱은 HTML을 보고 브라우저가 DOM 트리를 만드는 과정이다.
HTML과 DOM은 다르다. HTML은 '여기다가 헤더 만들거고, 그 아래에 타이틀 넣을 거야'라는 요구서같은 거고, DOM은 그걸 보고 브라우저가 만들어 낸 결과물이다.
1-2. 토큰화
이 코드는 어휘 분석을 통해서 HTML5 표준에 지정된 고유한 토큰으로 변환된다.
각 토큰은 특별한 의미와 고유한 규칙을 가진다.
예를 들어
<html>
는 html이 열렸다라는 의미를 가지고
</body>
는 body 태그가 닫혔다 라는 의미를 가진다.
1-3. 렉싱
브라우저 렉싱과정을 통해서 토큰이 해당 속성과 규칙을 정의하는 노드 객체로 변환된다.
1-4. DOM 생성
그리고 그 노드가 서로 연관성을 가질 수 있도록 트리를 생성한다. ( HTML은 상위-하위 관계로 정의할 수 있어, 트리 구조로 나타낼 수 있다. ) 이게 바로 DOM Tree이다.
출처 : https://youtube.com/watch?v=sJ14cWjrNis&feature=share
HTML 문서의 모든 것들은 다 DOM을 구성하게 된다.
최상위 → Document객체
Tag → Element 노드
Tag의 요소 → Attrubute 노드
Text → Text 노드
주석 → Comment 노드
출처 : https://youtube.com/watch?v=sJ14cWjrNis&feature=share
HTML을 DOM Tree로 만드는 과정과 비슷하게 CSS로는 CSSOM이라는 Tree가 만들어진다.
DOM이 어떻게 화면에 표시될지를 알려주는 역활을 한다.
CSS도 위에서 아래로 스타일 규칙이 정해지기 때문에 이 또한 트리 구조를 가지고있는데, 예를들어 스타일시트에서 body tag에 text-align:center;
속성을 정의했다면 body의 자식 요소들에게도 동일한 속성이 전파돼서 적용되게 된다.
DOM Tree와 CSSOM Tree를 합쳐서 Render Tree를 만든다.
출처 : https://youtube.com/watch?v=sJ14cWjrNis&feature=share
Render Tree는 화면에 표시되어야 할 모든 노드의 컨텐츠, 스타일 정보를 포함하는 트리이다.
Document 객체부터 각 노드를 순회하면서 각각에 맞는 CSSOM을 찾아서 규칙을 적용한다.
그러면서 렌더에 관련된 요소들을 렌더 트리에 포함시킨다. 이때 <meta>
태그나 display:none;
같은 속성을 가진 요소들을 렌더와 관계 없기 때문에 렌더트리에 포함되지 않는다.
Render Tree가 생성되면 Layout 과정을 거친다.
veiwport 내에서 요소들의 정확한 위치와 크기를 계산하는 과정이다.
박스모델에 따라서 화면에 차지하는 영역이나 여백, 스타일 속성이 계산된다. 이때 CSS에서 %나 em같은 상대적인 단위를 사용했을 때는 기계의 뷰폴트에 맞춰서 픽셀 단위로 변환된다.
레이아웃 과정에서 렌더링 엔진이 각 요소들이 어떻게 생겼고, 어떻게 보여줄지 알게되면 마지막으로 화면에 실제 픽셀로 그려지도록 변환하는 과정을 거친다. 이것이 Paint 과정이다.
이 과정에서 Render Tree에 포함된 요소들이나 텍스트, 이미지들이 실제 픽셀로 그려진다.
이 결과들은 레이어화 되어 관리되고 이후 합성 과정을 거쳐 사용자에게 보여진다.
HTML과 CSS를 가지고 렌더링 엔진이 어떻게 동작하는지를 살펴보았다.
Critical Rendering Path 의 시간을 줄이면 브라우저가 웹페이지를 보여주는데 걸리는 시간도 줄일 수 있다.
하지만 사용자 동작으로 JS가 실행되어서 CSS가 변경되거나 애니메이션 재생이 일어났을때 이때는 어떻게 될까?
크게 3가지 경우로 동작한다.
JavaScript → Style → Layout → Paint → Composite ⇒ Layout 부터
JavaScript → Style →Layout →Paint → Composite ⇒ Paint 부터
JavaScript → Style →Layout → Paint→ Composite ⇒ Composite 만
JavaScript → Style → Layout → Paint → Composite
주로 요소의 크기나 위치가 바뀔 때, 혹은 브라우저 창의 크기가 바뀌었을 때 다시 발생한다. 이때 레이아웃 수치를 계산해서 다시 배치 해줘야하기 때문에 Layout 과정이 다시 발생하고, 이에 맞춰서 Paint 과정, 레이아웃 합성 과정까지 거쳐야한다.
JavaScript → Style →
Layout →Paint → Composite
주로 배경이미지나 텍스트 색상, 그림자 등 레이아웃의 수치를 변화시키지 않는 스타일 변경이 일어났을 때 발생한다. 이때는 Layout 과정이 발생하지 않기 때문에 성능상으로 좀 더 이점을 가진다.
JavaScript → Style →
Layout → Paint→ Composite
Layout과 Paint을 수행하지 않고 레이어의 합성만 발생하기 때문에 성능상으로 가장 큰 이점을 가진다.
레이어는 포토샵의 레이어와 비슷하게 페이팅할 영역을 나눠놓은것을 의미한다. 크롬의 경우에는 Layout 과정 이후에 정해진 기준이나 필요에 의해서 브라우저가 레이어를 생성한다. 그리고 Render Tree에 있는 노드 객체들은 생성된 레이어에 포함되게 된다. 이 레이어들은 트리 형태로 구성된다. 렌더링 엔진이 레이어를 프린팅 과정에서 각각 그려준 다음에 하나의 비트맵으로 합성해서 페이지를 완성한다. 이때의 경우는 Layout 과 Paint 과정도 수행하지 않고 합성만 발생해서 성능상 가장 큰 이점을 가진다.
HTML, CSS를 기반으로 DOM Tree, CSSOM Tree를 생성한다.
DOM, CSSOM Tree가 생성되면 이걸 기반으로 Render Tree를 생성한다. 이때 Render Tree는 화면에 보여질 내용만 포함하기 때문에 display: none
, meta tag
와 같이 화면에 보이지 않는 것들은 포함하지 않는다.
Render Tree가 생성되면 Layout을 한다. Reflow라고도 부르는 과정이다. Viewport에 맞게 화면에 배치를 한다. 이때 %, em, rem과 같은 상대 단위는 모두 px 단위로 변경된다.
Layout 과정이 완료되면 paint 과정이 일어난다. 실제 화면에 그림을 그리는 과정이다.이 결과들은 레이어화 되어 관리되고 이후 합성 과정을 거쳐 사용자에게 보여진다.
사용자에게 보여지는 화면은 특정 이벤트를 통해 다시 그려지는 경우가 있다.
예를들어 크기가 변경되면 다시 viewport에 맞게 재계산을 해야하기 때문에 reflow 과정부터 repaint, 합성 과정을 거치게 된다.
그러나 그림자, 색상 변경과 같이 계산할 필요가 없는 값을 변경하면 repaint, 합성 과정을 거치게 된다.
마지막으로 transform과 같이 합성 과정만 거치는 경우도 있다.
위와 같이 어떠한 과정을 거쳐 화면에 보여지는 지 알게되면 렌더링 최적화를 할 수 있다.
예를들어 애니메이션을 구현한다고 할 때, left, top 과 같은 값을 변경하는 것보단 transform을 이용하면 더 빠르게 렌더링을 할 수 있다.
🔗 참고 링크
https://youtube.com/watch?v=sJ14cWjrNis&feature=share
https://codiving.kr/144
https://velog.io/@pse/브라우저의-렌더링-과정