웹 브라우저 렌더링 과정

1. 파싱(Parse)

웹 브라우저는 HTML, CSS 및 JavaScript와 같은 웹 페이지의 리소스를 서버로부터 가져옵니다. 그리고 가져온 리소스들은 파싱되어 문서 객체 모델(DOM) 및 CSS 객체 모델(CSSOM)로 변환됩니다. 이 단계에서 HTML 마크업을 DOM 트리로 구문 분석하고, CSS 규칙을 파싱하여 CSSOM 트리를 구성합니다.

그리고 DOM 트리와 CSSOM 트리를 이용해서 Render Tree를 생성하고, 문서의 구조와 각 노드의 스타일 속성이 입력되게 됩니다.

파싱이란?

파싱은 주어진 문장이나 코드를 구성 요소로 분해하고 그 구조를 이해하는 과정을 말합니다. 또한 파싱 과정에서 코드 분석을 하며, 특정 액션을 취하거나 데이터 추출, 포괄적인 개념으로의 변환 등의 다양한 목적을 달성할 수도 있습니다. 따라서 파싱을 위해서는 해당 도메인에서의 특정 지식이나 약속된 규칙을 잘 이해합니다.

2. 레이아웃(Layout, Reflow)

레이아웃 단계에서는 DOM 트리와 CSSOM 트리를 기반으로 상대적인 단위(rem, vh, vw)를 실제 픽셀 단위로 변환하고, 각 요소의 크기와 위치를 계산하여 레이아웃 트리(렌더 트리, render tree)를 생성합니다. 레이아웃 트리는 화면에 표시되는 각 요소의 정확한 위치와 크기를 정의합니다. 이 단계에서는 브라우저 창의 크기나 사용자의 스크롤 위치 등과 같은 뷰포트의 속성을 고려하여 요소를 배치합니다.

CSS의 상대적인 단위

  1. em

    요소의 상대적인 크기를 나타내는 단위로, 부모 요소의 폰트 크기가 기준이 됩니다.

  2. rem

    root em의 약자로, em과 마찬가지로 요소의 상대적인 크기를 나타냅니다. 기준은 root 요소의 폰트 크기가 기준이 됩니다. 따라서 전체 페이지에 걸쳐 일관된 크기를 유지할 수 있습니다.

  3. %

    부모의 요소의 크기를 기준으로 상대적인 크기를 나타내는 단위입니다. 예를 들어 부모 요소의 width가 200px인데, 자식 요소의 폭이 50%이면 자식 요소의 실제 width값은 100px이 됩니다.

  4. vw, vh

    viewport width와 viewport height의 비율을 의미하는 단위입니다. vw는 뷰포트 너비의 1/100을, vh는 뷰포트 높이의 1/100을 나타냅니다. 예를 들어, 50vw는 현재 뷰포트의 너비의 50%를 나타내고, 75vh는 뷰포트의 높이의 75%를 나타냅니다.

상대적인 단위들은 반응형 웹 디자인과 레이아웃 조정에 유용하게 사용되며, 화면 크기에 따라 자동으로 조정되어 다양한 장치와 화면 크기에서 일관된 디자인을 제공할 수 있습니다.

뷰포트(viewport)

뷰포트(viewport)는 웹 페이지를 표시하는 디바이스의 실제 가시 영역을 의미합니다. 즉, 사용자가 웹 브라우저 안에서 웹 페이지를 볼 수 있는 실제 화면 영역을 말합니다. 웹 브라우저는 웹 페이지를 뷰포트에 표시하고 사용자가 상호 작용할 수 있도록 합니다.

뷰포트의 크기는 디바이스의 화면 크기에 따라 다르며, 일반적으로 픽셀 단위로 표현됩니다. 뷰포트의 너비와 높이는 웹 페이지에서 사용할 수 있는 가용한 공간을 나타냅니다.

모바일 디바이스의 경우, 뷰포트의 너비는 일반적으로 디바이스의 화면의 실제 픽셀 너비와 동일합니다. 하지만 초기에는 데스크톱 웹 페이지를 모바일 디바이스에서 확대해서 보여주는 경우도 있었습니다. 이때 뷰포트의 너비는 초기 화면에 맞추어 설정되어 전체 컨텐츠가 화면에 나타날 수 있도록 했습니다.

그러나 모바일 웹 디자인에서는 반응형 레이아웃과 뷰포트 메타 태그를 사용하여 뷰포트를 제어하고 조정하는 것이 중요해졌습니다. 뷰포트 메타 태그를 사용하면 웹 개발자가 뷰포트의 초기 크기, 축소/확대 제한, 페이지 배율 조정 등을 설정할 수 있습니다. 이를 통해 모바일 장치에서 웹 페이지가 올바르게 표시되고 사용자 경험이 향상될 수 있습니다.

