RenderingNG 아키텍처 개요

Chris Harrelson
Chris Harrelson

이전 게시물에서 RenderingNG 아키텍처 목표와 주요 속성을 간략하게 설명했습니다. 이 게시물에서는 구성요소 조각이 설정되고 렌더링 파이프라인이 이러한 조각을 통과하는 방식을 설명합니다.

가장 높은 수준에서 시작하여 드릴다운하면 렌더링 작업은 다음과 같습니다.

  1. 화면의 픽셀로 콘텐츠를 렌더링합니다.
  2. 콘텐츠의 시각 효과를 한 상태에서 다른 상태로 애니메이션합니다.
  3. 입력에 대한 응답으로 스크롤합니다.
  4. 개발자 스크립트 및 기타 하위 시스템이 응답할 수 있도록 올바른 위치로 입력을 효율적으로 라우팅합니다.

렌더링할 콘텐츠는 각 브라우저 탭과 브라우저 UI의 프레임 트리입니다. 터치 스크린, 마우스, 키보드 및 기타 하드웨어 기기의 원시 입력 이벤트 스트림입니다.

각 프레임에는 다음이 포함됩니다.

  • DOM 상태
  • CSS
  • 캔버스
  • 이미지, 동영상, 글꼴, SVG와 같은 외부 리소스

프레임은 HTML 문서 및 URL입니다. 브라우저 탭에 로드된 웹페이지에는 최상위 프레임, 최상위 문서에 포함된 각 iframe의 하위 프레임, 재귀 iframe 하위 요소가 있습니다.

시각 효과는 스크롤, 변환, 클립, 필터, 불투명도 또는 블렌딩과 같이 비트맵에 적용되는 그래픽 작업입니다.

아키텍처 구성요소

RenderingNG에서 이러한 작업은 여러 단계와 코드 구성요소에 걸쳐 논리적으로 분할됩니다. 구성요소는 다양한 CPU 프로세스, 스레드 및 이러한 스레드 내의 하위 구성요소에 배치됩니다. 각각은 모든 웹 콘텐츠에 대해 안정성, 확장 가능한 성능, 확장성을 달성하는 데 중요한 역할을 합니다.

렌더링 파이프라인 구조

다음 텍스트에 설명된 렌더링 파이프라인 다이어그램

렌더링은 그 과정에서 여러 단계와 아티팩트가 생성되는 파이프라인에서 진행됩니다. 각 스테이지는 렌더링 내에서 잘 정의된 작업 하나를 실행하는 코드를 나타냅니다. 아티팩트는 단계의 입력 또는 출력인 데이터 구조입니다. 다이어그램에서 입력 또는 출력은 화살표로 표시되어 있습니다.

이 블로그 게시물에서는 아티팩트에 대해 자세히 다루지 않으며 다음 게시물인 RenderingNG에서 주요 데이터 구조 및 그 역할에서 다루겠습니다.

파이프라인 단계

앞의 다이어그램에서 단계는 실행되는 스레드 또는 프로세스를 나타내는 색상으로 표시됩니다.

  • 녹색: 렌더링 프로세스 기본 스레드
  • 노란색: 렌더링 프로세스 컴포지터
  • 주황색: 시각화 프로세스

상황에 따라 여러 위치에서 실행할 수 있는 경우도 있기 때문에 두 가지 색상이 있는 경우도 있습니다.

