학습 공간 개념 · 판단 · 실험

Frontend Performance Lab

브라우저

탐색·DOM·레이아웃과 페인트

URL 탐색과 자원 로딩 이후 브라우저는 DOM·스타일·레이아웃·페인트·합성 단계를 거쳐 화면을 그립니다.

이럴 때 필요해요

네트워크 지연과 메인 스레드 렌더링 병목을 구분해 진단하고 강제 동기 레이아웃 같은 비용을 예방합니다.

어떻게 동작하나요?

사용자가 주소창에 URL을 입력하면 브라우저는 먼저 캐시나 서비스 워커에 재사용 가능한 응답이 있는지 확인하고, 필요할 때만 DNS 조회와 TCP 연결, TLS 핸드셰이크를 거쳐 서버와 HTTP 응답을 주고받습니다. 기존 연결을 재사용하거나 캐시에 적중하면 이 네트워크 단계의 일부는 생략될 수 있습니다.

응답으로 받은 HTML 바이트를 파싱해 문서 구조인 DOM 트리를 만들고, CSS를 파싱해 스타일 규칙인 CSSOM을 만든 뒤 둘을 합쳐 화면에 그릴 대상을 추려냅니다. 이어서 각 요소의 크기와 좌표를 계산하는 레이아웃(Layout/Reflow), 실제 색상과 외형을 칠하는 페인트(Paint/Repaint), 그리고 나뉜 레이어를 합치는 합성(Composite) 단계를 거쳐 모니터에 화면이 표시됩니다.

이때 요소의 너비나 위치를 바꾸면 주변 배치까지 다시 계산하는 리플로우와 리페인트가 함께 일어나지만, 단순 배경색 변경은 레이아웃을 건너뛰고 리페인트만 일어납니다. 특히 JavaScript에서 스타일을 바꾼 직후 getBoundingClientRect()나 offsetHeight처럼 기하 정보를 읽는 코드를 반복하면 브라우저가 즉시 레이아웃을 다시 계산하느라 화면이 버벅일 수 있으므로, 읽기 작업과 쓰기 작업을 분리하고 Performance 트레이스로 실제 비용을 확인합니다.

코드 예제

동작을 설명하는 읽기 전용 예제입니다.

example.js
// 설명용: 먼저 읽고, 이후 쓰기를 모은다.
const widths = elements.map(el => el.getBoundingClientRect().width);
elements.forEach((el, i) => { el.style.width = `${widths[i] + 10}px`; });
javascript · 읽기 전용3줄

여러 요소의 크기를 조정할 때 먼저 길이를 모두 읽은(Read) 뒤 스타일 변경(Write)을 한꺼번에 모아 적용해 불필요한 레이아웃 재계산 반복을 줄이는 패턴입니다.

자주 헷갈리는 포인트

  • 페이지 이동 때마다 언제나 DNS 조회와 TLS 협상이 매번 새로 발생한다고 단정하지 않습니다.
  • React 컴포넌트가 UI 객체를 계산하는 렌더 시간과 브라우저가 실제로 픽셀을 배치·칠하는 레이아웃·페인트 시간을 같은 작업으로 섞어 설명하지 않습니다.

내 말로 설명해 보기

요소의 배경색만 바꾸는 작업과 요소의 너비(width)를 바꾸는 작업은 브라우저 렌더링 파이프라인에서 왜 비용 차이가 날 수 있나요?

함께 읽으면 좋은 개념

관련 면접 질문 5개

브라우저는 HTML을 어떤 단계로 화면에 그리나요?

브라우저는 서버에서 받은 HTML을 파싱해 DOM 트리를 만들고, CSS를 파싱해 CSSOM을 만든 뒤 둘을 결합해 화면에 표시될 노드의 스타일(Render Tree)을 계산합니다. 이어서 각 요소의 정확한 크기와 위치(기하 정보)를 계산하는 레이아웃(Layout)을 수행하고, 픽셀을 칠하는 페인트(Paint)와 여러 레이어를 합치는 합성(Composite) 단계를 거쳐 화면을 출력합니다. 이때 모든 단계가 매번 전체 문서에 대해 한 번만 끝나는 것이 아니라, 이미지·폰트 로딩이나 JavaScript의 DOM·스타일 조작에 따라 필요한 범위에서 부분적으로 다시 실행됩니다.

꼬리질문과 참고자료 →

브라우저의 주요 구성 요소와 역할은 어떻게 연결되나요?

브라우저는 주소창과 탭 같은 사용자 인터페이스, 네트워크 요청 계층, HTML·CSS를 해석해 그리는 렌더링 엔진, JavaScript 엔진, 그리고 쿠키·웹 스토리지 같은 데이터 저장소와 보안 샌드박스가 유기적으로 연결된 실행 환경입니다. 사용자가 이동을 요청하면 네트워크 계층과 캐시·서비스 워커가 자원을 가져오고, 렌더러 프로세스의 메인 스레드가 파싱·스크립트 실행·렌더링 파이프라인을 조율합니다. 따라서 메인 스레드에서 무거운 JavaScript 연산이 길어지면 사용자 입력 처리와 화면 갱신까지 함께 지연될 수 있습니다.

꼬리질문과 참고자료 →

DOM과 BOM은 각각 어떤 대상을 다루나요?

DOM(Document Object Model)은 HTML이나 XML 문서의 요소·속성·텍스트를 트리 구조의 노드 객체로 모델링해 JavaScript가 문서 내용을 읽고 수정하거나 이벤트를 다룰 수 있게 해 주는 표준 인터페이스입니다. 반면 BOM(Browser Object Model)은 문서 자체를 넘어 window, location, history, navigator, screen처럼 브라우저 창과 실행 환경을 제어하는 객체들을 묶어 부르는 관용적인 명칭입니다. 따라서 문서 내부 요소를 바꿀 때는 DOM API(document.*)를 쓰고, URL 이동이나 화면 크기·브라우저 환경 정보를 다룰 때는 BOM API를 쓰며, Node.js 기반의 서버 렌더링(SSR) 시점에는 둘 다 브라우저처럼 존재하지 않는다는 점을 구분해야 합니다.

꼬리질문과 참고자료 →
나머지 질문 2개

공식 참고 자료

← 브라우저