중요 랜더링 경로
HTML, CSS, JavaScript로 작성된 문서를 파싱 하여 브라우저에 시각적으로 출력하는 것을 랜더링이라고 하며, 그 일련의 단계를 중요 랜더링 경로라고 한다.
- 파싱
- 리플로우 & 리페인트
- 페인트
1. 파싱
파싱은 텍스트 문서를 읽어 들여 실행하기 위해 문자열을 의미 있는 토큰(어휘 분석의 단위)으로 분해하고 토큰화 된 문자열들로 파스 트리를 생성하는 과정이다. 이러한 파싱을 전문적으로 해주는 부분을 파서라고 한다.
HTML, CSS는 랜더링 엔진에서 파싱 하고, JavaScript는 별도의 자바스크립트 엔진에서 파싱 한다.
(1) HTML 파싱과 DOM 생성
브라우저의 요청에 의해 서버가 응답한 HTML 문서는 문자열로 이루어진 순수한 텍스트이다. 따라서 앞서 설명한 파스 트리를 이용해 브라우저가 이해할 수 있는 자료구조(DOM 객체)로 변환하여 메모리에 저장해야 시각적인 픽셀로 렌더링 할 수 있다. 파스 트리를 바로 사용하지 않는 이유는 파스 트리는 토큰화 된 문자열을 구조화한 트리에 불과하고, DOM트리는 실제로 상호작용할 수 있는 HTML 엘리먼트로 이루어진 트리이기 때문이다.
처음부터 단계를 설명하면 다음과 같다.
1. 서버는 브라우저의 요청이 있으면 요청한 HTML 파일을 읽어 메모리에 저장한 다음 메모리에 저장된 바이트(2진수)를 인터넷을 경유하여 응답한다. 따라서 브라우저는 바이트 형태의 HTML 문서를 응답받는데, 이때 html 파일을 만들면 습관적으로 쓰던 <meta> 태그가 쓰인다.
<meta charset="UTF-8">
응답된 바이트 형태의 HTML 문서는 meta 태그의 charset 속성에 의해 지정된 인코딩 방식(UTF-8)을 기준으로 문자열로 변환된다.
2. 그 후 앞서 말했던 파싱 단계를 거치면서 토큰들을 객체로 변환, 노드를 생성한다. 토큰의 내용에 따라 문서 노드, 요소 노드, 어트리뷰트 노드, 텍스트 노드가 생성된다.
3. HTML 요소는 중첩 관계를 갖기 때문에 요소 간에는 중첩에 의한 부자 관계가 형성된다. 이러한 부자 관계를 반영하여 모든 노드들로 트리 자료구조를 구성하는데 이것을 DOM이라고 부른다. 즉 DOM은 HTML 문서를 파싱 한 결과물이다.
(2) CSS 파싱과 CSSOM 생성
랜더링 엔진은 HTML을 처음부터 한 줄씩 순서대로 파싱 하면서 DOM을 생성해 나가다가 <link>, <style>, <script> 같은 태그를 만나게 되면 파싱을 즉시 중단한다. href 속성에 지정된 CSS 파일을 서버에 요청하여서 로드한 CSS 파일이나 style 태그 내의 CSS를 HTML과 동일한 파싱 과정(바이트 > 문자 > 토큰 > 노드 > CSSOM)을 거치며 해석하여 CSSOM을 생성한다. CSS 파싱을 완료하면 HTML 파싱이 중단된 지점부터 다시 HTML을 파싱 하기 시작하여 DOM 생성을 재개한다. CSSOM은 CSS의 상속을 반영하여 생성된다.
(3) 랜더 트리 생성
랜더링 엔진은 DOM과 CSSOM을 생성하고, 랜더링을 위해 둘을 랜더 트리로 결합한다. 이때 브라우저 화면에 랜더링 되지 않는 노드와 CSS에 의해 비표시 되는 노드들은 포함하지 않는다. 즉 랜더 트리는 브라우저 화면에 랜더링 되는 노드만으로 구성된다.
<!-- 랜더링 하지 않는 노드 -->
<meta>
<script>
{
display : none;
}
.
.
.
랜더 트리는 각 HTML 요소의 레이아웃을 계산하는 데 사용되며 브라우저 화면에 픽셀을 렌더링 하는 페인팅 처리에 입력된다.
(4) JavaSript 파싱과 실행
DOM은 HTML 문서의 구조와 정보뿐만 아니라 HTML 요소나 스타일을 변경할 수 있는 프로그래밍 인터페이스로서 DOM API를 제공한다. 즉, 자바스크립트 코드에서 DOM API를 사용하면 이미 생성된 DOM을 동적으로 조작할 수 있다. 자바스크립트 파싱과 실행은 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다. 자바스크립트 엔진은 구글 크롬과 Node.js의 V8, 사파리의 JavaScriptCore 등 다양한 종류가 있으며 모두 ECMAScript 사양을 준수한다.
CSS 파싱 과정과 마찬가지로 렌더링 엔진은 HTML을 한 줄씩 파싱 하며 DOM을 생성해 나가다가 src 어트리뷰트가 있는 script 태그를 만나거나 자바스크립트 코드를 콘텐츠로 담은 script 태그를 만나면 DOM 생성을 중단한다. 제어권을 받은 자바스크립트 엔진은 자바스크립트 코드를 파싱 하기 시작한다. DOM과 CSSOM을 생성하듯 자바스크립트 코드를 해석하여 추상적 구문 트리(AST)를 생성 한다. 이 AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드인 바이트코드를 생성하고 실행한다.
2. 리플로우 & 리페인트
자바스크립트 코드에 DOM이나 CSSOM을 변경하는 DOMAPI가 사용된 경우 DOM이나 CSSOM이 변경된다. (상단 그림 참조)
이때 각각에 변경이 발생하면 다시 렌더 트리로 결합되고 레이아웃과 페인트 과정을 거쳐 브라우저 화면에 다시 렌더링 하게 되는데 이 과정을 리플로우, 리페인트라고 한다.
(1) 리플로우
레이아웃 계산을 다시 하는 것을 말한다. 노트 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경에 한해서 실행된다. 따라서 리플로우가 일어나면 반드시 리페인트가 일어난다.
position, width, height, margin, padding, border, border-width, font-size, font-weight, line-height, text-align, overflow
(2) 리페인트
재결합된 렌더 트리를 기반으로 다시 페인트를 하는 것을 말한다. 이때 레이아웃에 영향이 없는 변경이라면 리플로우 없이 리페인트만 실행된다.
background, color, text-decoration, border-style, border-radius
3. 페인트
렌더 트리를 기반으로 HTML 요소의 레이아웃을 계산하고 브라우저 화면에 HTML 요소를 페인팅한다. 페인팅은 z-index 축을 이용해 낮은 순서대로 먼저 페인팅된다.
'Programing > Javascript' 카테고리의 다른 글
[JS] 소셜웹페이지 - 댓글 추가기능 구현 (0) | 2022.08.06 |
---|---|
[JS] 소셜웹페이지 - 메인화면 (0) | 2022.08.06 |
[JS] 소셜웹페이지 - 로그인 UI (0) | 2022.08.02 |
[JS] 변수 호이스팅 (0) | 2022.07.28 |
[JS] HTMLCollection & NodeList (0) | 2022.07.19 |