뷰포트는 반응형 웹 디자인과 모바일 최적화에 핵심적인 역할을 합니다. 적절한 뷰포트 설정과 레이아웃 조정을 통해 다양한 화면 크기와 디바이스에서 웹 페이지가 최적으로 표시되며, 사용자 경험이 향상될 수 있습니다.

3. 페인트(Paint, Repaint)

페인트 단계에서는 레이아웃 트리의 각 요소를 실제로 그려줍니다. 이 단계에서는 요소의 배경색, 텍스트, 이미지 등을 브라우저의 렌더링 엔진을 통해 화면에 페인팅합니다. 브라우저의 렌더링 엔진은 DOM Tree의 각 요소를 순서대로 탐색하며 해당 요소의 스타일과 속성을 적용하여, 화면에 요소를 배치하고 화면에 그래픽을 그립니다. Paint 단계에서는 화면을 업데이트하는 작업에 집중되며, 이 단계에서의 작업은 GPU가 아닌 'CPU'에 의해 처리됩니다.

4. 합성(Composite)

Composite 단계는 렌더링 엔진이 그려진 그래픽을 최종 화면에 조합하는 단계입니다. 이 단계에서는 레이아웃 트리에서 각 요소가 어떻게 겹치고 상호작용하는지 계산하고, 화면에 그려진(paint된) 그래픽 요소들을 합성하여 최종적으로 화면에 표시될 이미지를 생성합니다. 각 그래픽 요소들은 별도의 레이어로 생성되며, 여러 개의 레이어가 합성되어 최종 이미지를 생성하게 됩니다.

Composite 단계는 GPU를 사용하여 그래픽을 처리하며, 보통 하드웨어 가속 기능을 활용하여 빠른 화면 갱신을 지원합니다. 여러 개의 레이어(layer)로 구성된 화면의 각 부분이 합성되어 최종 이미지가 생성되는 과정입니다.

브라우저는 Paint 단계에서 화면에 그래픽을 그리고, Composite 단계에서 그려진 그래픽을 조합하여 최종 화면을 구성합니다. 이렇게 구성된 화면은 사용자에게 표시됩니다. Paint 단계와 Composite 단계는 렌더링 과정에서 서로 다른 역할을 수행하며, GPU와 CPU를 효율적으로 활용하여 빠르고 부드러운 화면 갱신을 제공합니다.

브라우저의 렌더링 vs 리액트의 렌더링

브라우저의 렌더링은 웹 페이지의 HTML, CSS, JavaScript 등의 리소스를 가져와서 화면에 표시하는 과정을 의미합니다.

리액트의 렌더링은 리액트 컴포넌트의 가상 DOM(Virtual DOM)을 생성하고 이를 기반으로 실제 DOM을 업데이트하는 과정을 의미합니다.

결국 '렌더링'을 한다는 것은 리소스의 변화를 감지하고 해당 페이지의 구조와 속성을 분석해서 dom을 만들고, 구조와 계층을 시각화하기 위해서 dom tree를 만들고, 다시 그것들을 바탕으로 화면을 업데이트 시켜주는 개념이라고 할 수 있습니다.

리액트의 렌더링 과정

초기 렌더링

  • 리액트 컴포넌트의 가상 DOM(가상 DOM 트리)을 생성합니다.
  • 가상 DOM을 기반으로 실제 DOM에 업데이트를 수행합니다. 이를 마운팅(Mounting)이라고도 합니다.

업데이트

  • 컴포넌트의 상태(State)나 속성(Properties)이 변경되면, 리액트는 업데이트를 트리거합니다.
  • 변경된 상태를 기반으로 새로운 가상 DOM(가상 DOM 트리)을 생성합니다.
  • 이전 가상 DOM과 새로운 가상 DOM을 비교하여 변경된 부분을 찾습니다. 이 과정은 가상 DOM의 Diff 알고리즘을 활용하여 효율적으로 수행됩니다.
  • 변경된 부분만을 선택적으로 실제 DOM에 반영하여 업데이트합니다. 이를 리렌더링(Rendering)이라고도 합니다.

리액트의 가상 DOM을 활용하는 이유는, 모든 컴포넌트를 다시 렌더링하는 대신 변경된 부분만을 효율적으로 업데이트하기 위해서입니다. 가상 DOM은 실제 DOM 조작을 최소화하고, 변경 사항을 효율적으로 반영하여 성능을 개선합니다. 이에 따라 효율적인 컴포넌트 업데이트와 빠른 UI 렌더링이 가능해졌습니다.

unmount

Unmount 과정은 컴포넌트의 생명주기(Lifecycle) 중 "componentWillUnmount" 메서드가 호출되는 시점에 발생하는 것으로, 이 메서드는 컴포넌트가 화면에서 제거되기 전에 실행됩니다. 주로 리소스 정리, 타이머 해제, 이벤트 핸들러 해제 등의 작업을 수행하는 데 사용됩니다.

