[Chromium] 브라우저의 원리 알아보기 - Chromium 아키텍처

이진우·2025년 5월 4일
0

브라우저 렌더링 과정에 대해서 설명해주세요

익숙한 질문인가요? 웹 개발자 기술 면접의 단골 질문이지만, 저는 지금까지 '대충' 알고 넘어갔었습니다. 이번 기회에 브라우저를 제대로 알고자 Chromium project를 분석해보려고합니다.
Chromium을 분석 대상으로 선정한 이유는 현대 웹 브라우저 생태계에서의 압도적인 영향력 때문입니다. 현재 시장 점유율이 가장 높은 Google Chrome을 비롯하여 Microsoft Edge, Opera, Naver Whale, Brave, Vivaldi 등 수많은 주요 웹 브라우저들이 Chromium의 오픈 소스 코드를 기반으로 개발되고 있습니다.
이 글에서는 브라우저의 동작 방식부터 Chromium의 실제 구조까지 파헤쳐보겠습니다.

🤔 브라우저는 어떻게 동작할까?

먼저 브라우저가 어떻게 동작하는지 알아보겠습니다.
MDN의 How browsers work 문서에 따르면 브라우저의 렌더링 단계를 다음과 같이 설명합니다.

⚡️ 핵심 렌더링 단계

  1. 파싱 (Parsing)
    • HTML → DOM 트리 변환 (HTMLParser)
    • CSS → CSSOM 트리 변환 (StyleEngine 처리)
  2. 렌더 트리 생성
    • DOM + CSSOM 결합 → 화면에 표시될 요소만 선택
    • display: none 요소는 제외, visibility: hidden은 포함
  3. 레이아웃 (Reflow)
    • 뷰포트 크기 기반으로 픽셀 단위 위치 계산
    • 상대 단위(%, rem) → 절대 픽셀 값으로 변환
  4. 페인트 (Paint)
    • 그리기 명령(PaintRecord) 생성
    • 레이어 분할: 3D transform, opacity 등의 속성은 별도 레이어로 렌더링
  5. 합성 (Compositing)
    • GPU 가속으로 레이어 병합 (컴포지터 스레드 담당)
    • 스크롤, 애니메이션은 리페인트 없이 처리 가능

브라우저는 DOM/CSSOM → 렌더 트리 → 레이아웃 → 페인트 → 합성 과정을 거칩니다.

🌐 Chromium은 무엇인가?

Chromium은 Google이 주도하는 오픈 소스 웹 브라우저 프로젝트입니다. 우리가 흔히 사용하는 Google Chrome 브라우저는 바로 이 Chromium 프로젝트의 소스 코드를 기반으로 만들어졌습니다. (Chrome 과 Chromium은 같은게 아닙니다!)

주요 특징은 다음과 같습니다:

  1. 핵심 엔진 제공 (Blink, V8)
  2. Chrome과의 차이 (독점 기능, 코덱 등)
    • Chrome vs Chromium 비교: 자동 업데이트, 미디어 코덱(MP3, H.264, AAC) 및 Flash 지원(과거), 오류 보고 등 Chrome에 추가된 기능과 Chromium과의 차이를 설명합니다.
    • Chrome vs Chromium 주요 차이점: Chrome이 Chromium 기반에 자동 업데이트, Google 동기화, 미디어 코덱 등 독점 코드를 추가했다고 설명합니다.
    • Google Chrome과의 차이: Chrome은 독점 라이선스를 가지며 MP3, H.264, AAC 코덱 및 Adobe Flash(과거)를 지원하지만 Chromium은 그렇지 않다고 설명합니다.
  3. 빠른 개발 주기 (기능 실험 및 테스트)
    • Chromium 공식 문서 - Chrome 릴리스 주기: 현재 Chrome이 4주마다 새로운 메이저 버전을 안정 채널(Stable Channel)에 출시하는 빠른 주기를 설명합니다. 새로운 기능은 메인 브랜치에서 개발되고 테스트 단계를 거쳐 배포됩니다.
    • Chromium 공식 문서 - 기능 출시 프로세스: 새로운 기능이 Chromium 내에서 프로토타입으로 시작하여 플래그(flag) 뒤에서 개발되고, 개발자 테스트(Dev Trials), 오리진 트라이얼(Origin Trial) 등을 거쳐 최종적으로 출시되는 과정을 설명합니다. 이는 Chrome 안정 버전에 포함되기 전에 Chromium에서 먼저 구현되고 테스트됨을 보여줍니다.