단계는 다음과 같습니다.

  1. 애니메이션: 계산된 스타일을 변경하고 선언적 타임라인에 따라 시간 경과에 따라 속성 트리를 변경합니다.
  2. 스타일: CSS를 DOM에 적용하고 계산된 스타일을 만듭니다.
  3. 레이아웃: 화면에서 DOM 요소의 크기와 위치를 결정하고 변경 불가능한 프래그먼트 트리를 만듭니다.
  4. 사전 페인트: 속성 트리를 계산하고 기존 표시 목록 및 GPU 텍스처 타일을 적절하게 invalidate합니다.
  5. 스크롤: 속성 트리를 변형하여 문서와 스크롤 가능한 DOM 요소의 스크롤 오프셋을 업데이트합니다.
  6. 페인트: DOM에서 GPU 텍스처 타일을 래스터하는 방법을 설명하는 표시 목록을 계산합니다.
  7. 커밋: 속성 트리와 표시 목록을 컴포지터 스레드에 복사합니다.
  8. Layerize(레이어화): 독립적인 래스터화 및 애니메이션을 위해 표시 목록을 합성 레이어 목록으로 분할합니다.
  9. 래스터, 디코딩, 페인트 워크릿: 표시 목록, 인코딩된 이미지, 페인트 Worklet 코드를 각각 GPU 텍스처 타일로 변환합니다.
  10. 활성화: 시각 효과와 함께 GPU 타일을 화면에 그리고 배치하는 방법을 나타내는 컴포지터 프레임을 만듭니다.
  11. 집계: 표시되는 모든 컴포지터 프레임의 컴포지터 프레임을 단일 전역 컴포지터 프레임으로 결합합니다.
  12. 그리기: GPU에서 집계된 컴포지터 프레임을 실행하여 화면에 픽셀을 만듭니다.

렌더링 파이프라인의 단계는 필요하지 않은 경우 건너뛸 수 있습니다. 예를 들어 시각 효과와 스크롤 애니메이션에서는 레이아웃, 프리 페인트, 페인트를 건너뛸 수 있습니다. 이러한 이유로 다이어그램에서 애니메이션과 스크롤이 노란색과 녹색 점으로 표시됩니다. 시각 효과를 위해 레이아웃, 사전 페인트, 페인트를 건너뛸 수 있는 경우 컴포지터 스레드에서 완전히 실행하고 기본 스레드를 건너뛸 수 있습니다.

브라우저 UI 렌더링은 여기에 직접 묘사되지는 않지만 이 파이프라인의 단순화된 버전으로 생각할 수 있습니다(실제로 구현은 코드의 대부분을 공유함). (직접 묘사되지는 않음) 동영상은 일반적으로 프레임을 GPU 텍스처 타일로 디코딩한 다음 컴포지터 프레임과 그리기 단계에 연결하는 독립 코드를 통해 렌더링됩니다.

프로세스 및 스레드 구조

CPU 프로세스

여러 CPU 프로세스를 사용하면 사이트 간 및 브라우저 상태에서 성능과 보안이 격리되고, GPU 하드웨어로부터 안정성과 보안이 격리됩니다.

CPU 프로세스의 다양한 부분을 보여주는 다이어그램

  • 렌더링 프로세스는 단일 사이트와 탭 조합의 입력을 렌더링, 애니메이션 처리, 스크롤, 라우팅합니다. 렌더링 프로세스는 다양합니다.
  • 브라우저 프로세스는 브라우저 UI의 입력(URL 표시줄, 탭 제목, 아이콘 포함)을 렌더링하고 애니메이션으로 처리하고 나머지 입력을 모두 적절한 렌더링 프로세스로 라우팅합니다. 브라우저 프로세스는 정확히 하나뿐입니다.
  • 비즈 프로세스는 여러 렌더링 프로세스 및 브라우저 프로세스에서 합성을 집계합니다. GPU를 사용하여 래스터화하고 그립니다. Viz 프로세스는 정확히 1개입니다.

사이트마다 항상 서로 다른 렌더링 프로세스가 이루어집니다. (실제로는 항상 데스크톱에서 사용 가능하며 가능하면 모바일에서 사용하는 것이 좋습니다. 아래에 '항상'이라고 적겠지만 이 주의사항은 전체적으로 적용됩니다.)

동일한 사이트에서 여러 브라우저 탭이나 창은 일반적으로 서로 다른 렌더링 프로세스를 거칩니다. 단, 탭이 서로 연결되는 경우는 예외입니다. 데스크톱의 메모리 압력이 강하면 Chromium에서 동일한 사이트의 여러 탭을 서로 관련이 없더라도 동일한 렌더링 프로세스에 배치할 수 있습니다.

