브라우저 렌더링 원리: HTML/CSS가 화면에 그려지는 CRP(Critical Rendering Path) 분석

Picture of Ethan Blake
Ethan Blake

미국 실리콘밸리에서 작은 스타트업을 운영하고 있습니다. 주로 서버, 네트워크와 IT 관련된 스마트기기 사용법을 서술합니다.

Table of Contents

우리가 매일 사용하는 웹사이트는 어떻게 눈앞의 화면에 나타날까요? HTML과 CSS 코드가 단순히 브라우저에 표시되는 것이 아니라, 복잡한 과정을 거쳐 시각적인 페이지로 변환됩니다. 이 과정을 이해하는 것은 단순히 개발자만의 영역이 아닙니다. 웹사이트의 속도가 왜 느려지는지, 특정 애니메이션이 왜 부자연스러운지 등 웹 경험 전반에 걸쳐 중요한 통찰력을 제공해 주기 때문입니다.

이번 글에서는 ‘브라우저 렌더링 원리’ 중 핵심이라고 할 수 있는 CRP (Critical Rendering Path)에 대해 심층적으로 다루고, 이 원리를 실생활과 개발에 어떻게 적용하여 더 빠르고 효율적인 웹 환경을 만들 수 있을지 알아보겠습니다.

브라우저 렌더링 원리 이해의 중요성

브라우저 렌더링 원리를 이해하는 것은 웹을 사용하는 모든 사람에게 유익합니다. 특히 웹 개발자에게는 성능 최적화와 사용자 경험 향상을 위한 필수 지식이며, 일반 사용자에게도 웹사이트의 동작 원리를 파악하고 더 나은 웹 환경을 선택하는 데 도움을 줍니다.

  • 사용자 경험 향상 웹 페이지 로딩 속도는 사용자의 만족도와 직결됩니다. CRP를 이해하면 로딩 속도를 저해하는 요소를 파악하고 개선하여 사용자에게 더 빠르고 쾌적한 경험을 제공할 수 있습니다.
  • 검색 엔진 최적화 SEO 구글과 같은 검색 엔진은 페이지 로딩 속도를 중요한 랭킹 요소로 고려합니다. CRP 최적화는 SEO 점수를 높이는 데 기여하여 더 많은 트래픽을 유도할 수 있습니다.
  • 성능 병목 현상 진단 웹 페이지가 느려지는 원인을 정확히 진단하고 해결책을 모색하는 데 CRP 지식이 필수적입니다. 어떤 단계에서 시간이 오래 걸리는지 알면 효율적인 개선이 가능합니다.
  • 자원 효율적인 웹 개발 불필요한 연산을 줄이고 자원을 효율적으로 사용하여 서버 부하를 줄이고 친환경적인 웹 서비스를 구축하는 데 기여할 수 있습니다.

CRP 핵심 5단계 깊이 들여다보기

CRP는 브라우저가 HTML, CSS, JavaScript와 같은 웹 리소스를 다운로드하고 처리하여 최종적으로 화면에 픽셀을 그리는 일련의 과정을 말합니다. 이 과정은 크게 5단계로 나눌 수 있습니다.

1. DOM과 CSSOM 트리 구축

브라우저가 웹 페이지를 렌더링하기 위한 첫 단계는 HTML과 CSS 파일을 분석하여 각각의 객체 모델 트리를 만드는 것입니다.

  • DOM Document Object Model 트리 구축
    • 브라우저는 서버로부터 HTML 파일을 받으면 이를 한 줄씩 읽으며 분석합니다. 이 과정을 ‘파싱’이라고 합니다.
    • 파싱 과정에서 HTML 태그들은 노드(Node)로 변환되고, 이 노드들이 부모 자식 관계를 가지며 계층적인 트리 구조를 형성합니다. 이것이 바로 DOM입니다.
    • DOM은 웹 페이지의 내용과 구조를 나타내며, JavaScript를 통해 접근하고 조작할 수 있습니다.
    • HTML 파싱은 CSS나 JavaScript 로딩에 의해 중단될 수 있습니다. 특히 <script> 태그는 일반적으로 HTML 파싱을 멈추고 스크립트 실행이 완료될 때까지 기다립니다.
  • CSSOM CSS Object Model 트리 구축
    • HTML 파싱과 동시에 또는 그 이후에 브라우저는 <link> 태그로 연결된 CSS 파일이나 <style> 태그 내의 CSS 코드를 분석합니다.
    • CSS 코드를 분석하여 각 선택자에 해당하는 스타일 규칙을 노드로 만들고, 이 노드들을 계층적으로 연결하여 CSSOM 트리를 생성합니다.
    • CSSOM은 웹 페이지의 모든 요소에 적용될 스타일 정보를 담고 있으며, 상속 및 우선순위 규칙이 적용됩니다.
    • CSSOM은 렌더 트리 생성을 위해 필수적이므로, CSSOM 구축이 완료되기 전까지는 렌더링이 차단됩니다.