Unmount 단계에서는 컴포넌트의 가상 DOM은 더 이상 필요하지 않으며, 컴포넌트가 화면에서 사라지므로 실제 DOM에서도 해당 컴포넌트와 관련된 요소들이 제거됩니다.

컴포넌트가 화면에서 제거되는 주요 상황은 다음과 같습니다.

  1. 라우팅 변경: 사용자가 다른 페이지로 이동하거나 라우팅 경로가 변경될 때, 해당 페이지의 컴포넌트는 화면에서 제거됩니다. 이는 리액트 라우터 또는 다른 라우팅 라이브러리를 사용하여 처리됩니다.

  2. 조건부 렌더링: 화면에서 특정 조건에 따라 컴포넌트를 동적으로 추가하거나 제거하는 경우가 있습니다. 조건이 변경되어 해당 컴포넌트가 화면에 더 이상 필요하지 않을 때, 컴포넌트는 제거됩니다.

  3. 데이터 변경: 컴포넌트의 데이터가 변경되어 해당 컴포넌트가 화면에 더 이상 필요하지 않은 경우에도 컴포넌트는 제거될 수 있습니다. 예를 들어, 리스트 컴포넌트에서 항목이 삭제되거나 필터링 조건에 따라 특정 항목이 숨겨질 때 해당 컴포넌트는 제거됩니다.

리액트에서 컴포넌트가 unmount되면 다음과 같은 과정을 진행합니다.

  • 컴포넌트의 "componentWillUnmount" 메서드가 호출됩니다. 이 메서드 내에서는 컴포넌트의 정리 작업이 수행됩니다.
  • 해당 컴포넌트와 관련된 실제 DOM 요소들이 제거됩니다. 이로써 화면에서 해당 컴포넌트가 완전히 제거되고, 관련된 자원들이 해제됩니다.

Unmount 단계는 컴포넌트의 라이프사이클에서 중요한 단계입니다. 컴포넌트가 더 이상 필요하지 않을 때 메모리 누수를 방지하고 자원을 정리하기 위해 Unmount 단계에서 필요한 작업을 수행합니다. 이를 통해 애플리케이션의 성능과 자원 관리를 향상시킬 수 있습니다.

참고로 함수형 컴포넌트에서는 useEffect 훅을 이용하면 mount, unmount 시 실행할 동작을 정해줄 수도 있습니다.

렌더링 컨텍스트

렌더링 컨텍스트(Rendering Context)는 리액트에서 컴포넌트 트리 전체에 대한 데이터를 공유하기 위한 메커니즘입니다. 렌더링 컨텍스트를 사용하면 컴포넌트 간에 데이터를 전달하고 공유할 수 있으며, 중첩된 컴포넌트에서도 쉽게 접근할 수 있습니다.

렌더링 컨텍스트는 주로 상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때 사용됩니다. 이를 통해 프로퍼티 체인을 통해 데이터를 하위 컴포넌트로 전달하는 것보다 간편하고 효율적인 방식으로 데이터를 공유할 수 있습니다.

렌더링 컨텍스트는 다음과 같은 주요 특징을 가지고 있습니다:

  1. Provider와 Consumer: 렌더링 컨텍스트는 Provider와 Consumer라는 두 가지 주요 구성 요소로 구성됩니다. Provider는 데이터를 제공하는 컴포넌트이고, Consumer는 데이터를 소비하는 컴포넌트입니다.

  2. 데이터 공유: Provider 컴포넌트는 하위 컴포넌트에 데이터를 전달합니다. 이 데이터는 컴포넌트 트리의 하위 컴포넌트에서 Consumer 컴포넌트를 통해 접근할 수 있습니다.

  3. 중첩된 컴포넌트에서의 접근: 렌더링 컨텍스트는 중첩된 컴포넌트에서도 쉽게 접근할 수 있습니다. 컴포넌트 트리의 어느 위치에서든 Provider 컴포넌트를 사용하여 데이터를 제공하고, 필요한 곳에서 Consumer 컴포넌트를 사용하여 데이터를 소비할 수 있습니다.

렌더링 컨텍스트는 주로 전역적인 상태 관리, 테마, 로컬라이제이션, 인증 정보 등과 같이 여러 컴포넌트에서 공유되어야 하는 데이터를 전달하는데 사용됩니다. 이를 통해 컴포넌트 간의 데이터 전달을 간소화하고, 중복 코드를 줄일 수 있습니다.

렌더링 컨텍스트는 React.createContext() 함수를 사용하여 생성하며, Provider와 Consumer 컴포넌트를 통해 데이터를 제공하고 소비합니다.