단일 브라우저 탭 내에서는 다른 사이트의 프레임이 항상 서로 다른 렌더링 프로세스에 있지만 동일한 사이트의 프레임은 항상 동일한 렌더링 프로세스에 있습니다. 렌더링의 관점에서 다중 렌더링 프로세스의 중요한 이점은 교차 사이트 iframe과 탭이 서로 성능 격리를 지원한다는 것입니다. 또한 출처는 훨씬 더 높은 격리를 선택할 수 있습니다.

모든 Chromium에는 정확히 하나의 Viz 프로세스가 있습니다. 무엇보다도 일반적으로 그릴 수 있는 GPU와 화면이 하나뿐입니다. Viz를 자체 프로세스로 분리하면 GPU 드라이버 또는 하드웨어의 버그 발생 시 안정성이 향상됩니다. 또한 Vulkan과 같은 GPU API에 중요한 보안 격리에도 유용합니다. 이는 일반적인 보안에도 중요합니다.

브라우저에는 여러 개의 탭과 창이 있을 수 있고 모든 창에 그릴 브라우저 UI 픽셀이 있으므로 브라우저 프로세스가 정확히 하나만 있는 이유가 궁금할 수 있습니다. 그 이유는 한 번에 하나만 포커스가 있고, 실제로 표시되지 않는 브라우저 탭은 대부분 비활성화되고 모든 GPU 메모리를 삭제하기 때문입니다. 그러나 복잡한 브라우저 UI 렌더링 기능이 렌더링 프로세스 (WebUI라고도 함)에서도 점점 더 많이 구현되고 있습니다. 이는 성능 격리를 위한 것이 아니라 Chromium의 웹 렌더링 엔진의 사용 편의성을 활용하기 위한 것입니다.

이전 Android 기기에서는 WebView에서 사용할 때 렌더링 및 브라우저 프로세스가 공유됩니다. 이는 일반적으로 Android의 Chromium에는 적용되지 않으며 WebView에만 적용됩니다. WebView에서는 브라우저 프로세스도 삽입 앱과 공유되며 WebView에는 렌더링 프로세스가 하나만 있습니다.

보호된 동영상 콘텐츠를 디코딩하는 유틸리티 프로세스도 있습니다. 이 과정은 위에 설명되어 있지 않습니다.

대화목록

스레드는 작업 속도가 느리고 파이프라인 병렬화, 다중 버퍼링에도 불구하고 성능 격리와 응답성을 달성하는 데 도움이 됩니다.

이 문서에 설명된 렌더링 프로세스 다이어그램

  • 기본 스레드는 스크립트, 렌더링 이벤트 루프, 문서 수명 주기, 조회 테스트, 스크립트 이벤트 전달, HTML, CSS, 기타 데이터 형식의 파싱을 실행합니다.
    • 기본 스레드 도우미는 인코딩 또는 디코딩이 필요한 이미지 비트맵 및 blob 생성과 같은 작업을 실행합니다.
    • 웹 작업자는 OffscreenCanvas의 스크립트 및 렌더링 이벤트 루프를 실행합니다.
  • 컴포지터 스레드는 입력 이벤트를 처리하고, 웹 콘텐츠의 스크롤 및 애니메이션을 실행하고, 웹 콘텐츠의 최적 계층화를 계산하며, 이미지 디코딩, 페인트 워크릿 및 래스터 작업을 조정합니다.
    • 컴포지터 스레드 도우미는 Viz 래스터 작업을 조정하고 이미지 디코딩 작업, 페인트 Worklet, 대체 래스터를 실행합니다.
  • 미디어, 디뮤서 또는 오디오 출력 스레드는 동영상 및 오디오 스트림을 디코딩, 처리, 동기화합니다. 동영상은 기본 렌더링 파이프라인과 동시에 실행됩니다.

기본 스레드와 컴포지터 스레드를 분리하는 것은 애니메이션의 성능 격리 및 기본 스레드 작업에서 스크롤하는 데 매우 중요합니다.

같은 사이트의 여러 탭이나 프레임이 같은 프로세스에 있을 수 있지만 렌더링 프로세스당 하나의 기본 스레드만 있습니다. 그러나 다양한 브라우저 API에서 수행되는 작업과 성능은 분리되어 있습니다. 예를 들어 Canvas API의 이미지 비트맵 및 blob 생성은 기본 스레드 도우미 스레드에서 실행됩니다.

