본문 바로가기
생각/글쓰기

[브라우저 이해하기] 2. 브라우저 엔진 들여다보기 (Webkit)

by 3604 2023. 11. 6.
728x90

출처: https://codecraft.tistory.com/entry/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-2-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%97%94%EC%A7%84-%EB%93%A4%EC%97%AC%EB%8B%A4%EB%B3%B4%EA%B8%B0-Webkit

브라우저를 구성하는 요소들중 단연 중요한것은 '엔진'일 것이다.

사용자가 주소를 입력하는 시점부터, 브라우저 영역안에 웹 컨텐츠들이 보여지기까지 어떤 일들이 일어나는지를 이해하기 위해 꼭 짚고 넘어가야할 요소이다.

 

*본문의 내용들은 Html5rocks에서 Tali Garsiel과 Paul Irish가 작성한 'How Browsers Work: Behind the scenes of modern web browsers' 본문에서 상당부분 참고, 인용하였음

 

브라우저를 구성하는 엔진'들'

브라우저는 사실 여러 엔진'들'로 구성되어 있다.

예시로 Chrome 브라우저를 살펴보면 브라우저 엔진은 Chromium, 렌더링(레이아웃) 엔진은 Blink, JS 런타임(JS 엔진)은 V8이라 불린다.

크롬 브라우저 구성엔진 (출처 : bloggeek)

 

브라우저 엔진이란?

브라우저 엔진은 사용자가 어떤 액션을 하는 것부터(인터페이스), 화면에 결과물을 그래픽으로 보여주기까지의 과정에 관여한다.

웹이 점점 발전함에 따라 엔진은 고도화 되었고, 화면에 결과물을 보여주는 렌더링 엔진과 JS 구문을 분석하는 JS 런타임 엔진이 별도로 분리 되었다.

 

렌더링 엔진이란?

렌더링 엔진은 사용자가 요청한 HTML 문서와 CSS(서식 정의)를 파싱하여 화면에 그리는 역할을 수행한다.

렌더링 엔진은 종종 브라우저 엔진과 같은 의미로 불리기도 한다. 용어적으로 분리가 명확하지 않은 이유는 JS 엔진이 브라우저 없이 독립적으로 실행(ex: Node.js)될 수 있는 반면, 렌더링 엔진은 그렇지 않기 때문이다.

 

렌더링 엔진 동작 과정 (Critical Rendering Path)

렌더링 엔진은 네트워크 계층으로부터 문서를 전송받는 것으로 시작된다. 기본적인 동작과정은 다음과 같다.

Webkit 엔진의 동작 과정 (출처 : 네이버 D2)

1. HTML 파싱

HTML은 알다시피 여러개의 태그로 구성되어 있다. 엔진은 이 태그들을 파싱하여 DOM(Document Object Model) node로 변환한다. DOM node들이 계층 구조로 구성되어 DOM tree가 구축된다.

 

2. CSS 파싱

HTML 파싱이 이루어짐과 동시에 CSS를 파싱하여 CSSOM(Cascading Style Sheet Object Model)을 생성한다.

 

3. 어테치먼트 (렌더트리 생성)

앞서 생성된 DOM tree와 CSSOM을 결합하여, 색상 및 면적 등의 시각적 정보를 담은 Render tree를 구축한다. 이 과정에서 화면에 표시되지 않는 DOM node(ex: head tag, display:none 속성의 node)는 제외된다.

 

Reflow(Layout) & Repaint(Redraw) 그리고 Composite

*Webkit 엔진 기준으로는 Layout이 맞지만, 이 글에선 Reflow로 표현할것이다. (같은 의미)

 

Reflow는 레이아웃(margin, padding, width, height 등) 변경이 발생할때 트리거 되며, 연관된 노드의 레이아웃을 다시 계산하여 렌더트리를 조정한다.

 

Repaint는 가시성과 관련된(color, background-color, visibility 등) 변경이 발생할때 트리거 되며, 전체 노드의 가시성을 다시 확인하고 Layer를 생성한다.

*Opera Dev 사이트에 따르면, Repaint는 엔진이 모든 요소를 ​​탐색하며 가시성을 판단해야 하므로 성능 면에서 비용이 많이 든다고 한다.

 

Composite은 생성된 Renderer Layer를 합성하는 단계로 2개 이상의 Layer를 하나의 비트맵으로 합성하는 과정이다.

 