2. 렌더 트리 생성

DOM과 CSSOM 트리가 각각 완성되면, 브라우저는 이 두 트리를 결합하여 ‘렌더 트리(Render Tree)’를 만듭니다. 렌더 트리는 화면에 실제로 그려질 요소들로만 구성됩니다.

  • DOM 트리의 각 노드에 해당하는 CSSOM 트리의 스타일 정보를 적용합니다.
  • display: none 속성이 적용된 요소나 <head> 태그 내부의 요소처럼 화면에 보이지 않는 요소는 렌더 트리에 포함되지 않습니다.
  • 렌더 트리는 각 요소의 시각적인 속성(색상, 폰트, 크기 등)과 내용이 모두 결합된 형태입니다.

3. 레이아웃 리플로우 계산

렌더 트리가 생성되면, 브라우저는 각 요소가 화면의 어디에, 어떤 크기로 배치되어야 할지 정확한 위치와 크기를 계산합니다. 이 과정을 ‘레이아웃’ 또는 ‘리플로우(Reflow)’라고 합니다.

  • 모든 요소의 박스 모델(width, height, padding, margin, border)을 계산합니다.
  • 뷰포트(브라우저 창)의 크기, 다른 요소들과의 상대적인 위치, CSS 속성(position, float, flex, grid 등)을 고려하여 정확한 좌표를 결정합니다.
  • 이 단계는 상당히 비용이 많이 드는 작업입니다. 레이아웃 변경이 발생하면 해당 요소뿐만 아니라 주변 요소들까지 영향을 받아 전체 또는 부분적인 재계산이 필요할 수 있습니다.

4. 페인트 리페인트 과정

레이아웃 단계에서 모든 요소의 위치와 크기가 결정되면, 이제 브라우저는 이 정보를 바탕으로 픽셀을 화면에 그립니다. 이 과정을 ‘페인트’ 또는 ‘리페인트(Repaint)’라고 합니다.

  • 각 요소의 색상, 테두리, 그림자, 텍스트, 배경 이미지 등 모든 시각적 속성을 픽셀로 변환합니다.
  • 브라우저는 효율적인 페인팅을 위해 페이지를 여러 개의 ‘레이어(Layer)’로 분리할 수 있습니다. 예를 들어, 움직이는 요소나 투명도가 있는 요소는 별도의 레이어로 분리되어 처리될 수 있습니다.
  • 리페인트는 레이아웃 변경 없이 색상이나 배경 이미지 등 시각적 속성만 변경될 때 발생합니다. 리플로우보다는 비용이 적게 들지만, 여전히 성능에 영향을 미칠 수 있습니다.

5. 합성 Composting

페인트 단계에서 생성된 여러 개의 레이어들을 최종적으로 하나로 합쳐서 화면에 표시하는 과정입니다. 이 과정을 ‘합성’ 또는 ‘컴포지팅(Compositing)’이라고 합니다.

  • 레이어들이 올바른 순서로 겹쳐지고, 3D 변환이나 투명도와 같은 효과가 적용됩니다.
  • 이 단계는 주로 GPU(그래픽 처리 장치)의 도움을 받아 처리됩니다. GPU는 병렬 처리에 강점이 있어 복잡한 그래픽 연산을 빠르게 수행할 수 있습니다.
  • 합성 단계만 발생하는 애니메이션(예: transform, opacity)은 리플로우나 리페인트를 일으키지 않으므로 매우 성능이 좋습니다.

실생활에서의 CRP 원리 활용 방법