마찬가지로 렌더링 프로세스당 컴포지터 스레드가 하나만 있습니다. 컴포지터 스레드에서 비용이 많이 드는 모든 작업이 컴포지터 작업자 스레드나 Viz 프로세스에 위임되고 이 작업을 입력 라우팅, 스크롤 또는 애니메이션과 동시에 실행할 수 있으므로 일반적으로 하나만 있다는 것은 문제가 되지 않습니다. 컴포지터 작업자 스레드는 Viz 프로세스에서 실행되는 작업을 조정하지만 드라이버 버그와 같이 Chromium에서 제어할 수 없는 이유로 인해 모든 곳에서 GPU 가속이 실패할 수 있습니다. 이러한 상황에서 작업자 스레드는 CPU의 대체 모드로 작업을 수행합니다.

컴포지터 작업자 스레드의 수는 기기 기능에 따라 다릅니다. 예를 들어 데스크톱은 휴대기기보다 CPU 코어가 더 많고 배터리 제약이 적기 때문에 일반적으로 스레드를 더 많이 사용합니다. 이것은 수직 확장 및 축소의 예입니다.

렌더링 프로세스 스레딩 아키텍처는 세 가지 최적화 패턴을 적용한 것이라는 점도 흥미롭습니다.

  • 도우미 스레드: 장기 실행 하위 태스크를 추가 스레드로 보내 상위 스레드가 동시에 발생하는 다른 요청에 응답하도록 합니다. 기본 스레드 도우미 및 컴포지터 도우미 스레드가 이 기법의 좋은 예입니다.
  • 다중 버퍼링: 새 콘텐츠를 렌더링하는 동안 이전에 렌더링된 콘텐츠를 표시하여 렌더링 지연 시간을 숨깁니다. 컴포지터 스레드는 이 기법을 사용합니다.
  • 파이프라인 병렬화: 여러 위치에서 동시에 렌더링 파이프라인을 실행합니다. 스크롤과 애니메이션을 동시에 실행할 수 있으므로 기본 스레드 렌더링 업데이트가 발생하더라도 스크롤과 애니메이션이 이렇게 빨라질 수 있습니다.

브라우저 프로세스

렌더링 스레드와 합성 스레드, 렌더링 및 합성 스레드 도우미 간의 관계를 보여주는 브라우저 프로세스 다이어그램

  • 렌더링 및 합성 스레드는 브라우저 UI의 입력에 응답하고 다른 입력을 올바른 렌더링 프로세스로 라우팅하며 브라우저 UI를 배치하고 페인트합니다.
  • 렌더링 및 합성 스레드 도우미는 이미지 디코딩 작업을 실행하고 대체 래스터 또는 디코딩을 실행합니다.

브라우저 프로세스 렌더링 및 합성 스레드는 기본 스레드와 컴포지터 스레드가 하나로 결합된다는 점을 제외하고 렌더링 프로세스의 코드 및 기능과 유사합니다. 이 경우에는 스레드가 하나만 필요합니다. 긴 기본 스레드 작업에서 성능 격리가 필요하지 않기 때문입니다. 왜냐하면 설계상 스레드가 없기 때문입니다.

Viz 프로세스

Viz 프로세스에 GPU 기본 스레드와 디스플레이 컴포지터 스레드가 포함되어 있음을 보여주는 다이어그램

  • GPU 기본 스레드 래스터는 목록과 동영상 프레임을 GPU 텍스처 타일에 표시하고 컴포지터 프레임을 화면에 그립니다.
  • 디스플레이 컴포지터 스레드는 각 렌더링 프로세스 및 브라우저 프로세스에서 합성을 화면에 표시하기 위해 단일 컴포지터 프레임으로 집계하고 최적화합니다.

래스터와 그리기는 일반적으로 동일한 스레드에서 발생합니다. 둘 다 GPU 리소스에 의존하고 GPU를 멀티 스레드로 안정적으로 사용하기가 어렵기 때문입니다. GPU에 대한 더 쉬운 멀티 스레드 액세스가 새로운 Vulkan 표준을 개발하는 한 가지 동기 중 하나입니다. Android WebView에는 WebView가 네이티브 앱에 삽입되는 방식 때문에 그리기를 위한 별도의 OS 수준 렌더링 스레드가 있습니다. 향후 다른 플랫폼에서도 이러한 스레드를 보유할 수 있습니다.