🏰 Chromium 아키텍처 탐구: 탭 하나가 멈춰도 전체 브라우저는 괜찮은 이유

참고 문서 https://www.chromium.org/developers/design-documents/multi-process-architecture/

혹시 웹 서핑 중 특정 웹 페이지 하나 때문에 브라우저 전체가 멈추거나 꺼져버리는 답답한 경험을 해보신 적 있나요? 2000년대 중반의 웹 브라우저들은 종종 이런 문제를 겪곤 했습니다. 마치 오래된 싱글태스킹 운영체제에서 응용 프로그램 하나가 시스템 전체를 마비시키는 것처럼, 웹 페이지나 플러그인 하나가 브라우저 전체를 멈추게 만들 수 있었습니다.

하지만 오늘날 우리가 사용하는 Chrome과 같은 최신 브라우저들은 훨씬 안정적입니다. 그 비결은 바로 Chromium의 멀티 프로세스 아키텍처(Multi-Process Architecture) 에 있습니다. Chromium은 이 아키텍처를 통해 마치 현대 운영체제가 여러 응용 프로그램을 독립된 프로세스로 분리하여 안정성과 보안을 확보하는 것과 같은 이점을 웹 브라우징 환경에 가져왔습니다.

핵심 아이디어: 분리하고 보호

Chromium은 브라우저의 기능을 여러 개의 독립적인 프로세스(Process) 로 나눕니다.

  1. 브라우저 프로세스 (Browser Process):
    • 브라우저의 '두뇌' 역할을 합니다.
    • 사용자 인터페이스(UI)를 담당하고, 다른 모든 프로세스(렌더러, GPU 등)를 관리합니다.
    • 각 렌더러 프로세스와 통신하며 상태를 관리하는 RenderProcessHost 객체를 가집니다.
  2. 렌더러 프로세스 (Renderer Process):
    • 실제 웹 페이지를 화면에 그리는(렌더링) 작업을 담당합니다. 각 탭이나 프레임은 일반적으로 별도의 렌더러 프로세스에서 실행됩니다. (물론, 특정 조건 하에서는 프로세스를 공유하기도 합니다.)
    • HTML 파싱과 레이아웃을 위해 Blink 렌더링 엔진을 사용합니다.
      각 렌더러 프로세스는 부모인 브라우저 프로세스와 통신하고 전역 상태를 관리하는 RenderProcess 객체를 가집니다.
    • 각 문서(프레임)는 RenderFrame 객체에 해당하며, 이는 브라우저 프로세스의 RenderFrameHost와 통신합니다.

멀티 프로세스 아키텍처의 장점