*위 동작들의 자세한 내용과 최적화 방법에 대해서는 다음 글에서 자세히 다뤄볼것이다.

 

스크립트와 스타일 시트의 실행 순서

예측 파싱

Webkit, Gecko 등 메이저 엔진은 예측 파싱과 같은 최적화를 지원한다. 스크립트를 실행하는 동안에도 다른 스레드를 활용하여 네트워크로 부터 자원을 다운로드 받고 파싱을 진행한다. '예측 파서'는 DOM 트리를 직접 수정하지 않고, 메인 파서에게 해당 작업을 넘긴다. 예측 파서는 외부 스크립트, 외부 스타일 시트와 외부 이미지와 같이 참조된 외부 자원만을 파싱한다.

 

스크립트 로딩

웹은 파싱과 실행이 동시에 이루어지는 동기화 모델을 가지고 있다. 웹 개발자는 파서가 <script>태그를 만나자 마자(순서대로) 실행되기를 기대하며, 이는 곧 다음 본문의 파싱을 중단하고 스크립트를 우선 실행한다는 뜻이기도 하다.

동기화 방식의 문제는 스크립트를 네트워크에서 별도로 가져와야 할때, 네트워크의 응답까지 동기적으로 대기한다는 것이다. 한마디로 매우 비효율적이다.

 

브라우저는 이를 해결하기 위한 대안 2가지를 제공한다.

1. defer 속성 : 스크립트 실행을 지연시키는 방법으로, 백그라운드에서 스크립트를 다운받고 본문 파싱이 끝난 뒤에 해당 스크립트 실행을 보장한다. (정확히는 본문 파싱 이후 & DOMContentLoaded 이벤트 발생전 시점에 스크립트가 실행된다)

2. async 속성 : 스크립트를 비동기적으로 실행하는 방법으로, 백그라운드에서 스크립트를 다운받으며 다운로드가 끝나는 시점에 본문 파싱을 중단하고 스크립트를 실행시킨다. 즉, 실행 시점 및 순서가 보장되지 않는다.

 

스타일 시트 로딩

스타일 시트는 CSSOM이라는 별도의 모델을 생성하여 관리한다. 이론적으로 스타일 시트는 DOM 트리의 구조를 변경하지 않기 때문에 문서 파싱을 기다리거나 중단할일이 없다. 하지만 반대로 스크립트가 실행되는 동안 스타일 속성을 참조해야하는 경우에는 문제가 될 수 있다.

그래서 Webkit에서는 로드되지 않은 스타일 시트 가운데 문제가 될만한 속성이 있을때는 스크립트를 중단하고 스타일시트가 로드되길 기다린다.

 

렌더 트리 구축

문서를 파싱하며 DOM 트리가 구축되는 동안 엔진은 렌더 트리를 구축한다. 각 요소의 올바른 위치를 계산하고 표현하기 위함이다.

 

웹킷 렌더러의 기본 클래스인 RenderObject 클래스는 다음과 같이 정의되어 있다.

class RenderObject {
    virtual void layout();
    virtual void paint(PaintInfo);
    virtual void rect repaintRect();
    Node * node; //the DOM node
    RenderStyle * style; // the computed style
    RenderLayer * containgLayer; //the containing z-index layer
}

각 렌더러는 CSS2 명세에 따라 노드의 CSS 박스에 부합하는 사각형을 표시한다. 렌더러는 너비, 높이 그리고 위치와 같은 기하학적 정보를 포함한다. 참고로, 박스 노드는 "display" 스타일 속성의 영향을 받는다.

 

스타일 계산

렌더 트리를 구축하려면 각 렌더 객체의 시각적 속성에 대한 계산이 필요한데 이것은 각 요소의 스타일 속성을 계산함으로써 처리된다.

스타일을 계산하는 일에는 다음과 같은 몇 가지 어려움이 따른다.

  1. 스타일 속성은 굉장히 광범위하고, 이를 수용하는 과정에서 메모리 문제를 야기할 수 있다.
  2. 최적화되어 있지 않다면 각 요소에 할당된 규칙을 찾는 것은 성능 문제를 야기할 수 있다.
  3. 규칙을 적용하는 것은 계층 구조를 파악해야 하는 꽤나 복잡한 다단계 규칙을 수반한다.

브라우저가 이 문제를 어떻게 처리하는지 살펴보자.

 

구조체로 분리

