머릿말

웹 브라우저는 가장 널리 사용되는 소프트웨어이다.
또한 웹 개발자로서 브라우저가 어떻게 동작하는지에 대한 이해는 반드시 필요하다고 생각한다.
이번 글에서는 브라우저가 내부적으로 어떻게 동작하는지에 대해 이해해보고자 한다.

브라우저의 역할

브라우저의 역할은 다음 2개와 같다

  1. HTTP Request를 구성하여 서버로 요청을 보낸다.
  2. 서버로부터 받은 HTTP Response를 해석하여 화면에 표시한다.

여러가지 유형의 리소스로 응답받을 수 있으나, 가장 근본적인 브라우저의 역할은
HTML 파일을 요청하고, 이를 응답받아 해석하여 화면에 표시하는 것이다.

하지만, HTTP가 발전함에 따라 HTML 이외 리소스(이미지, PDF파일 등등..)에 대해서도 브라우저가 해석하도록 발전했다.

브라우저의 구성요소

브라우저는 HTML 파일을 해석하기 위해 몇몇 모듈로 구성되고,
각 모듈들은 역할에 따라 HTML 문서를 해석하여 화면에 보여준다.

브라우저별로 각 구성요소별 상이한 점은 다소 있으나, 큰 맥락에서는 차이가 없다고 봐도 무방하다.
(예를 들면, Chrome 브라우저의 경우 각 탭에 하나씩 렌더링 엔진 인스턴스를 실행하므로, 각 탭이 별도의 프로세스에서 실행된다)

브라우저 구성요소(출처: https://web.dev/howbrowserswork/)

User Interface(사용자 인터페이스) ; UI

요청한 페이지가 표시되는 창을 제외한 브라우저의 모든 부분이 User Interface에 해당한다.

  • URI 표시 / 삽입을 위한 주소표시줄
  • 뒤로 / 앞으로 가기 버튼
  • 북마크 메뉴
  • 새로고침 / 중지 버튼
  • 홈 버튼

Networking

서버로부터 리소스를 가져오기 위한 네트워크 호출을 담당한다.
Request 형식 지정, 프록시 처리, 캐싱 등을 적용한다.

UI Back - End

기본적인 버튼, 입력 상자, 창과 같은 기본 위젯을 그리는 역할을 수행한다.
렌더링 엔진은 레이아웃 및 페인팅 단계에서 UI 백엔드 레이어를 사용하여 브라우저에 웹 페이지를 표시한다.

Javascript Interpreter

JavaScript 엔진은 DOM 또는 CSSOM에서 JavaScript 코드를 구문 분석하고 실행하는데 사용된다.
JavaScript 코드는 웹 서버에서 제공하거나 웹 브라우저에서 제공할 수 있다.

초기 브라우저는 JavaScript Interpreter(컴파일 없이 한 줄씩 바로 실행)를 사용했지만,
최신 JavaScript 엔진은 성능 향상을 위해 부분적으로 JIT 컴파일을 사용한다

JavaScript 엔진의 종류

  • Chrome : V8 JavaScript Engine
  • Safari : JavaScriptCore
  • FireFox : SpiderMonkey Engine

JIT : Just - In - Time
소스코드를 중간언어로 변환 하고 (IR : Intermediate Representation),
실행 시 IR을 해석하여 실행하는 방식이다.

대표적으로 Java가 JIT 방식에 해당하는 언어이다.
최근 JavaScript도 부분적으로 JIT 방식을 채택하여 사용하고 있다.

Data Storage

브라우저는 때때로 데이터를 로컬(쿠키, 캐시 등)에 저장해야 할 때가 있다.
이 때, Data Storage 가 이 부분을 처리한다.

최신 브라우저는 Local Storage, IndexedDB 및 File System과 같은 Storage 매커니즘도 지원한다.

Rendering Engine

브라우저의 구성요소로서 렌더링 엔진은 HTML의 구문 분석 후
브라우저 화면에 분석한 HTML을 표시한다는 점에서 구성요소 중 가장 큰 역할을 담당하고 있다.

브라우저의 발전 역사를 복기해보면 불행하게도, 표준화 되지 않고 체계가 없이 발전되어 왔다.
따라서 웹 표준과 호환성 측면에서 심각한 문제를 야기시켰다.
(물론 현재는 이런 문제를 인식하고, 웹 표준을 어느정도 준수하고 있다.)
브라우저의 렌더링 엔진도 이런 발전 과정에 따라 상이하게 개발되어 왔고, 브라우저마다 별도의 렌더링 엔진을 사용하게 되었다.

브라우저의 점유율 순위로 보면 Chrome, Safari, FireFox가 압도적으로 우세하며,
렌더링 엔진의 종류도 사실상 위 3가지 브라우저의 렌더링 엔진만 알아두면 될 듯 하다.

Browser Rendering Engine
FireFox Gecko
Safari WebKit
Chrome Blink(WebKit의 포크 버전)

렌더링 엔진의 구문 분석 주요 흐름

렌더링 엔진은 네트워크 계층에서 전달된 문서의 내용을 가져오면서, 화면에 점진적으로 표시해준다.

렌더링 엔진의 기본 흐름(출처: https://web.dev/howbrowserswork/)

렌더링 엔진의 주요 흐름을 디테일하게 이해하려면 반드시 Tree라는 자료구조에 대한 선행학습이 필요하다.

핵심만 정리하자면,

  1. HTMLDOM으로 객체화
  2. DOMCSS 같은 부가적인 레이아웃을 파싱하여 매핑시킴

사실상 렌더링 엔진은 위 2 단계를 반복, 점진을 통해 화면에 표시한다.
(상세한 내용은 글 마지막에 참고자료를 참고하길 바란다.)

생각해보자

브라우저의 구조를 파악해보면서 그간 겉핡기 식으로만 알고 있던 지식들이 한층 정리되는 느낌이었다.

  1. DOM(Document Object Model)이란 개념이 추상적인 개념이 아니라 구조적인 측면으로 이해할 수 있다.
    Java에서 클래스와 객체를 흔히 붕어빵틀과 붕어빵으로 비유하곤 한다.
    DOM도 이제 와서 생각해보니 일종의 HTML이라는 클래스의 객체라고도 이해할 수 있을 것 같다.
  2. Apple은 왜 WebKit이라는 렌더링 엔진을 오픈소스로 공개했을까?
  3. SSR(Server Side Rendering) 에서의 렌더링이란 개념이 브라우저의 렌더링 엔진과 연관이 있는가?

브라우저에 대해 더 자세히 알고싶으면,

참고자료