디스플레이 컴포지터는 다른 스레드에 있습니다. 항상 응답해야 하고 GPU 기본 스레드에서 속도 저하 원인을 차단할 수 없어야 하기 때문입니다. GPU 기본 스레드가 느려지는 한 가지 이유는 공급업체별 GPU 드라이버와 같이 Chromium이 아닌 코드를 호출하는데, 이 호출로 인해 예측하기 어려운 방식으로 속도가 느려질 수 있습니다.

구성요소 구조

각 렌더링 프로세스 기본 스레드나 컴포지터 스레드 내에는 구조화된 방식으로 서로 상호작용하는 논리적 소프트웨어 구성요소가 있습니다.

렌더링 프로세스 기본 스레드 구성요소

Blink 렌더기의 다이어그램

  • Blink 렌더기:
    • 로컬 프레임 트리 조각은 로컬 프레임 트리와 프레임 내의 DOM을 나타냅니다.
    • DOM 및 Canvas API 구성요소에는 이러한 모든 API의 구현이 포함되어 있습니다.
    • 문서 수명 주기 실행기는 커밋 단계까지는 렌더링 파이프라인 단계를 실행합니다.
    • 입력 이벤트 조회 테스트 및 전달 구성요소는 조회 테스트를 실행하여 이벤트에서 타겟팅하는 DOM 요소를 확인하고 입력 이벤트 전달 알고리즘 및 기본 동작을 실행합니다.
  • 렌더링 이벤트 루프 스케줄러 및 실행기는 이벤트 루프에서 실행할 항목과 실행 시점을 결정합니다. 기기 디스플레이와 일치하는 주기로 렌더링이 발생하도록 예약합니다.

프레임 트리 다이어그램

로컬 프레임 트리 프래그먼트는 생각하기에 약간 복잡합니다. 프레임 트리는 기본 페이지 및 하위 iframe이며 반복적으로 사용됩니다. 프레임은 렌더링 프로세스에서 렌더링되는 경우 렌더링 프로세스의 로컬이며 렌더링되지 않으면 원격입니다.

렌더링 프로세스에 따라 프레임에 색상을 지정한다고 상상할 수 있습니다. 위 이미지에서 녹색 원은 모두 한 렌더링 프로세스의 모든 프레임입니다. 주황색 원은 1초에, 파란색 원은 1/3에 있습니다.

로컬 프레임 트리 프래그먼트는 프레임 트리에 있는 동일한 색상으로 연결된 구성요소입니다. 이미지에는 로컬 프레임 트리가 4개 있습니다(사이트 A에 2개, 사이트 B에 1개, 사이트 C에 1개). 각 로컬 프레임 트리는 자체 Blink 렌더기 구성요소를 가져옵니다. 로컬 프레임 트리의 Blink 렌더기는 다른 로컬 프레임 트리와 동일한 렌더링 프로세스에 있을 수도 있고 아닐 수도 있습니다(앞서 설명한 대로 렌더링 프로세스가 선택되는 방식에 따라 결정됩니다).

렌더링 프로세스 컴포지터 스레드 구조

렌더링 프로세스 컴포지터 구성요소를 보여주는 다이어그램

렌더링 프로세스 컴포지터 구성요소에는 다음이 포함됩니다.

  • 합성 레이어 목록, 표시 목록 및 속성 트리를 유지관리하는 데이터 핸들러입니다.
  • 렌더링 파이프라인의 단계를 애니메이션, 스크롤, 합성, 래스터, 디코딩, 활성화하는 수명 주기 실행기 애니메이션과 스크롤은 기본 스레드와 컴포지터 모두에서 발생할 수 있습니다.
  • 입력 및 히트 테스트 핸들러는 합성된 레이어의 해상도로 입력 처리 및 히트 테스트를 실행하여 스크롤 동작을 컴포지터 스레드에서 실행할 수 있는지, 어떤 렌더링 프로세스 히트 테스트를 타겟팅해야 하는지 판단합니다.