웹 브라우저의 구조

User Interface

  • 사용자가 웹 브라우저와 상호작용할 수 있도록 하는 부분입니다.
  • 주소 표시줄, 이전/다음 버튼, 즐겨찾기, 확대/축소 등의 기능이 포함됩니다.

Browser Engine

브라우저 엔진은 User Interface와 Browser Engine을 연결하는 역할을 합니다.

Rendering Engine

  • 웹 페이지의 HTML, CSS 등을 해석하여 화면에 그래픽을 그리는 엔진입니다.
  • DOM Tree와 CSSOM Tree를 생성하고, 이를 기반으로 레이아웃을 처리하고 화면에 그래픽 요소를 배치합니다.
  • 대표적인 렌더링 엔진으로는 Blink(Chrome, Opera), Gecko(Firefox), WebKit(Safari) 등이 있습니다.
  • 크롬의 경우 원래는 Webkit을 쓰다가, 2013년부터 Webkit에서 갈라져 나온 Blink 엔진을 사용하고 있습니다.

Networking

  • Networking은 웹 브라우저에서 서버로의 통신을 처리하는 역할을 의미합니다.
  • HTTP 요청과 응답을 주고받아 웹 페이지의 리소스를 로드하고 전송합니다.
  • 네트워킹은 웹 페이지의 리소스를 다운로드하고, 외부 서버와의 통신을 처리하는 등의 네트워크 관련 작업을 담당합니다.

JavaScript Interpreter

  • 웹 페이지에 포함된 JavaScript 코드를 해석하고 실행합니다.
  • 자바스크립트 엔진은 브라우저 엔진의 일부로 포함되어 있습니다.
  • 예를 들어, V8 엔진은 Chrome에서 사용되고, SpiderMonkey 엔진은 Firefox에서 사용됩니다.

UI Backend

  • 사용자 인터페이스를 그리는 데 사용되는 백엔드 시스템입니다.
  • 플랫폼에 따라 다양한 시스템 API를 사용하여 윈도우, 버튼, 메뉴 등을 그립니다.

UI Backend는 각 플랫폼의 기능과 시스템 API를 활용하여 UI 요소를 그리고 이벤트를 처리합니다. 이를 통해 사용자 인터페이스를 그리고 사용자 입력에 응답하는 등의 작업을 수행합니다. 각 플랫폼은 해당 플랫폼에 특화된 UI Backend를 가지고 있으며, 플랫폼에 따라 API 및 도구가 다를 수 있습니다.

예를 들어, Windows에서는 UI 요소를 그리기 위해 Windows API 함수를 사용하고, macOS에서는 Core Graphics 및 AppKit을 활용하여 UI를 그리고 이벤트를 처리합니다. 이와 같은 방식으로 UI Backend는 각 플랫폼에서 원활한 UI 표시와 상호작용을 제공합니다.

Data Persistance

  • 웹 브라우저 내에서 데이터를 저장하고 관리하는 기능입니다.
  • 쿠키, 로컬 스토리지, 세션 스토리지, 웹 데이터베이스 등의 저장소를 사용하여 데이터를 유지합니다.

Back-End Integration

  • Back-End Integration은 웹 브라우저와 웹 서버 간의 데이터 통신을 관리하는 역할을 의미합니다.
  • 웹 브라우저에서 서버로 데이터를 전송하거나, 서버로부터 동적인 콘텐츠를 받아오는 등의 작업을 수행합니다.
  • 백엔드 통합은 웹 애플리케이션에서 서버 측과의 상호작용을 담당합니다.

Networking은 주로 웹 브라우저의 네트워크 관련 기능을 포함하고, HTTP 요청 및 응답을 처리합니다. 이는 웹 페이지의 리소스를 로드하거나, API와의 통신을 위한 네트워크 작업을 담당합니다.

반면에 Back-End Integration은 주로 웹 애플리케이션과 백엔드 서버 간의 데이터 통신을 관리합니다. 웹 브라우저에서 서버로 데이터를 전송하고, 서버로부터 동적인 콘텐츠를 받아오는 등의 작업을 수행합니다. 이는 웹 애플리케이션의 비즈니스 로직과 데이터 처리를 위한 서버와의 상호작용을 담당합니다.

따라서, Networking은 네트워크 관련 작업을 처리하고, Back-End Integration은 웹 애플리케이션과 서버 간의 데이터 통신을 관리하는 역할을 수행합니다. 두 개념은 서로 관련이 있으며 웹 브라우저의 기능을 지원하기 위해 함께 동작합니다.

참조링크

[10분 테코톡] 콤피의 CSS를 통한 브라우저 렌더링 최적화

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

profile
Front-end | Web Develop | Computer Science 🧑🏻‍💻

0개의 댓글