스타일 컨텍스트는 구조체(structs)로 분리된다. 이 구조체는 border나 color와 같은 특정 카테고리로 분리된다. 요소에 정의되지 않은 속성은 상위 노드의 속성을 그대로 사용한다. 단, 상속되지 않기(reset)로 속성이 정의되어 있다면 기본값을 사용한다.

 

이 과정에서 트리구조는 이미 계산된 값들을 캐싱할 수 있게 해주어, 엔드 노드에서의 불필요한 계산 작업을 줄여준다.

 

규칙 트리를 사용하여 스타일 문맥을 계산

어떤 요소의 스타일 컨텍스트를 계산할 때 가장 먼저 규칙 트리의 경로를 계산하거나 또는 이미 존재하는 경로를 사용한다. 그 다음 새로운 스타일 컨텍스트로 채우기 위해 경로 안에서 규칙을 적용한다. 가장 높은 우선순위(보통 가장 구체적인 선택자)를 가진 경로의 하위 노드에서 시작하여 구조체가 가득 찰 때까지 트리의 상단으로 거슬러 올라간다. 

스타일 정보 공유

웹킷 노드는 스타일 객체(RenderStyle)를 참조하는데 이 객체는 일정 조건 아래 공유할 수 있다. 주로 노드가 형제이거나 또는 사촌일 때 공유하며 자세한 내용은 성능 최적화에 관한 다른 글에서 살펴볼 것이다.

Cascading(다단계) 순서에 따라 규칙 적용하기

스타일 객체는 모든 CSS 속성을 포함하고 있는데 어떤 규칙과도 일치하지 않는 일부 속성은 부모 요소의 스타일 객체로부터 상속 받는다. 그 외 다른 속성들은 기본 값으로 설정된다.

문제는 하나 이상의 속성이 정의될 때 시작되고 다단계 순서가 이 문제를 해결하게 된다.

 

스타일 시트 Cascading 순서

 

스타일 속성 선언은 여러 스타일 시트에서 나타날 수 있고 하나의 스타일 시트 안에서도 여러 번 나타날 수 있는데 이것은 규칙을 적용하는 순서가 매우 중요하다는 것을 의미한다. 이것을 "다단계(cascade)" 순서라고 한다. CSS2 명세에 따르면 다단계 순서는 다음과 같다(우선 순위가 낮은 것에서 높은 순서임)

  1. 브라우저 선언 (browser declarations)
  2. 사용자 일반 선언 (user normal declarations)
  3. 저작자 일반 선언 (author normal declarations)
  4. 저작자 중요 선언 (author important declarations)
  5. 사용자 중요 선언 (user important declarations)

 

Reflow (Layout)

렌더러(RenderObject)가 생성되어 트리에 추가될 때 크기와 위치 정보는 없는데 이런 값을 계산하는 것을 Reflow(Layout)라고 부른다.

HTML은 흐름 기반의 배치 모델을 사용하는데 이것은 보통 단일 경로를 통해 크기와 위치 정보를 계산할 수 있다는 것을 의미한다. 일반적으로는 흐름상 나중에 등장한 요소가 앞서 배치된 요소에 영향을 주지 않기 때문에, 배치는 왼쪽에서 오른쪽으로, 위쪽에서 아래쪽으로 흐르게 된다.

단, table 요소는 크기와 위치를 계산할때 하나 이상의 경로를 필요로 하기 때문에 예외가 된다.

 

배치는 최상위 렌더러인 <html>태그에서 시작된다고 볼 수 있다. 최상위 렌더러는 뷰포트만큼의 크기를 갖게된다. 모든 렌더러는 Reflow(Layout)메소드를 갖게 되는데, 이는 각각 자식 요소의 Reflow 메소드를 호출한다.

 

Reflow 최적화

Dirty Bit 시스템

소소한 변경 때문에 전체를 다시 배치하지 않기 위해 브라우저는 "Dirty Bit" 시스템을 사용한다. 렌더러는 다시 배치할 필요가 있는 변경 요소 또는 추가된 것과 그 자식을 "Dirty"로 표시한다.

전역(Global) 배치와 점증(Incremental) 배치

배치는 렌더러 트리 전체에서 발생할 수 있는데 이를 '전역' 배치라 부른다.

전역 배치는 주로 글꼴크기 변경, 화면 크기 변경과 같이 모든 렌더러에 영향을 주는 전역 스타일 변경 케이스에 발생한다.

점증 배치는 렌더러가 더티상태일때 비동기적으로 발생하는데, 대표적인 예로는 네트워크를 통해 본문이 추가되어 Renderer(RenderObject)가 Tree에 추가되었을때 발생한다.