실제 사례

이제 예를 들어 아키텍처를 구체적으로 만들어 보겠습니다. 이 예에는 다음과 같은 3개의 탭이 있습니다.

탭 1: foo.com

<html>
  <iframe id=one src="foo.com/other-url"></iframe>
  <iframe  id=two src="bar.com"></iframe>
</html>

탭 2: bar.com

<html>
 …
</html>

탭 3: baz.com html <html> … </html>

이러한 탭의 프로세스, 스레드 및 구성 요소 구조는 다음과 같습니다.

탭 프로세스 다이어그램

이제 렌더링의 4가지 기본 작업을 각각 하나씩 살펴보겠습니다. 예를 들면 다음과 같습니다.

  1. 콘텐츠를 화면의 픽셀로 렌더링합니다.
  2. 콘텐츠의 시각 효과를 한 상태에서 다른 상태로 애니메이션합니다.
  3. 입력에 대한 응답으로 스크롤합니다.
  4. 개발자 스크립트 및 기타 하위 시스템이 응답할 수 있도록 입력을 올바른 위치로 효율적으로 라우팅합니다.

탭 1용으로 변경된 DOM을 렌더링하려면 다음 단계를 따르세요.

  1. 개발자 스크립트가 foo.com의 렌더링 프로세스에서 DOM을 변경합니다.
  2. Blink 렌더기는 컴포지터에 렌더기가 필요하다고 알려 줍니다.
  3. 컴포지터는 Viz에 렌더링이 필요하다고 알립니다.
  4. Viz는 컴포지터에 렌더의 시작을 다시 알립니다.
  5. 컴포지터는 시작 신호를 Blink 렌더기에 전달합니다.
  6. 기본 스레드 이벤트 루프 실행기가 문서 수명 주기를 실행합니다.
  7. 기본 스레드가 컴포지터 스레드에 결과를 전송합니다.
  8. 컴포지터 이벤트 루프 실행기는 합성 수명 주기를 실행합니다.
  9. 모든 래스터 작업은 래스터용 Viz로 전송됩니다. 이러한 작업이 두 개 이상인 경우가 많습니다.
  10. GPU의 Viz 래스터 콘텐츠
  11. Viz는 래스터 작업 완료를 확인합니다. 참고: Chromium은 종종 래스터가 완료될 때까지 기다리지 않고 대신 15단계가 실행되기 전에 래스터 작업으로 해결해야 하는 동기화 토큰이라는 것을 사용합니다.
  12. 컴포지터 프레임이 Viz로 전송됩니다.
  13. Viz는 foo.com 렌더링 프로세스, bar.com iframe 렌더링 프로세스, 브라우저 UI의 컴포지터 프레임을 집계합니다.
  14. Viz는 추첨 일정을 예약합니다.
  15. Viz는 집계된 컴포지터 프레임을 화면에 그립니다.

탭 2에서 CSS 변환 전환에 애니메이션을 적용하는 방법은 다음과 같습니다.

  1. bar.com 렌더링 프로세스의 컴포지터 스레드는 기존 속성 트리를 변형하여 컴포지터 이벤트 루프의 애니메이션을 확인합니다. 그러면 컴포지터 수명 주기가 다시 실행됩니다. 래스터 및 디코딩 작업이 발생할 수 있지만 여기서는 다루지 않습니다.
  2. 컴포지터 프레임이 Viz로 전송됩니다.
  3. Viz는 foo.com 렌더링 프로세스, bar.com 렌더링 프로세스, 브라우저 UI용 컴포지터 프레임을 집계합니다.
  4. Viz는 추첨 일정을 예약합니다.
  5. Viz는 집계된 컴포지터 프레임을 화면에 그립니다.

