브라우저의 동작원리에 대해

Shin Yeongjae·2023년 7월 5일
0

TIL

목록 보기
17/21

이전 블로그에서 글 옮김

2021년 10월 기준 크롬이 무려 65.05%의 점유율을 차지하고 있다. 우리나라의 경우를 생각해보면 인터넷 익스플로러(IE)부터 시작해서 크롬으로 옮겨가기 까지 많은 우여곡절이 있었던 것 같다. 나는 크롬이 출시되자마자 썼던 걸로 기억하는데 정부에서 제공하는 서비스를 이용할 수가 없어서 불편했던 기억이 있는데 이제는 크롬에서도 잘 동작하는것을 보면 정말 많이 변했구나 생각이 든다.

각설하고 이렇듯 브라우저라는 것이 웹에 있어서 뗄래야 뗄 수 없는 그런 존재이다. 그럼 과연 브라우저는 어떻게 동작을 하는지 알아보자.

브라우저

주요 기능

브라우저의 주요 기능은 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것이다. 자원은 보통 HTML 문서이지만, PDF나 이미지 또는 다른 형태일 수 있다.
자원의 주소는 URI(Uniform Resource Identifier)에 의해 정해진다.

구조

브라우저의 주요 구성 요소

브라우저를 구성하고 있는 요소는 다음과 같다.

  1. 사용자 인터페이스: 요청한 페이지를 보여주는 창을 제외한 나머지 부분 (ex: 주소 표시줄, 북마크 등)
  2. 브라우저 엔진: 사용자 인터페이스와 렌더링 엔진 사이의 동작 제. HTML 문서와 기타 자원의 웹 페이지를 사용자의 장치에 상호작용적인 시각 표현으로 변환
  3. 렌더링 엔진: 요청한 콘텐츠를 표시. HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시함.
    1. 게코(Gecko)엔진: 파이어폭스
    2. 웹킷(Webkit)엔진: 사파리, 크롬
  4. 통신: HTTP 요청과 같은 네트워크 호출에 사용되며 이것은 플랫폼의 독립적인 인터페이스이고 각 플랫폼 하부에서 실행됨.
  5. UI 백엔드: 콤보 박스와 창 같은 기본적인 장치를 그림. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용
  6. 자바스크립트 해석기: 자바스크립트 코드를 해석하고 결과를 렌더링 엔진으로 처리하는 자바스크립트 엔진
    1. 크롬: V8(Chromium 프로젝트의 일환으로 구글에서 자체 개발)
    2. 파이어폭스: SpiderMonkey(역사상 최초의 자바스크립트 엔진)
    3. 사파리: 니트로(구 SquirrelFish)
    4. 엣지: 차크라
    5. 오페라: V8
    6. IE: 차크라
  7. 자료 저장소: localStorage, IndexedDB 같은 스토리지 메커니즘 지원. 브라우저가 설치된 컴퓨터의 로컬 드라이브에 생성된 작은 데이터베이스.

크롬은 대부분의 브라우저와 달리 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지한다. 각 탭은 독립된 프로세스로 처리된다.

동작 과정

렌더링 엔진의 동작 과정
  1. HTML 문서를 파싱하여 DOM 트리를 생성한다.
  2. CSS 파일과 함께 포함된 스타일 요소를 파싱하여 CSSOM 트리를 생성한다.
  3. 만들어진 DOM 트리와 CSSOM 트리를 결합하여 렌더 트리를 생성한다.
  4. 렌더 트리를 배치한다. 이것은 각 노드가 화면의 정확한 위치에 표시되는 것을 의미한다.
  5. 렌더 트리를 그린다. UI 백엔드에서 랜더 트리의 각 노드를 가로지르며 렌더링한다.

위 과정들은 점진적으로 진행된다. 실제로 브라우저는 8KB 청크의 데이터를 수신하고 전체 HTML 페이지가 로드될 때까지 기다리지 않고 조금씩 렌더링을 시작한다.

실제 렌더링 과정을 나타낸 이미지

