브라우저 렌더링

김진효·2026년 4월 22일

[CS] FE

목록 보기
1/5
post-thumbnail

웹 페이지 로드 전체 프로세스

웹 페이지 로드
웹 페이지 로딩은 크게 네트워크 영역브라우저 영역으로 나뉜다

  • Network: 주소 입력 ➔ DNS 탐색 ➔ TCP 연결 ➔ HTTP 요청/응답
  • Browser: 응답받은 리소스를 바탕으로 화면을 구성하는 CRP 수행

브라우저 렌더링 원리

브라우저가 렌더링 할때 CRP(Critical Rendering Path)라는 핵심 과정을 거친다
→ 브라우저가 HTML, CSS, Javascipt를 화면에 픽셀로 변화하는 일련의 과정!

CRP

  1. HTML Parser
    HTML를 파싱 후 DOM트리를 구축

  2. CSS Parser
    CSS를 파싱 후 CSSOM트리를 구축

  3. JavaScript
    JS 엔진이 코드를 파싱하여 AST를 만들고 실행

    • HTML 중간에 스크립트를 만나면 기본적으로 HTML 파싱이 중단
      async, defer 로 비동기 제어 가능
      HTML 파싱과 스크립트 다운로드가 동시에 진행
    • JS에서 CSS가 필요한 경우가 있다면 CSSOM이 완성될 때까지 실행이 지연될 수 있음
  4. Render Tree
    DOM과 CSSOM을 결합하여 실제로 화면에 표시될 요소들로만 구성된 트리 구조 생성

    • display: none 속성과 같이 화면에서 보이지도 않고 공간을 차지하지 않는 것은 렌더트리로 구축되지 않음
    • visibility : hidden 의 경우에는 보이지는 않을 뿐 공간은 실제 차지하고 있기 때문에 렌더트리로 구축
  5. Layout
    뷰포트(Viewport) 기반으로 렌더트리의 각 노드가 가지는 정확한 위치와 크기를 계산

  6. Paint
    계산한 위치/크기를 기반으로 화면에 그림
    각 노드를 화면의 실제 픽셀로 변환하는 과정

  7. Composite
    Paint 단계에서 생성된 여러 개의 레이어(Layer)를 GPU가 하나로 합성하여 최종 화면 완성


UI 변경 비용

Reflow > Repaint > Composite 순으로 비용 과중

  • Reflow (Layout)
    전체 레이아웃을 다시 계산
    요소의 크기나 위치가 바뀔 때 발생
  • Repaint (Paint)
    다시 화면에 그리는 과정
    색상, 그림자 등 위치와 상관 없는 스타일이 바뀔 때 발생
  • Composite
    레이어 재배치
    transform, opacity 등 변경될 때 발생

불필요한 Reflow와 Repaint의 반복렌더링 성능 저하의 원인


Reflow와 Repaint 최소화

  1. DOM 조작 최소화

    • DOM 요소 삽입 및 수정 최소화

      ❌ 안좋은 예시
      DOM을 반복적으로 갱신하면서 Reflow/Repaint가 계속 발생

      <script>
         const $ul = document.getElementById('ul');
         for (let i = 0; i < 3000; i++) {
           $ul.innerHTML += `<li>${i}</li>`; // 매 반복마다 DOM 갱신
         }
      </script>

      ⭕️ 좋은 예시
      변경사항을 모아서 한 번만 DOM에 반영

      <script>
        let list = "";
        for (let i = 0; i < 3000; i++) {
          list += `<li>${i}</li>`;
        }
        $ul.innerHTML = list; // 단 한 번만 DOM 갱신
      </script>
    • 개별 스타일 변경 대신 일괄 적용
      여러 스타일을 각각 수정하면 그만큼 렌더링 비용 증가
      cssText등을 활용하여 내부적으로 여러 스타일 속성을 한 번에 파싱
      다만, 현대 브라우저(Chrome 등)는 스타일 변경을 즉시 반영하지 않고 비동기 배치(batch) 처리

      ❌ 안좋은 예시 (개별 수정)

      <script>
        el.style.width = "100px";
        el.style.height = "100px";
        el.style.backgroundColor = "red";
      </script>

      ⭕️ 좋은 예시 (cssText 활용)

      <script>
      	el.style.cssText = "width: 100px; height: 100px; background-color: red;"
      </script>
  2. DOM 접근 최소화 DocumentFragment를 활용

    <script>
      const fragment = document.createDocumentFragment();
        for (let i = 0; i < 3000; i++) {
           const li = document.createElement('li');
           li.textContent = i;
           fragment.appendChild(li);
         }
       $ul.appendChild(fragment); // 단 한 번만 DOM 접근
    </script>

개념 정리

  • DNS
    사람이 읽을 수 있는 도메인 이름(예: www.amazon.com)을 머신이 읽을 수 있는 IP 주소(예: 192.0.2.44)로 변환해주는 역할

  • TCP 3-way Handshake
    통신을 위한 연결 설정
    TCP 3-way Handshake

    SYN (Synchronize): 연결 시작 및 동기화 요청 (Client → Server)
    SYN-ACK (Synchronize-Acknowledgment): 서버의 요청 수락 및 확인 응답 (Server → Client)
    ACK (Acknowledgment): 서버의 응답을 확인했음을 알리는 최종 응답 (Client → Server)

    HTTP/3 에서는 QUIC 통합 Handshake 사용

  • DOM (Document Object Model)
    DOM

    웹 페이지를 이루는 요소들을 브라우저가 트리 구조로 만든 객체 모델
    웹 페이지(Document)를 구조화된 객체로 제공하여 프로그래밍 언어가 페이지 구조에 접근할 수 있는 방법을 제공

  • CSSOM (CSS Object Model)
    CSSOM

    DOM처럼 CSS 내용을 파싱하고 노드를 만들어 구조화된 트리 구조로 만든 것
    '씨에스오엠' 또는 '썸' 이라고 부르는 것 같다

  • AST(Abstract Syntax Tree)
    추상 구문 트리
    프로그래밍 언어의 소스 코드를 트리 구조로 만든 자료 구조
    JS

  • DocumentFragment
    DOM 트리에는 존재하지 않고 메모리상에서만 존재하는 DOM 노드
    실제 DOM에 넣기 전에 모든 요소를 잠시 담아두는 가상의 컨테이너 느낌

    DOM에 반영되기 전까지는 DOM 트리가 아닌 메모리상에서만 존재하기 때문에 구조에 변경이 일어나도 브라우저가 다시 화면을 렌더링하지 않음

    (추가) createElement 에 모아서 하는 것과 무슨 차이일까? 감싸는 게 있느냐 없느냐 차이인 듯 하다 성능은 별 차이 없음

    createElement('div') 사용 시:
    마지막에 DOM에 붙일 때, 내가 담은 내용물뿐만 아니라 나를 감싸고 있는 div까지 통째로 DOM에 들어감

    DocumentFragment 사용 시:
    '투명한 봉투' 같은 느낌 DOM에 붙이는 순간 div는 사라지고 안에 든 내용물만 들어간다



참고

브라우저의 렌더링 원리
CRP 최적화 방안
웹 사이트 로딩 & 렌더링 과정 이해하기
[JS] script의 async와 defer 속성
DocumentFragment

0개의 댓글