탭 3에서 웹페이지를 스크롤하려면 다음 단계를 따르세요.

  1. 일련의 input 이벤트 (마우스, 터치 또는 키보드)가 브라우저 프로세스에 들어옵니다.
  2. 각 이벤트는 baz.com의 렌더링 프로세스 컴포지터 스레드로 라우팅됩니다.
  3. 컴포지터는 기본 스레드가 이벤트에 관해 알아야 하는지 판단합니다.
  4. 필요한 경우 이벤트는 기본 스레드로 전송됩니다.
  5. 기본 스레드는 input 이벤트 리스너(pointerdown, touchstar, pointermove, touchmove 또는 wheel)를 실행하여 리스너가 이벤트에서 preventDefault를 호출하는지 확인합니다.
  6. 기본 스레드가 preventDefault가 컴포지터에 호출되었는지 여부를 반환합니다.
  7. 그렇지 않으면 입력 이벤트가 브라우저 프로세스로 다시 전송됩니다.
  8. 브라우저 프로세스는 이 동작을 다른 최근 이벤트와 결합하여 스크롤 동작으로 변환합니다.
  9. 스크롤 동작은 baz.com의 렌더링 프로세스 컴포지터 스레드로 다시 전송됩니다.
  10. 여기에 스크롤이 적용되고 bar.com 렌더링 프로세스의 컴포지터 스레드가 컴포지터 이벤트 루프에서 애니메이션을 재실행합니다. 그런 다음 속성 트리의 스크롤 오프셋을 변경하고 컴포지터 수명 주기를 다시 실행합니다. 또한 기본 스레드에 scroll 이벤트 (여기에서는 설명하지 않음)를 실행하라고 지시합니다.
  11. 컴포지터 프레임이 Viz로 전송됩니다.
  12. Viz는 foo.com 렌더링 프로세스, bar.com 렌더링 프로세스, 브라우저 UI의 컴포지터 프레임을 집계합니다.
  13. Viz는 추첨 일정을 예약합니다.
  14. Viz는 집계된 컴포지터 프레임을 화면에 그립니다.

탭 1에서 iframe #2의 하이퍼링크에 있는 click 이벤트를 라우팅하려면 다음 단계를 따르세요.

  1. input 이벤트 (마우스, 터치 또는 키보드)가 브라우저 프로세스에 수신됩니다. 대략적인 히트 테스트를 실행하여 bar.com iframe 렌더링 프로세스가 클릭을 수신해야 하는지 확인한 후 거기로 전송합니다.
  2. bar.com의 컴포지터 스레드는 click 이벤트를 bar.com의 기본 스레드로 라우팅하고 렌더링 이벤트 루프 작업을 예약하여 처리합니다.
  3. bar.com의 기본 스레드용 입력 이벤트 프로세서는 iframe에서 클릭된 DOM 요소를 확인하기 위해 테스트를 실행하고 스크립트에서 관찰할 수 있도록 click 이벤트를 실행합니다. preventDefault를 듣지 못하여 하이퍼링크로 이동합니다.
  4. 하이퍼링크의 대상 페이지가 로드되면 위의 '변경된 DOM 렌더링' 예와 유사한 단계로 새 상태가 렌더링됩니다. (이와 같은 후속 변경사항은 여기에 설명되지 않습니다.)

결론

정말 자세히 설명해 주셨네요. 보시다시피 Chromium에서의 렌더링은 매우 복잡합니다. 모든 요소를 기억하고 내재화하는 데 많은 시간이 걸릴 수 있으므로 부담스러워 보여도 걱정하지 마세요.

가장 중요한 점은 세심한 모듈화와 세밀한 주의를 통해 개념적으로 단순한 렌더링 파이프라인이 여러 개의 독립적인 구성요소로 분할되었다는 것입니다. 그런 다음 이러한 구성요소는 병렬 프로세스와 스레드에 분할되어 확장 가능한 성능확장성 기회를 극대화합니다.

이러한 각 구성요소는 최신 웹 앱에 필요한 모든 성능과 기능을 구현하는 데 중요한 역할을 합니다. 곧 각 개념과 그 역할에 대한 심층적인 내용을 게시할 것입니다.

하지만 이에 앞서 이 게시물에서 언급한 주요 데이터 구조(렌더링 파이프라인 다이어그램 측면의 파란색으로 표시된 구조)가 코드 구성요소만큼 RenderingNG에 중요한 이유를 설명하겠습니다.

읽어주셔서 감사드리며 조금만 기다려 주세요.

삽화: 우나 크라베츠