CRP 원리를 이해하면 웹사이트의 성능을 개선하고 사용자 경험을 최적화하는 데 다양한 방식으로 활용할 수 있습니다.

  • 웹사이트 속도 개선
    • 개발자 관점 CSS 파일을 HTML <head> 태그 안에 배치하여 CSSOM 생성을 빠르게 하고, JavaScript 파일은 <body> 태그의 끝에 배치하거나 async, defer 속성을 사용하여 DOM 파싱을 방해하지 않도록 합니다. 불필요한 리소스(이미지, 폰트)를 줄이고 압축하여 다운로드 시간을 단축합니다.
    • 사용자 관점 불필요한 브라우저 확장 기능을 비활성화하고, 웹사이트에서 제공하는 ‘다크 모드’나 ‘저용량 모드’를 활용하여 렌더링 부하를 줄일 수 있습니다.
  • 모바일 웹 최적화
    • 모바일 환경에서는 데스크톱보다 네트워크 속도가 느리고 CPU, GPU 성능이 제한적입니다. CRP 원리를 활용하여 모바일 기기에 최적화된 반응형 디자인을 구현하고, 불필요한 CSS나 JavaScript를 조건부로 로드하여 초기 렌더링 시간을 단축합니다.
    • viewport 메타 태그를 올바르게 설정하여 브라우저가 모바일 기기에 맞게 렌더링하도록 지시합니다.
  • 애니메이션 성능 향상
    • CSS 애니메이션이나 JavaScript 기반 애니메이션을 구현할 때, width, height, left, top과 같이 레이아웃을 변경하는 속성 대신 transform, opacity와 같이 합성 단계에서만 처리되는 속성을 사용하는 것이 좋습니다.
    • transformopacity는 레이아웃과 페인트를 건너뛰고 합성 단계에서만 처리되어 부드러운 애니메이션을 구현할 수 있습니다.

CRP 최적화를 위한 유용한 팁과 조언

웹 페이지의 성능을 극대화하기 위한 구체적인 팁과 조언입니다.

개발자를 위한 팁

  • CSS와 JavaScript 위치 최적화
    • CSS는 <head> 태그 안에 두어 CSSOM 생성을 최대한 빨리 시작합니다.
    • JavaScript는 <body> 태그 닫는 부분 바로 위에 두거나, async 또는 defer 속성을 사용하여 HTML 파싱을 방해하지 않도록 합니다.
  • 불필요한 리플로우 리페인트 줄이기
    • JavaScript로 DOM을 조작할 때, 한 번에 여러 스타일을 변경하기보다는 클래스를 토글하는 방식으로 변경 횟수를 줄입니다.
    • document.createDocumentFragment()를 사용하여 여러 DOM 요소를 한꺼번에 추가하거나, DOM 변경을 최소화하는 라이브러리(React, Vue 등)를 활용합니다.
    • 애니메이션에는 transform, opacity 속성을 주로 사용합니다.
  • CSS 선택자 효율적으로 사용
    • 복잡하거나 너무 일반적인 CSS 선택자는 브라우저가 CSSOM을 구축하고 스타일을 적용하는 데 더 많은 시간을 소요하게 합니다.
    • 클래스나 ID 선택자를 우선적으로 사용하고, 깊은 계층 구조의 선택자를 피하여 스타일 계산 비용을 줄입니다.
  • 웹폰트 최적화
    • 웹폰트는 다운로드 시간이 길어지면 FOIT (Flash of Invisible Text)나 FOUT (Flash of Unstyled Text)를 유발할 수 있습니다.
    • font-display: swap, optional 등을 사용하여 폰트 로딩 전략을 최적화하고, 필요한 폰트만 포함합니다.
  • 이미지 최적화
    • 적절한 이미지 포맷 (WebP, AVIF)과 압축률을 사용하고, 반응형 이미지를 위해 srcsetsizes 속성을 활용합니다.
    • loading="lazy" 속성을 사용하여 화면에 보이지 않는 이미지는 나중에 로드하도록 합니다.
  • will-change 속성 활용
    • 특정 요소에 애니메이션이 적용될 예정임을 브라우저에 미리 알려주어, 브라우저가 해당 요소에 대한 최적화를 미리 수행할 수 있도록 돕습니다.
    • 과도하게 사용하면 오히려 성능 저하를 유발할 수 있으므로 주의해서 사용해야 합니다.

일반 사용자를 위한 팁

  • 브라우저 확장 기능 관리
    • 너무 많은 브라우저 확장 기능은 메모리를 차지하고 웹 페이지 렌더링 프로세스에 개입하여 속도를 저하시킬 수 있습니다. 불필요한 확장 기능은 비활성화하거나 삭제합니다.
  • 캐시 활용
    • 브라우저 캐시를 주기적으로 정리하는 것은 좋지만, 자주 방문하는 사이트의 캐시는 유지하여 다음 방문 시 더 빠르게 로드되도록 합니다.
  • 네트워크 환경 개선
    • 빠른 인터넷 연결은 CRP의 첫 단계인 리소스 다운로드 시간을 단축하는 가장 기본적인 방법입니다.