이렇게 프로세스를 분리함으로써 Chromium은 여러 가지 중요한 이점을 얻습니다.

  1. 안정성 (Stability): 만약 하나의 탭(렌더러 프로세스)에서 오류가 발생하거나 멈추더라도, 해당 탭만 영향을 받고 브라우저 전체가 다운되지 않습니다. 문제가 생긴 탭에는 "앗, 이런!" 화면이 표시되고, 사용자는 해당 탭만 새로고침하여 복구할 수 있습니다.
  2. 보안 (Security): 각 렌더러 프로세스는 샌드박스(Sandbox) 라는 제한된 환경에서 실행됩니다. 이는 렌더러 프로세스가 사용자의 파일 시스템, 네트워크, 입력 장치 등에 직접 접근하는 것을 막아줍니다. 만약 악의적인 웹사이트가 렌더러 프로세스를 장악하더라도, 샌드박스 덕분에 시스템 전체에 미치는 피해를 크게 줄일 수 있습니다.
  3. 자원 관리 (Resource Management): 사용자가 보지 않는 숨겨진 탭이나 백그라운드 탭(렌더러 프로세스)의 우선순위를 낮출 수 있습니다. 시스템 메모리가 부족할 경우, 운영체제는 이런 우선순위가 낮은 프로세스의 메모리를 먼저 디스크로 옮깁니다(스왑 아웃). 이를 통해 사용자가 현재 보고 있는 활성 탭이 더 빠르고 부드럽게 동작하도록 돕습니다. 메모리가 충분할 때는 이 과정이 눈에 띄지 않으므로 성능 저하 없이 효율적인 메모리 관리가 가능합니다.

👩🏽‍🎤 Blink 는 어떻게 작동하는가

How Blink works 문서에서는 Blink의 작동 방식에 대해서 다음과 같이 설명합니다. 자세한 설명은 문서를 참고바랍니다.

Blink의 역할

Blink는 웹 브라우저 탭 안에서 웹 콘텐츠를 렌더링하는 핵심 엔진입니다. 주요 역할은 다음과 같습니다.

  • 웹 표준 구현: HTML, CSS, Web IDL 등 웹 플랫폼의 다양한 기술 표준을 해석하고 처리합니다. (e.g. HTML standard)
  • JavaScript 실행: V8 JavaScript 엔진을 내장하여 웹 페이지의 동적인 기능을 수행합니다.
  • 리소스 요청: 웹 페이지에 필요한 이미지, 스타일 시트 등의 자원을 네트워크를 통해 가져옵니다.
  • DOM 트리 구축: 다운로드한 HTML 코드를 바탕으로 웹 페이지의 구조를 나타내는 DOM (Document Object Model) 트리를 만듭니다.
  • 스타일 및 레이아웃 계산: CSS를 해석하여 각 요소의 시각적인 스타일을 결정하고, DOM 트리를 기반으로 화면에 어떻게 배치할지 계산합니다.
  • 그래픽 렌더링: 계산된 스타일과 레이아웃 정보를 바탕으로 실제 화면에 콘텐츠를 그립니다 (Chrome Compositor 활용).

Blink는 웹 페이지의 코드를 해석하고 시각적으로 표현하여 사용자가 웹 콘텐츠를 볼 수 있도록 하는 핵심적인 렌더링 기능을 제공하는 엔진입니다. Chromium, Opera, Android WebView와 같은 다양한 웹 브라우저 환경에서 content public APIs를 통해 사용됩니다.

Blink와 프로세스 구조

Chromium은 여러 개의 프로세스를 사용하는 구조입니다. 크게 하나의 브라우저 프로세스와 여러 개의 샌드박스 처리된 렌더러 프로세스로 나뉩니다. Blink는 바로 이 렌더러 프로세스 안에서 동작합니다.

렌더러 프로세스는 왜 이렇게 많을까요?

가장 큰 이유는 보안 때문입니다. 서로 다른 웹사이트의 정보가 담긴 메모리 공간을 분리하는 것이 중요합니다. 이를 사이트 격리(Site Isolation)라고 부릅니다. 이상적으로는 각 렌더러 프로세스가 하나의 웹사이트만을 담당해야 합니다.

하지만 현실은 조금 다릅니다. 사용자가 너무 많은 탭을 열거나 기기의 메모리가 부족할 때는 하나의 렌더러 프로세스가 여러 개의 다른 웹사이트 (iframe이나 탭)를 함께 처리하기도 합니다. 따라서 렌더러 프로세스, iframe, 탭 사이에는 1:1 관계가 없습니다.