1. DOM(Document Object Model)트리 생성

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link href="style.css" rel="stylesheet">
    <title>Critical Path</title>
  </head>
  <body>
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg"></div>
  </body>
</html> 
HTML 파싱 과정

HTML 페이지는 바이트를 문자로 변환하여 토큰화 => 노드로 변환 => DOM 트리 생성 과정을 거치게 된다.
DOM 트리는 렌더링될 때 어떻게 표시할지는 알려주지 않는데, 그 정보는 CSSOM이 알려준다.

2. CSSOM(CSS Object Model)트리 생성

렌더링 엔진은 위에서 아래로 HTML 문서를 파싱하는데 이 때, <style>요소를 만나면 즉시 그 안의 CSS를 파싱한다.
HTML 문서의 파싱을 중단하고 CSS 룰셋을 파싱하는데 집중한다. CSS 파싱이 끝나면 다시 HTML 파싱으로 돌아간다.

body { 
   font-size: 16px; 
}

p { 
   font-weight: bold; 
}

span { 
   color: red;
}

p span { 
   display: none;
}

img { 
   float: right;
} 

CSS 또한 HTML과 마찬가지로 바이트를 문자로 변환 => 토큰화 => 노드로 변환 => CSSOM 트리 구축 과정을 거치게 된다.

CSS 파싱 과정
  • CSSOM이 트리 구조를 갖는 이유는 스타일은 하향식으로 규칙을 적용하게 된다. 페이지의 객체에 있는 스타일을 계산할 때, 브라우저는 해당 노드에 적용 가능한 가장 일반적인 규칙에서 더욱 구체적인 규칙을 적용하게 된다.
  • 위 트리는 완전한 CSSOM 트리가 아닌데 그 이유는 브라우저가 기본적으로 제공하는 user agent styles에서 스타일 시트가 재정의 하도록 결정한 스타일만 표시하기 때문이다.

3. 렌더 트리 생성

렌더 트리 생성 과정
  • 먼저 DOM 트리와 CSSOM 트리를 결합하여 렌더 트리를 형성한다.
  • 렌더 트리에는 페이지를 렌더링하는데 필요한 노드만 포함된다.
  • 렌더 트리는 페이지에 표시되는 모든 DOM 콘텐츠와 각 노드에 대한 모든 스타일 정보를 갖고 있다.

DOM 트리의 루트에서 시작하여 순회하는데 이 때 렌더링이 되지 않는 <script><meta>태그와 같은 노드들은 렌더 트리에서 생략된다.
일부 노드는 CSS를 통해 숨겨지며 렌더 트리에서도 생략된다. 예를 들면, display: none속성을 갖는 노드는 렌더 트리에서 생략된다.
이후 표시된 각 노드에 대해 매칭되는 CSSOM 규칙을 찾고 적용한다. 마지막으로 표시된 노드를 콘텐츠와 스타일과 함께 내보내게 된다.

4. 렌더 트리 배치

배치는 보통 다음과 같은 형태로 진행된다.
1. 부모 렌더러가 자신의 너비를 결정
2. 부모가 자식을 검토
1. 자식 렌더러를 배치(자식와 x와 y를 설정)
2. 필요하다면 자식 배치를 호출하여 자식의 높이를 계산
3. 부모는 자식의 누적된 높이와 여백, 패딩을 사용하여 자신의 높이 설정. 이 값은 부모 렌더러의 부모가 사용하게 됨

뷰포트 내에서 노드의 정확한 위치와 크기를 계산하는데, 페이지 내에서 각 객체의 정확한 위치와 크기를 계산하기 위해, 브라우저는 렌더 트리의 루트에서 시작하여 트리를 순회함.
레이아웃 과정의 결과는 Box Model이다. 박스 모델은 뷰포트 내에서 각 노드의 정확한 위치와 크기 정보를 담고 있다. 모든 상대적인 측정값은 화면에서 절대적인 픽셀로 변환된다.

5. 랜더 트리 그리기

마지막으로, 렌더 트리의 각 노드를 화면에서의 실제 픽셀로 변환한다.


Reference

profile
문과생의 개발자 도전기

0개의 댓글