흔한 오해와 사실 관계

CRP와 관련하여 흔히 오해하는 몇 가지 사실들을 바로잡아 보겠습니다.

  • 오해 CSS는 무조건 HTML보다 먼저 로드되어야 한다.
    • 사실 CSS는 렌더 트리 구축 전까지만 준비되면 됩니다. 하지만 CSSOM이 완성되지 않으면 렌더 트리를 만들 수 없고, 이는 ‘렌더링 차단(Render Blocking)’을 유발하여 페이지가 흰 화면으로 보이는 시간을 길게 만들 수 있습니다. 따라서 가능한 한 빨리 CSS를 로드하는 것이 좋습니다.
  • 오해 모든 CSS 변경은 리플로우를 일으킨다.
    • 사실 그렇지 않습니다. width, height, margin, padding 등 레이아웃에 영향을 주는 속성 변경은 리플로우를 일으키지만, color, background-color, box-shadow 등 레이아웃에 영향을 주지 않는 시각적 속성 변경은 리페인트만 일으킵니다. 리페인트는 리플로우보다 훨씬 비용이 적습니다.
  • 오해 자바스크립트는 항상 페이지 로딩을 느리게 한다.
    • 사실 자바스크립트가 DOM과 CSSOM을 변경하면 CRP 과정을 다시 트리거하여 성능에 영향을 줄 수 있습니다. 하지만 모든 자바스크립트가 느린 것은 아닙니다. 비동기 로딩(async, defer), 코드 스플리팅, 효율적인 DOM 조작 기법 등을 사용하면 성능 저하를 최소화할 수 있습니다. 오히려 사용자 인터랙션을 풍부하게 하여 전반적인 사용자 경험을 향상시키기도 합니다.
  • 오해 캐싱은 항상 웹 페이지를 빠르게 만든다.
    • 사실 캐싱은 재방문 시 페이지 로딩 속도를 크게 향상시키지만, 최초 방문 시에는 효과가 없습니다. 또한, 캐시된 내용이 오래되어 실제 콘텐츠와 다를 경우 문제가 될 수 있습니다. 적절한 캐시 전략(캐시 만료 시간, 캐시 무효화)이 중요합니다.

전문가의 조언

웹 성능 전문가들은 CRP 최적화에 대해 다음과 같은 조언을 합니다.

  • “측정 없이는 최적화도 없다. 브라우저 개발자 도구 (Chrome DevTools의 Performance, Lighthouse 등)를 사용하여 현재 웹 페이지의 CRP 각 단계에서 어떤 병목 현상이 발생하는지 정확히 파악하는 것이 가장 중요하다.”
  • “사용자 경험은 기능만큼 중요하다. 아무리 훌륭한 기능을 제공하는 웹사이트라도 로딩이 느리거나 버벅거린다면 사용자들은 떠나게 될 것이다. 초기 렌더링 시간, 상호작용까지의 시간 등을 꾸준히 모니터링해야 한다.”
  • “모바일 퍼스트 전략을 채택하라. 데스크톱 환경보다 제약이 많은 모바일 환경에 맞춰 웹 페이지를 설계하고 최적화하면, 자연스럽게 데스크톱 환경에서도 좋은 성능을 얻을 수 있다.”
  • “점진적 개선을 추구하라. 한 번에 모든 것을 완벽하게 최적화하기는 어렵다. 가장 큰 병목 현상부터 하나씩 해결해나가면서 지속적으로 개선하는 접근 방식이 효과적이다.”

자주 묻는 질문과 답변

Q1 CRP가 웹 성능에 중요한 이유는 무엇인가요

CRP는 웹 페이지가 사용자에게 보이기까지의 모든 과정을 포함합니다. 이 과정이 최적화되지 않으면 페이지 로딩 시간이 길어지고, 버벅거리는 현상이 발생하며, 이는 사용자 경험 저하, 이탈률 증가, 검색 엔진 랭킹 하락으로 이어질 수 있습니다. 즉, CRP는 웹사이트의 성공과 직결되는 핵심 요소이기 때문입니다.

Q2 리플로우와 리페인트는 어떻게 다른가요