샌드박스 안에서 Blink는 뭘 할 수 있을까요?

렌더러 프로세스는 샌드박스라는 제한된 환경에서 실행되기 때문에, 시스템 자원(파일 접근, 오디오 재생 등)에 직접 접근하거나 사용자 정보(쿠키, 비밀번호 등)를 함부로 사용할 수 없습니다. Blink가 이러한 작업을 수행하려면 브라우저 프로세스에 요청해야 합니다.

브라우저 프로세스와 렌더러 프로세스는 어떻게 소통할까요?

이 둘 사이의 통신은 Mojo라는 기술을 통해 이루어집니다. 과거에는 Chromium IPC라는 방식을 사용했지만, 현재는 Mojo로 대체되고 있습니다. Chromium 내부적으로는 브라우저 프로세스를 여러 개의 "서비스"로 나누는 작업(Servicification)이 진행 중이며, Blink 입장에서는 Mojo를 통해 이러한 서비스들과 편리하게 상호작용할 수 있습니다.

렌더러 프로세스 내의 스레드 구조

하나의 렌더러 프로세스 안에는 다음과 같은 종류의 스레드가 존재합니다.

  • 메인 스레드 (Main Thread): Blink에서 가장 중요한 작업들이 대부분 이 스레드에서 처리됩니다. JavaScript 실행 (Worker 제외), DOM 조작, CSS 처리, 스타일 계산, 레이아웃 계산 등이 모두 메인 스레드에서 이루어집니다. Blink는 이 메인 스레드의 성능을 최대한으로 끌어올리도록 매우 잘 최적화되어 있습니다. (대부분의 작업이 단일 스레드에서 처리된다고 가정합니다.)
  • 워커 스레드 (Worker Threads, N개): 웹 워커(Web Workers), 서비스 워커(ServiceWorker), 워크릿(Worklets)과 같은 별도의 작업을 병렬로 처리하기 위해 Blink가 필요에 따라 여러 개의 워커 스레드를 생성할 수 있습니다.
  • 내부 스레드 (Internal Threads, 몇 개): Blink와 V8 엔진 내부적으로 특정 작업을 처리하기 위해 사용되는 스레드들입니다. 예를 들어, 웹 오디오 처리, 데이터베이스 작업, 가비지 컬렉션(GC) 등이 이러한 내부 스레드에서 실행될 수 있습니다.

스레드 간 통신 방식:

서로 다른 스레드끼리 정보를 주고받기 위해서는 메시지 전달 방식을 사용해야 합니다. PostTask API를 통해 작업을 특정 스레드의 작업 큐에 추가하는 방식으로 통신합니다. 공유 메모리 방식은 성능상의 특별한 이유가 있는 극히 일부 경우를 제외하고는 권장되지 않습니다. 따라서 Blink 코드베이스에서 MutexLock과 같은 동기화 메커니즘을 많이 찾아볼 수 없는 이유이기도 합니다.

렌더링 파이프라인

그래서 어떻게 렌더링 하는가에 대한 것이 웹 프론트엔드 개발자에게 중요할 것입니다. 렌더링 각 단계에 대한 자세한 설명은 이 문서를 참고하세요.

전체적인 렌더링 흐름은 다음과 같습니다:

조금 더 자세한 다이어그램:

👾 Chromium 에 대해 알아보며...

처음에는 단순히 "브라우저가 어떻게 화면을 그리는지"에 대한 호기심으로 시작했던 여정이었습니다. 렌더링 과정의 각 단계를 하나씩 따라가다 보니, 그 뒤에 숨겨진 Chromium의 거대한 아키텍처와 혁신적인 아이디어들을 마주하게 되었습니다.

Chromium에 대해 더 알아본 뒤에 Firefox와 최근에 개발이 시작된 ladybird 프로젝트 등도 살펴봐야 겠습니다.

profile
언젠가 보게 된다. 기록하자 😡🔥🔥

0개의 댓글