브라우저가 우리에게 보여지기까지

최호빈·2024년 8월 19일
0
post-thumbnail

우리는 주로 html, css, js를 사용하여 웹페이지를 만들기 위한 코드를 작성한다.
웹 브라우저에서는 이 코드(Ex) 8비트 데이터 형태인 html 파일)를 가지고 웹페이지를 그려준다.


🛞 웹 브라우저의 구조

렌더링 과정에 대해서 알아보기 전에, 웹 브라우저의 구조에 대해서 알아보자.

여러 웹 브라우저가 존재하지만, 공통적인 구조는 아래와 같다.

User Interface

웹 페이지를 제외하고, 사용자와 상호작용하는 사용자 인터페이스

Rendering Engine

HTML과 CSS를 파싱하여 요청한 웹 페이지를 표시하는 렌더링 엔진

+) 모든 브라우저에는 고유한 렌더링 엔진이 있다.

  • Google Chrome 및 Opera v.15+: Blink
  • 인터넷 익스플로러: 트라이던트
  • 모질라 파이어폭스: 게코
  • iOS 및 Safari용 Chrome: WebKit

Browser Engine

User InterfaceRendering Engine을 연결하는 브라우저 엔진

사용자 인터페이스에서 수신한 입력에 따라 렌더링 엔진을 쿼리하고 처리한다.

Networking

각종 네트워크 요청을 수행하는 네트워킹 파트

HTTP 또는 FTP와 같은 표준 프로토콜을 사용하여 네트워크 호출을 관리한다.

UI Backend

체크박스나 버튼과 같은 기본적인 위젯을 그려주는 UI 백엔드 파트

기본 운영 체제의 사용자 인터페이스 방법을 사용한다.

Javascript Interpreter

자바스크립트 코드를 구문 분석하고 실행하는 인터프리터 (Ex) Chrome-V8)

해석된 결과가 생성되면 사용자 인터페이스에 표시하기 위해 렌더링 엔진으로 전달된다.

Data Persistence

보조 기억장치에 데이터를 저장하는 파트(Ex) LocalStorage, Cookie)

브라우저는 WebSQL, IndexedDB, FileSystem 등과 같은 데이터 저장 메커니즘과 호환되어야 한다.



🛠️ 렌더링 엔진의 동작 과정

렌더링 엔진은 웹페이지에 포함된 모든 요소들을 화면에 보여준다. 또한, 업데이트가 필요할때(Ex) 체크박스 클릭) 효율적으로 렌더링을 할 수 있도록 자료구조를 생성한다.

+) 이 과정에서 가공되어지는 하나의 단위는 node(노드)인데, 이 노드는 바이트 형태의 html ➡️ 문자 ➡️ 토큰 ➡️ 노드를 거쳐서 만들어진다. 이 노드를 통해 아래에서 설명할 DOM or CSSOM을 생성하는 것이다.

Critical Rendering Path라고도 불리는 동작 과정은 크게 5가지로 나눌 수 있다.

  1. HTML & CSS 파싱 후 각각의 Tree 생성

    이 트리 구조 때문에 부모의 속성이 자식에게 전파되는 것이다!

    • HTML 파싱: 브라우저가 HTML을 파싱하여 DOM(Document Object Model) Tree를 생성한다.
      <html>
        <body>
          <h1>안녕하세요</h1>
          <p>이것은 예시입니다.</p>
        </body>
      </html>
      ⬇️
      html
        └── body
            ├── h1
            │   └── "안녕하세요"
            └── p
                └── "이것은 예시입니다."
    • CSS 파싱: CSS를 파싱하여 CSSOM(CSS Object Model) Tree를 생성한다.
      body { font-family: Arial; }
      h1 { color: blue; }
      p { margin: 10px; }
      ⬇️
      body
        ├── font-family: Arial
        ├── h1
        │   └── color: blue
        └── p
            └── margin: 10px
  2. Render Tree 생성

    • DOM과 CSSOM을 결합하여 Render Tree를 생성한다. 이는 화면에 표시될 요소들(모든 노드의 컨텐츠, 스타일 정보)만 포함한다.
      // 브라우저마다 다를 수 있음
      body (font-family: Arial)
        ├── h1 (color: blue)
        │   └── "안녕하세요"
        └── p (margin: 10px)
            └── "이것은 예시입니다."
    • Render Tree가 만들어지는 과정 Document 객체에서 각 노드를 순회하면서 각각의 스타일을 CSSOM에서 찾아 보여질 요소를 Render Tree에 포함시킨다. 이때, meta 태그나 display 속성이 none이면 Render Tree에 포함하지 않는다.
  1. Render Tree 배치(Layout)

    렌더 트리가 생성될 때 위치 또는 크기 값은 할당되지 않는다. 따라서, 이 단계에서 각 요소의 크기와 위치를 계산하고 모든 노드에 정확한 좌표가 할당되어 모든 노드가 화면에서 정확한 위치에 나타날 수 있게 된다.

    이때, CSS에서 %나 em 같은 상대적인 단위를 사용했을 경우, 기기에 맞춰서 pixel 단위로 변환하게 된다.

  1. Render Tree 그리기(Paint)

    실제 화면에 픽셀을 그리는 과정이다. 렌더 트리를 탐색하고 렌더러의 paint() 메서드를 호출하여 UI 백엔드 계층을 사용하여 화면의 각 노드를 그린다.

    모든 브라우저는 고유한 렌더링 엔진을 가지고 있다. 따라서 자연스럽게 모든 브라우저는 사용자 화면에서 웹 페이지를 해석하는 고유한 방식을 가지고 있으므로 웹사이트의 크로스 브라우저 호환성도 고려를 해야 한다는 것을 잊지말자. 🤓

  2. 레이어 합성(Composite)

    레이어를 합성하여 실제 화면에 나타낸다.