비동기 배치와 동기 배치

점증배치는 비동기로 실행된다. 웹킷은 비동기 타이머에 의해 점증배치가 트리거되며, 이때 트리를 탐색하여 "더티" 렌더러를 배치한다.

이때 offsetHeight과 같은 스타일 정보를 요청하는 스크립트는 동기적으로 점증배치된다.

브라우저의 배치 최적화

만약 배치가 리사이즈 또는 렌더러 위치 변경에 의해 트리거 되는 경우, 사이즈를 다시 계산하지 않고 캐시에서 가져온다.
어떤 경우는 하위 트리만 변경되는데, input에 텍스트를 입력할때와 같이 한정된 범위 내에서 발생하는 변화는 최상위(root)에서 부터 트리거 되지 않는다.

배치 과정

배치는 보통 다음과 같은 과정으로 실행된다.

 

1. 부모 렌더러가 자신의 너비(width)를 결정

2. 부모가 자식 렌더러를 확인

    1. 자식 렌더러 배치 (x, y 좌표 결정)

    2. (더티 상태이거나, 전역 배치 작업인 경우) 자식의 배치 메소드 호출

3. 자식의 누적된 높이와 여백값을 통해 자신의 높이를 결정

4. 더티비트 플래그를 제거

너비 계산

렌더러의 너비는 컨테이너(부모)의 너비, 렌더러에 설정된 너비값(width) 그리고 여백과 테두리(border)에 의해 계산된다.

웹킷은 다음(RenderBox 클래스의 calcWidth 메서드)과 같이 계산한다.

  • 컨테이너의 너비는 컨테이너 availableWidth와 0 사이의 최대값이다. 이 경우 availableWidth는 다음과 같이 계산된 contentWidth이다.
clientWidth() - paddingLeft() - paddingRight()
  • clientWidth와 clientHeight는 객체의 테두리(border)와 스크롤바를 제외한 내부 영역을 의미한다.
  • 요소의 너비는 "width" 스타일 속성의 값이다. 이 값이 %로 정의되어 있다면 계산된 절대 값으로 변환될 것이다.
  • 여기까지 계산된 너비에 좌우측 테두리와 패딩 값이 추가된다.
    여기까지 "희망 너비"의 계산이었다. 이제는 최소 너비와 최대 너비를 계산해야 한다.
  • 희망 너비가 최대 너비보다 크면 최대 너비가 사용된다. 미리 획득한 너비가 최소 너비(깨지지 않는 가장 작은 단위)보다 작으면 최소 너비가 사용된다.

계산된 값은 너비가 변하지 않으면서, 배치에 활용되는 경우에 캐싱된다.

줄바꿈

렌더러가 배치를 수행하는 동안, 줄을 바꿀 필요가 있음이 감지되면 부모에게 이를 전달한다. 이때 부모는 추가 렌더러를 생성하고 배치를 호출한다.

페인팅 (painting)

페인팅 단계에서는 화면에 그리기 위해 렌더트리가 탐색되고 "paint()" 메소드가 호출된다. 그리기 단계는 UI 인프라 컴포넌트(아마 OS 레벨의 그래픽 컴포넌트를 의미하는듯)를 이용한다.

전역 페인팅 점증 페인팅

배치와 비슷하게, 페인팅도 전역 & 점증 방식으로 구분된다.

  • 점증 페인팅은 당연하지만 전체 트리에 영향을 주지 않는 변경사항을 반영할때 트리거 된다. 변경된 렌더러는 화면상의 사각형 영역을 무효화 한다. 이는 OS입장에서 "더티 영역"으로 인식하도록 하여 "paint"이벤트를 발생시킨다.
  • 크롬의 경우는 렌더러가 메인 프로세스 분리된 별도의 프로세스에서 실행되기 때문에 좀 더 복잡하다. 그래서 크롬은 OS의 페인팅 방식을 모방한다. (이를 구성하는 RenderLayer는 다른 글에서 자세히 알아볼것이다)
  • 프레젠테이션(화면 출력을 담당하는 프로세스를 뜻하는듯)은 이런 이벤트를 탐지하고 최상위 렌더러로 보낸다. 이후 "paint" 이벤트가 발생한 영역에 맞는 렌더러에 도달할때 까지 전체 트리를 탐색한다.
  • 해당되는 렌더러를 찾으면 repaint를 실행한다.

