FrontEnd
[프론트엔드 면접 대비] 브라우저의 렌더링 과정 알아보기
DevInvestor
2021. 8. 24. 00:52
반응형
모던자바스크립트 Deep Dive 책의 38장을 정리한 내용임
브라우저의 렌더링 과정 개요
- 파싱
- parse tree/ syntax tree를 생성하는 일련의 과정
- 파싱이 완료되면 파스 트리 기반으로 바이트 코드를 생성함
- 바이트 코드는 특정 하드웨어가 아니라 가상 머신에서 실행하도록 만든 바이너리 코드
- 렌더링
- html, css, js 문서를 파싱하여 브라우저에 시각적으로 출력하는 것
- CSSOM +DOM > Render Tree 생성 후 레이아웃, 페인팅을 통해 브라우저에 출력됨
브라우저는 다음 과정을 거쳐 렌더링을 수행함
- HTML, JS, CSS, 이미지, 폰트 파일 등 렌더링에 필요한 리소스를 요청하고 서버에서 응답받는다.
- CSS와 HTML로 각각 CSSOM과 DOM을 생성 후 결합하여 렌더 트리를 만든다
(렌더링 엔진)
- HTML 해석하다 CSS(스타일, 링크 태그)를 만나면 CSS를 파싱한다. 그 후 중단된 HTML 파싱 과정으로 돌아옴
- HTML을 파싱하다 JS를 만나면(script 태그)
자바스크립트 엔진
이 자바스크립트를 파싱하여 AST > 바이트코드로 변환하여 실행- 이때 실행되는 JS는 DOM과 CSSOM을 조작할 수 있음 >
script 실행 시점이 중요
- 이때 실행되는 JS는 DOM과 CSSOM을 조작할 수 있음 >
- 렌더 트리를 기반으로 레이아웃(위치와 크기) 계산 후 HTML 요소를 페인팅
- 브라우저의 기능은 필요한 리소스를 서버에 요청 및 응답받아 시각적 렌더링 및 인터랙션 제공
- 리소스 다운로드, 파싱, 렌더링, JS해석 & 실행
- 브라우저의 렌더링 엔진은 HTML을 파싱하는 도중 외부 리소스를 로드하는 태그를 만나면 HTML의 파싱을 일시 중단하고 해당 리소스 파일을 서버로 요청함
- script 태그
- img 태그
- link 태그 ...
- HTTP/1.1 vs HTTP/2
- HTTP/2는 다중응답/다중요청 가능
- HTTP/1.1은 응답 와야 다음 요청 보냄
HTML 파싱과 DOM 생성
- DOM은 HTML 문서를 파싱한 결과물인 트리 자료구조다
- 다운로드 한 리소스는
바이너리
에 불과- 파일 포맷에 맞게 파싱 > 자료구조로 변환 > 메모리 저장 필요
- 브라우저의
렌더링 엔진
은 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 자료구조인DOM
생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<ul>
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
<script src="app.js"></script>
</body>
</html>
- 서버에서 응답받은 HTML 프일은 바이너리에 불과 (바이트 - 2진수)
- 응답 헤더의
charset
에 따라 디코딩 (ex:utf-8
)content-type: text/html; charset=utf-8
- 문자열로 변환된 HTML 문서를 문법적 의미를 갖는 코드의 최소 단위인
토큰화
- 토큰을 객체로 변환하여
노드
생성- 노드는 document, attribute, text 노드 등이 있음
- DOM의 기본 구성 요소임
- HTML 노드의 부자 관계를 반영하여 트리 자료구조 만듬
- 이 트리 자료구조가
DOM
임
- 이 트리 자료구조가
- CSS도 동일하게 바이트 > 문자 >토큰 > 노드 > CSSOM을 거쳐 해석함
- link 태그나 style 태그 만나면...
렌더 트리 생성
- 렌더링 엔진은 DOM과 CSSOM을 결합하여
render tree
를 생성함- 렌더 트리는 렌더링을 위한 트리의 자료구조임
- 화면에 렌더링되지 않는 노드들은 포함되지 않음
- 브라우저 화면에 렌더링되는 노드만으로 구성
- ex) (display : none)인 css에 의해 비표시되는 태그, script태그, meta태그 등
- 화면에 렌더링되지 않는 노드들은 포함되지 않음
- 렌더 트리는 렌더링을 위한 트리의 자료구조임
- 렌더 트리는 레이아웃(위치와 크기) 계산과 페인팅(브라우저 화면에 렌더링)에 사용됨
- 레이아웃 계산과 페인팅은 반복 실행될 수 있음 (가급적 줄여야 함)
- 자바스크립트에 의한 노드 추가 / 삭제
- 브라우저 창의 리사이징에 의한
뷰포트
크기 변경 - HTML 요소의 레이아웃(위치,크기)을 변경시키는 스타일 변경
자바스크립트 파싱과 실행
- DOM은 HTML 문서의 구조와 정보, 스타일을 변경할 수 있는 DOM API 제공
- 자바스크립트 파싱은 자바스크립트 엔진이 실행함
- script 태그를 만나면 src 어트리뷰트에 정의된 파일을 서버에 요청 후 로드
- 렌더링 엔진이 자바스크립트 엔진에 제어권을 넘겨줌
- 자바스크립트 파싱 및 실행 종료 후 렌더링 엔진에 다시 제어권을 넘김
- AST > 바이트코드
- 토크나이징
- 소스코드를 문법적 의미 코드 최소 단위인 토큰으로 분해
- 파싱
- 토큰에 문법적 의미와 구조 반영한 AST(추상 구문 트리)를 생성
- 바이트코드 생성과 실행
- AST는 인터프리터(v8-ignition)가 실행할 수 있는 중간 코드인 바이트코드로 변환 후 실행됨
- JIT (v8-turbofan)에 의해 머신 코드로 컴파일 되기도 함
리플로우와 리페인트
- 자바스크립트 코드에 DOM이나 CSSOM을 변경하는 DOM API가 사용된 경우
- 렌더 트리로 다시 DOM과 CSSOM을 결합 후 레아이웃 > 페인트 과정 거쳐 다시 렌더링
리플로우
,리페인트
- 리플로우는 레이아웃을 다시 계산
- 노드 추가 삭제
- 요소 크기 위치 변경
- 윈도우 리사이징
- 리페인트
- 재결합된 렌더 트리 기반 다시 페인트
- 레이아웃에 영향이 없는 변경은 리플로우 없이 리페인트만 실행
자바스크립트 파싱에 의한 HTML 파싱 중단
- 렌더링 엔진과 자바스크립트 엔진은 파싱을 직렬적으로 실행
- 동기적, 순차적 HTML, JS, CSS 파싱 및 실행
- JS의 경우 DOM, CSSOM이 미완성된 경우 오류 가능
- 동기적, 순차적 HTML, JS, CSS 파싱 및 실행
- app.js에서 파싱이 다 끝나기 전에
- 요소를 조작하면?
- TypeError
- script 태그를 닫는 body 바로 위에 위치시키는 이유
- 로딩 전 DOM 조작 오류 방지
- 자바스크립트 실행 전에 DOM 생성이 완료되었으므로 페이지 로딩 시간 단축
- 다시 HTML을 파싱할 필요 없음
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<ul>
<li id="apple">Apple</li>
<li id="banana">Banana</li>
<li id="orange">Orange</li>
</ul>
<script>
/*
DOM API인 document.getElementById는 DOM에서 id가 'apple'인 HTML 요소를
취득한다. 아래 코드가 실행되는 시점에는 id가 'apple'인 HTML 요소의 파싱이 완료되어
DOM에 포함되어 있기 때문에 정상적으로 동작한다.
*/
const $apple = document.getElementById('apple');
// apple 요소의 css color 프로퍼티 값을 변경한다.
$apple.style.color = 'red';
</script>
</body>
</html>
script 태그의 async/defer 어트리뷰트
- 자바스크립트 파싱에 의해 DOM 생성이 중단되는 문제 해결 위한 어트리뷰트
- src 어트리뷰트가 없는 inline 자바스크립트에는 사용 불가
- 외부 파일 로딩에만 사용 가능
<script async src="extern.js"></script>
<script defer src="extern.js"></script>
- async
- 자바스크립트 로드만 비동기로 실행
- 다운 왼료되면 JS 실행하며 HTML 파싱 중단
- 여려개 있으면 다운 먼저된놈부터 실행됨
- 순서보장이 안됨
- defer
- 로드 비동기로 하고 마지막에 실행해줌
- DOMContentLoaded 이벤트
- HTML 파싱이 완료된 직후 발생
- 즉, DOM 생성이 완료된 직후 발생
- 좀 더 공부해보면 좋은 내용
- AST
- 바이트코드
- 기계어의 추상화
이 내용들은 면접에 무조건 나오는거 같다. 매번 복기하자.
반응형