🤔 UI가 업데이트 된다면?

어떤 상황인지에 따라서 특정 단계부터 다시 시작하게 된다.

1️⃣ Layout부터 다시 발생하는 경우(reflow)

  • 주로 요소의 크기나 위치가 바뀔 때 혹은 브라우저 창의 크기가 바뀌었을 때
    • DOM 요소 추가/제거
    • 요소의 크기 변경 (width, height)
    • 요소의 위치 변경 (top, left, margin, padding)
    • 폰트 크기 변경
    • 화면 크기 변경 (브라우저 창 크기 조절)
    • 코드 예시
      document.getElementById('myDiv').style.width = '200px';
      이 경우, 브라우저는 Layout 단계부터 다시 시작하여 모든 요소의 위치와 크기를 재계산한 후 Paint 단계를 거치게 된다.

2️⃣ Paint부터 다시 발생되는 경우

  • 배경 이미지, 텍스트 색상, 그림자 등 레이아웃의 수치를 변화시키지 않는 스타일의 변경이 일어났을 때
    • 배경색 변경
    • 텍스트 색상 변경
    • 그림자 효과 추가/변경
    • 투명도(opacity) 변경
    • 코드 예시
      document.getElementById('myDiv').style.backgroundColor = 'blue';
      이 경우, 브라우저는 Layout 단계를 건너뛰고 Paint 단계부터 다시 시작한다. 요소의 위치와 크기는 그대로지만, 새로운 스타일을 적용하여 다시 그리게 된다.

3️⃣ Composite만 다시 발생되는 경우

  • Layout과 Paint을 수행하지 않고 레이어의 합성만 발생하기 때문에 성능상으로 가장 큰 이점을 가진다.
  • 이 경우는 브라우저가 특정 요소를 별도의 레이어로 처리할 수 있을 때 발생한다. 주로 애니메이션이나 변형과 관련이 있다.
    • CSS transform을 사용한 요소 이동
    • CSS opacity를 사용한 투명도 변경
    • CSS fixed position 요소의 이동
    • 코드 예시
      document.getElementById('myDiv').style.transform = 'translateX(100px)';
      이 경우, 브라우저는 Layout과 Paint 단계를 건너뛰고 Composite 단계만 수행한다. 이미 그려진 레이어를 새로운 위치에 배치하는 것만 수행하여 화면을 업데이트하는 것이다.

성능 최적화를 위해서는 가능한 한 3번째 경우(레이어 합성)를 활용하는 것이 좋다. 만약 3번이 불가능한 상황이라면, 가능한 한 적은 요소에만 영향을 주도록 코드를 작성하는 것도 방법이다.




참고 자료

[10분 테코톡] ☕️ 체프의 브라우저 렌더링

Understanding Role of Rendering Engines in Browsers | BrowserStack

브라우저는 어떻게 동작하는가?

[Modern JavaScript] 브라우저의 렌더링 과정

브라우저의 렌더링 과정

웹개발자면서 이것도 모름? | DOM과 CSSOM, 렌더링 과정

0개의 댓글