리플로우는 레이아웃 변경을 포함하는 과정으로, 요소의 위치, 크기, 기하학적 형태가 변경될 때 발생합니다. 이 과정은 주변 요소들에게도 영향을 미치기 때문에 비용이 많이 듭니다. 반면, 리페인트는 레이아웃 변경 없이 요소의 색상, 배경, 투명도 등 시각적 속성만 변경될 때 발생합니다. 리페인트는 리플로우보다 훨씬 비용이 적지만, 여전히 성능에 영향을 미칠 수 있습니다.

Q3 자바스크립트가 CRP에 미치는 영향은 무엇인가요

자바스크립트는 DOM과 CSSOM을 동적으로 조작할 수 있습니다. 예를 들어, 새로운 요소를 추가하거나 기존 요소의 스타일을 변경하면, 브라우저는 변경된 내용에 따라 DOM 또는 CSSOM을 다시 구축하고, 이로 인해 렌더 트리 생성, 레이아웃, 페인트, 합성 과정을 다시 거쳐야 할 수 있습니다. 이러한 재계산 과정이 빈번하게 발생하거나 복잡하면 웹 페이지의 반응성이 떨어지고 느려질 수 있습니다.

Q4 FMP와 LCP는 CRP와 어떤 관계가 있나요

FMP (First Meaningful Paint)와 LCP (Largest Contentful Paint)는 웹 성능을 측정하는 중요한 지표들입니다. FMP는 사용자가 페이지의 주요 콘텐츠를 처음으로 보게 되는 시점을 나타내고, LCP는 뷰포트 내 가장 큰 콘텐츠 요소(이미지, 비디오, 텍스트 블록 등)가 렌더링되는 시점을 나타냅니다. 이 두 지표는 CRP의 페인트 단계와 밀접하게 관련되어 있으며, CRP 최적화는 FMP와 LCP 시간을 단축하여 사용자에게 더 빠른 시각적 피드백을 제공하는 데 기여합니다.

비용 효율적인 CRP 최적화 방법

고가의 솔루션 없이도 CRP를 효과적으로 최적화할 수 있는 방법들이 있습니다.

  • CDN Content Delivery Network 활용
    • CDN은 전 세계에 분산된 서버를 통해 사용자에게 가장 가까운 서버에서 콘텐츠를 전송하여 리소스 다운로드 시간을 단축시킵니다. 많은 호스팅 서비스에서 CDN을 기본으로 제공하거나 저렴한 비용으로 추가할 수 있습니다.
  • 이미지 압축 및 포맷 최적화
    • 무료 온라인 도구나 이미지 편집 소프트웨어를 사용하여 이미지 파일 크기를 줄이고, WebP나 AVIF와 같은 최신 포맷으로 변환하는 것은 리소스 다운로드 시간을 크게 단축시킬 수 있습니다. 이는 서버 비용 절감에도 기여합니다.
  • 코드 스플리팅 및 번들링
    • Webpack, Rollup과 같은 번들러를 사용하여 JavaScript 및 CSS 파일을 여러 개의 작은 파일로 나누고(코드 스플리팅), 필요한 시점에만 로드되도록 설정합니다. 이는 초기 로딩에 필요한 리소스의 양을 줄여 CRP를 최적화합니다. 대부분의 모던 프레임워크와 라이브러리는 이러한 기능을 기본적으로 제공합니다.
  • 오픈소스 라이브러리 및 도구 활용
    • Google Lighthouse, Chrome DevTools, WebPageTest와 같은 무료 성능 분석 도구를 적극적으로 활용하여 웹 페이지의 성능 병목 현상을 진단하고 개선 방안을 찾습니다.
    • lazy-loading.js와 같은 오픈소스 라이브러리를 사용하여 이미지나 비디오를 지연 로딩하여 초기 CRP 부하를 줄일 수 있습니다.
  • 브라우저 캐싱 정책 설정
    • 서버 설정(Cache-Control 헤더)을 통해 브라우저가 정적 파일을 효율적으로 캐싱하도록 지시합니다. 이는 재방문 시 리소스 다운로드 단계를 건너뛰어 CRP를 크게 단축시킵니다. 이 설정은 대부분의 웹 서버(Apache, Nginx)에서 기본적으로 제공하거나 쉽게 구성할 수 있습니다.

사용자 리뷰

아직 리뷰를 작성한 사람이 없어요. 첫번째로 리뷰를 작성 해보세요!