페인팅 순서

CSS2 명세에는 페인팅 과정의 순서가 적혀있고, 이는 실제로 element가 stacking contexts에 쌓이는 순서와 동일하다. 스택은 앞에서 뒤로 그려지기 때문에 실제로 페인팅 결과물에 영향을 준다.

블록 렌더러가 쌓이는 순서는 다음과 같다 :

1. background color
2. background image
3. border
4. children
5. outline

Webkit의 사각형 스토리지

리페인팅 전에 웹킷은 기존의 사각형을 비트맵으로 저장하여 새로운 사각형과 비교하고 차이가 있는 부분만 다시 그린다.

동적 변경

브라우저는 변경에 대해 가능한 한 최소한의 동작으로 반응하려고 노력한다. 그렇기 때문에 요소의 색깔이 바뀌면 해당 요소의 리페인팅만 발생한다. 요소의 위치가 바뀌면 요소와 자식 그리고 형제의 리페인팅과 재배치가 발생한다. DOM 노드를 추가하면 노드의 리페인팅과 재 배치가 발생한다. "html" 요소의 글꼴 크기를 변경하는 것과 같은 큰 변경은 캐시를 무효화하고 트리 전체의 배치와 리페인팅이 발생한다.

렌더링 엔진의 스레드

렌더링 엔진은 통신을 제외한 거의 모든 경우에 단일 스레드로 동작한다. 크롬에서는 이것이 탭 프로세스의 메인 스레드이다.

*파이어폭스와 사파리의 경우 렌더링 엔진의 스레드는 브라우저의 메인 스레드에 해당한다. 

통신은 몇 개의 병렬 스레드에 의해 진행될 수 있는데 병렬 연결의 수는 보통 2개에서 6개로 제한된다.

이벤트 루프

브라우저의 메인 스레드는 이벤트 루프이다. 이는 프로세스를 항상 유지하기 위해 무한히 반복된다.

이벤트 루프는 배치, 페인팅과 같은 이벤트를 기다리며 이를 실행시키는 역할을 수행한다. 

CSS2 시각 모델

CSS2 명세에 따르면, 캔버스는 '서식 구조가 렌더링되는 공간'으로 정의되어 있다. (즉, 브라우저가 내용을 그리는 공간을 뜻한다)

캔버스 공간의 면적은 무한하지만, 브라우저는 뷰포트에 기초해 초기 너비를 결정하게 되는것이다.

 

CSS2 명세에 따르면, 캔버스는 기본적으로 투명하기 때문에 다른 캔버스와 겹치면 비쳐보이고, 겹쳐져있지 않다면 브라우저에서 정의한 색상이 보여지게 된다.

CSS 박스 모델

CSS 박스 모델은 엘리먼트 단위로 생성되고, 시각적 서식 모델에 의해 배치된다.

각 박스는 콘텐츠(텍스트, 이미지 등) 영역과 padding, margin, border 영역(선택적)이 있다.

CSS2 박스 모델 (출처: html5rocks)

각 노드는 이런 박스를 각각 생성한다.

모든 요소는 "display" 속성을 갖는데, 이 속성이 박스의 유형을 결정하게 된다.

예시로

- block : 블록 박스를 만든다

- inline : 하나 이상의 인라인 박스를 만든다

- none : 박스를 만들지 않는다

 

원래 기본값은 inline이지만 브라우저 기본 스타일시트에 정의된 값은 통상 다르다. 예를들면 div의 브라우저 기본값은 block이다.

브라우저 기본 스타일 시트예제는 다음 사이트에서 확인할 수 있다.
www.w3.org/TR/CSS2/sample.html

 

Default style sheet for HTML 4

 

www.w3.org

위치 결정 방법 (positioning scheme)

브라우저가 위치를 결정하는 방법은 3가지이다.

 

1. normal : 객체는 문서 안의 자리에 따라 위치가 결정된다. 이것은 렌더 트리에서 객체의 자리가 DOM 트리의 자리와 같고 박스 유형과 면적에 따라 배치됨을 의미한다.

2. float : 객체는 우선 일반적인 흐름에 따라 배치된 다음, 갈 수 있는 한 왼쪽이나 오른쪽으로 이동한다.

3. absolute : 객체는 DOM 트리상의 위치와 별개인 렌더 트리 위치에 놓인다.

 

