요약
- HTML 마크업을 처리하고, DOM 트리를 빌드한다. (”무엇을” 그릴 지 결정한다.)
- CSS 마크업을 처리하고, CSSOM 트리를 빌드한다. (”어떻게” 그릴 지 결정한다.)
- DOM 및 CSSOM을 결합하여 렌더링 트리를 형성한다. (”화면에 그려질 것”만 결정한다.)
- 렌더링 트리에서 레이아웃을 실행하여 각 노드의 기하학적 형태를 계산한다. (”Box-Model”을 생성한다.)
- 개별 노드를 화면에 페인트한다.
브라우저의 주요 기능
브라우저의 주요 기능은 사용자가 선택한 자원을 서버에 요청하고, 브라우저에 표시하는 것이다.
자원은 보통 HTML 문서지만, PDF나 이미지, 다른 형태일 수 있다. 자원의 주소는 URI(Uniform Resource Identifier)에 의해 정해진다.
브라우저의 기본 구조
- 사용자 인터페이스
- 주소 표시중, 이전/다음 버튼, 북마크 메뉴 등 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분이다.
- 브라우저 엔진
- 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어
- 렌더링 엔진
- 요청한 컨텐츠를 화면에 표시한다.
- 통신
- HTTP 요청과 같은 네트워크 호출에 사용된다. 플랫폼 독립적인 인터페이스이고, 각 플랫폼 하부에서 실행된다.
- UI 백엔드
- 콤보박스와 같은 기본적인 장치를 그린다.
- 자바스크립트 해석기
- 자바스크립트 코드를 해석하고 실행한다.
- 자료 저장소
- 쿠키를 저장하는 것과 같이 모든 종류의 자원을 하드디스크에 저장할 필요가 있다. HTML5 명세에는 브라우저가 지원하는 ‘웹 데이터 베이스’가 정의되어있다.
렌더링 엔진
렌더링 엔진은 요청받은 내용을 브라우저 화면에 표시하는 역할이다.
Firefox는 Mozila에서 직접 만든 Gecko 엔진을 사용하고, 사파리와 크롬은 웹킷(Webkit) 엔진을 사용한다.
동작 과정
렌더링 엔진은 통신으로부터 요청한 문서의 내용을 얻는 것으로 시작하는데, 문서의 내용은 보통 8KB 단위로 전송된다.
렌더링 엔진의 기본적인 동작과정은 다음과 같다.
렌더링 엔진은 HTML 문서를 파싱하고, “컨텐츠 트리” 내부에서 태그를 DOM 노드로 변환한다. 그 다음 외부 CSS 파일과 함께 포함된 스타일 요소도 파싱한다. 스타일 정보와 HTML 표시 규칙은 “렌더 트리”라고 부르는 또 다른 트리를 생성한다.
렌터 트리는 색상 또는 면적과 같은 시각적 속성이 있는 사각형을 포함하고 있는데, 정해진 순서대로 화면에 표시된다.
렌더 트리 생성이 끝나면, 배치가 시작되는데, 이 것은 각 노드가 화면의 정확한 위치에 표시되는 것을 의미한다. 다음은 UI 백엔드에서 렌더 트리의 각 노드를 가로지르며 형상을 만들어내는 그리기 과정이다.
렌더링 엔진은 더 나은 사용자 경험을 위해 가능한 빠르게 내용을 표시하기 위해 모든 HTML을 파싱할 때까지 기다리지 않고, 배치와 그리기 과정을 시작한다.
파싱과 DOM 트리 구축
문서 파싱은 브라우저가 코드를 이해하고, 사용할 수 있는 구조로 변환하는 것을 의미한다. 파싱 결과는 보통 문서 구조를 나타내는 노드 트리인데, 파싱 트리(parse tree) 또는 문법 트리(syntax tree)라고 부른다.
파싱은 어휘 분석과 구문 분석이라는 두 가지로 구분할 수 있다.
어휘 분석은 자료를 토큰으로 분해하는 과정이다.
구문 분석은 언어의 구문 규칙을 적용하는 과정이다.
파싱은 파싱트리를 생성하고, 컴파일러를 통해 이를 기계코드 문서로 변환한다.
파서의 종류
파서는 하향식 파서와 상향식 파서가 있다.
하향식 파서는 구문의 상위 구조로부터 일치하는 부분을 찾기 시작한다.
상향식 파서는 낮은 수준에서 점차 높은 수준으로 찾는다.
HTML 파서
HTML 파서는 HTML 마크업을 파싱 트리로 변환한다. HTML의 어휘와 문법은 W3C에 의해 명세로 정의되어 있다.
모든 전통적인 파서는 HTML에 적용할 수 없다. 파싱은 CSS와 자바스크립트를 파싱하는 데 사용된다.
HTML 파서는 시작이나 종료 태그가 생략되어도 유연하게 파싱된다.
HTML이 일반적인 햐향식 또는 상향식 파서로 파싱이 안 되는 이유는
- 언어의 너그러운 속성
- 잘 알려져 있는 HTML 오류에 대한 브라우저의 관용
- 변경에 의한 재파싱. 일반적으로 소스는 파싱하는 동안 변하지 않지만, HTML에서
document.write
를 포함하고 있는 스크립트 태그는 토큰을 추가할 수 있기 때문에 파싱이 수정된다.
DOM
파싱 트리는 DOM 요소와 속성 노드의 트리로서 출력 트리가 된다. DOM은 문서 객체 모델(Document Object Model)의 준말이다. 이 것은 HTML 문서의 객체 표현이고, 외부를 향하는 자바스크립트와 같은 HTML 요소의 연결 지점이다. 트리의 최상위 객체는 문서이다.
<html>
<body>
<p>Hello world</p>
<div>
<img src"example.png" />
</div>
</body>
</html>
위 코드는 아래와 같은 DOM 트리로 변환할 수 있다.
CSS 파싱
HTML과 다르게 CSS는 문맥 자유 문법이고, 소개 글에서 설명했던 파서 유형을 이용하여 파싱이 가능하다.
렌더 트리 구축
DOM 트리가 구축되는 동안 브라우저는 렌더 트리를 구축한다. 표시해야 할 순서와 문서의 시각적인 구성 요소로써 올바른 순서로 내용을 그려낼 수 있도록 하기위한 목적이 있다.
DOM 트리와 렌더 트리의 관계
렌더러는 DOM 요소에 부합하지만, 1:1로 대응하는 관계는 아니다. 예를 들어, head
요소와 같은 비시각적 DOM 요소는 렌터 트리에 추가되지 않는다. 또한, display
속성에 “none” 값이 할당된 요소는 트리에 나타나지 않는다.
스타일 계산
렌더 트리를 구축하려면 각 렌더 객체의 시각적 속성에 대한 계산이 필요한데, 이 것은 각 요소의 스타일 속성을 계산함으로써 처리된다.
스타일은 인라인 스타일 요소와 HTML의 시각적 속성과 같은 다양한 형태의 스타일 시트를 포함하는데, HTML의 시각적 속성들은 대응하는 CSS 스타일 속성으로 변환된다.
배치
렌더러가 생성되어 트리에 추가될 때, 크기와 위치 정보는 없는데, 이런 값을 계산하는 것을 배치 또는 리플로라고 부른다.
HTML은 흐름 기반의 배치 모델을 사용하는데, 이 것은 보통 단일 경로를 통해 크기와 위치 정보를 계산할 수 있다는 것을 의미한다.
배치는 반복되며, HTML 문서의 <html>
요소에 해당하는 최상위 렌더러에서 시작한다. 배치는 프로임 계층의 일부 또는 정부를 통해 반복되고, 각 렌더러에 필요한 크기와 위치 정보를 계산한다.
최상위 렌더러의 위치는 (0,0)이고, 브라우저 창이 보이는 영역에 해당하는 뷰포트 만큼의 면적을 갖는다.
최적화
배치가 “크기 변경” 또는 렌더러 위치 변화 때문에 실행되는 경우, 렌더러의 크기는 다시 계산하지 않고, 캐시로부터 가져온다.
그리기
그리기 단계에서는 화면에 내용을 표시하기 위한 렌더 트리가 탐색되고, 렌더러의 “paint” 메서드가 호출된다. 그리기는 UI 기반의 구성요소를 사용한다.
전역과 점증
그리기는 배치와 마찬가지로 전역 또는 점증 방식으로 수행된다. 점증 그리기에서 일부 렌더러는 전체 트리에 영향을 주지 않은 방식으로 변경된다.
동적 변경
브라우저는 변경에 대해 가능한 한 최소한의 동작으로 반응하려고 노력한다. 그렇기 때문에, 요소의 색깔이 바뀌면 해당 요소의 리페인팅만 발생한다. 요소의 위치가 바뀌면 요소와 자식 그리고 형제의 리페인팅과 재배치가 발생한다. DOM 노드를 추가하면 노드의 리페인팅과 재배치가 발생한다. html
요소의 글꼴 크기를 변경하는 것과 같은 큰 변경은 캐시를 무효화하고, 트리 전체의 배치와 리페인팅이 발생한다.
렌더링 엔진의 스레드
렌더링 엔진은 통신을 제외한 거의 모든 경우에 단일 스레드로 동작한다.
파이어폭스와 사파리의 경우 렌더링 엔진의 스레드는 브라우저의 주요한 스레드에 해당한다. 크롬에서는 이 것이 탭 프로세스의 주요 스레드이다.
통신은 몇 개의 병렬 스레드에 의해 진행될 수 있는데, 병렬 연결의 수는 보통 2개에서 6개로 제한된다.
참고자료
Interview_Question_for_Beginner/FrontEnd at master · JaeYeopHan/Interview_Question_for_Beginner
'IT > 공통' 카테고리의 다른 글
[Git] 브랜치 일괄 삭제 (0) | 2022.08.23 |
---|---|
[VS Code] 파일 저장할 때 ESLint 동작하게 하기 (0) | 2022.01.27 |
REST API 정리 (0) | 2022.01.07 |
[Web Security] X-Frame-Options 헤더 (0) | 2021.10.08 |
[Web Security] X-XSS-Protection 헤더 (0) | 2021.07.15 |
댓글