위치는 CSS상 "position" 속성과 "float" 속성에 의해 결정된다.

  • static과 relative로 설정하면 일반적인 흐름에 따라 위치가 결정된다.
  • absolute와 fixed로 설정하면 절대적인 위치가 된다.

position 속성을 정의하지 않으면 기본값인 static이 적용되며 이는 normal 방식으로 위치를 결정한다. static이 아닌 다른값(relative, absolute, fixed)이 설정되면 top, bottom, left, right 속성으로 위치를 결정할 수 있다.

 

박스의 위치는 다음 요인들에 의해 결정된다

  • 박스 유형(display 속성)
  • 박스 면적(width, height)
  • 위치 결정 방법(position, float)
  • 외부적인 정보(이미지 사이즈, 화면 크기 등)

박스 유형

블록 박스 : 브라우저 창에서 사각형 블록을 생성한다.

block box 이미지 (출처: html5rocks)

인라인 박스 : 자체적인 블록은 없지만 컨테이너 블록 안에 존재한다.

inline box 이미지 (출처: html5rocks)

block은 수직적으로 배치되고, inline은 수평적으로 배치된다.

block과 inline 서식 (출처: html5rocks)

inline 박스는 line 또는 "line box" 안쪽에 놓인다. line은 가장 높이가 긴 box만큼 길어질 수 있고, "baseline" 정렬 방식(기본값)에선 더 길어질수 있다.

 

**baseline 정렬 방식은 글자의 꼬리부분을 제외한 하단을 기준으로, 다른 요소와 함께 정렬되기 때문에 높이가 요소의 최대 크기 이상으로 길어질 수 있다. (아래 그림 참고)

text 영역 설명 (출처: velog)

 

포함하는 너비가 충분하지 않으면 inline은 여러 line으로 배치되는데 이것은 주로 문단에서 발생하는 현상이다.

Line 영역 설명 (출처: html5rocks)

포지셔닝

상대 위치(relative)

Relative 포지셔닝은 일반적인 흐름에 따라 배치한 다음, 필요한 만큼 좌표를 이동하는 방식이다.

상대적 포지셔닝 설명 (출처: html5rocks)

떠있는 위치(float)

Float box는 라인의 왼쪽 또는 오른쪽으로 이동된다. 흥미로운 점은, 다른 box들은 이 영역 주변으로 흐른다는 것이다.

예를들어 빨간 상자가 float box라면 아래 그림 처럼 배치된다.

float 설명 (출처: html5rocks)

절대 위치(absolute)와 고정 위치(fixed)

절대, 고정 위치는 일반적인 배치 흐름과 무관하게 결정된다. 다만 면적은 컨테이너의 면적에 영향을 받는다.

*Fixed의 경우 컨테이너는 뷰포트가 되며, 따라서 스크롤을 해도 항상 동일한 위치에 배치된다.

fixed 위치 설명 (출처: html5rocks)

레이어 표현 (layered representation)

레이어를 표현하는 방법은 z-index 라는 속성을 통해 가능하다. 이는 박스 배치에서 3차원 축(z축)을 뜻하며 이에 따라 레이어의 배치가 결정된다.

각 박스는 스택(stacking contexts)으로 구분된다. 각 스택에서 뒤쪽에 있는 요소가 먼저 그려지고, 앞쪽에 있는 요소가 가장 나중에 그려진다. 당연하게도, 나중에 그려진 요소(앞쪽)가 먼저 그려진 요소(뒤쪽)을 가리게 된다.

 

맺으며

이렇게 브라우저의 엔진의 구성요소중 가장 중요하다고 생각되는 렌더링 엔진을 먼저 살펴봤다.

최신버전의 소스를 분석한 글은 아니지만, 엔진을 구성하는 기본적인 틀은 이 내용에서 크게 벗어나지 않았기에 브라우저의 동작을 이해하는데 큰 도움이 되었다.

 

다음 글에서는 점점 영역을 넓혀가고 있는 JS 런타임 엔진을 살펴볼 것이다.

 

 

 

참고 문서

참고 문서

https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/

https://d2.naver.com/helloworld/59361

https://bloggeek.me/chrome-only-browser/

https://www.lambdatest.com/blog/browser-engines-the-crux-of-cross-browser-compatibility/

https://developers.google.com/web/updates/2018/09/inside-browser-part3?hl=ko 

https://d2.naver.com/helloworld/59361

https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=ko

https://github.com/im-d-team/Dev-Docs/blob/master/Browser/Layer_Model.md

https://velog.io/@ursr0706/vertical-align

728x90