이 글은 아래 원문을 번역한 글로 의역이 있을 수 있습니다. 정확한 의미를 파악하고 싶으신 분은 원문을 참고해주시기 바랍니다.
원문: https://developer.chrome.com/blog/renderingng-data-structures/
저작권 정보: https://developers.google.com/terms/site-policies
이 글은 크롬 렌더링 엔진에 있는 시리즈의 일부분이다. 렌더링NG, 아키텍처, VideoNG 및 LayoutNG에 대해 자세히 알아보려면 나머지 시리즈를 확인하십시오.
이 시리즈의 이전 게시물에서는 렌더링NG 아키텍처의 목표, 주요 속성 및 고급 구성요소 조각에 대한 개요를 제공했다.이제 렌더링 파이프라인에 대한 입력 및 출력인 주요 데이터 구조(data structure)를 살펴보도록 하자.
이러한 데이터 구조는 다음과 같다.
- 렌더링 프로세스와 블링크 렌더러(Blink renderer)를 나타내는 로컬 및 원격 노드로 구성된 프레임 트리.
- 불변성 조각 트리(immutable fragment tree)는 레이아웃 제약 조건 알고리즘의 (입)출력을 나타낸다.
- 웹 문서의 변환, 클립(clip), 효과(effect) 및 스크롤 계층을 나타내며 파이프라인 전체에서 사용된다.
- 디스플레이 목록과 페인트 청크는 래스터(raster) 및 레이어화 알고리즘에 대한 입력이다.
- 컴포지터 프레임(Compositor frames)은 GPU를 사용하여 그리는 데 사용되는 표면, 렌더 표면 및 GPU 텍스처 타일을 캡슐화 합니다.
이러한 데이터 구조를 살펴보기 전에, 나는 이전 게시물 중 하나를 기반으로 하는 간단한 예를 보여드리고자 합니다.
이 게시물에서 데이터 구조가 어떻게 적용되는지 보여 주는 이 예를 몇 번 사용할 것입니다.
프레임 트리
크롬은 때때로 교차 오리진 프레임을 상위 프레임과 다른 렌더 프로세스로 렌더링하도록 선택할 수 있습니다.
예에는 총 세 개의 프레임이 있습니다.
사이트 격리를 통해 Chromium은 이 웹 페이지를 렌더링하기 위해 두 개의 렌더 프로세스를 사용할 것입니다.
각 렌더 프로세스에는 해당 웹 페이지에 대한 프레임 트리의 고유한 표현이 있습니다.
다른 프로세스에서 렌더링된 프레임을 원격 프레임으로 표현합니다.
예를 들어, 원격 프레임은 렌더링에서 자리 표시자 역할을 하는 데 필요한 최소한의 정보를 가지고 있습니다.그렇지 않으면 원격 프레임에는 실제 콘텐츠를 렌더링하는 데 필요한 정보가 없습니다.
반대로, 로컬 프레임은 이전 게시물에 설명된 표준 렌더링 파이프라인을 통과하는 프레임을 나타냅니다.로컬 프레임은 해당 프레임의 데이터(DOM 트리 및 스타일 데이터 등)를 렌더링 및 표시할 수 있는 것으로 전환하는 데 필요한 모든 정보를 포함합니다.
렌더링 파이프라인은 로컬 프레임 트리 조각의 세분화에 따라 작동합니다.
보다 복잡한 예를 보십시오.
foo.com기본 프레임으로:
그리고 다음은 bar.com 서브프레임:
아직 렌더러가 2개뿐이지만, 현재 3개의 로컬 프레임 트리 조각이 있으며, 2개는 렌더링 프로세스에 있습니다.foo.com렌더링 프로세스에서 다음 중 하나 bar.com:
웹페이지에 사용할 컴퍼지터 프레임을 1개 제작하기 위해 viz는 동시에 3개의 로컬 프레임 트리의 루트 프레임에서 컴퍼지터 프레임을 요청하고 이를 집계합니다.(이 게시물 뒷부분의 합성기 프레임 섹션도 참조하십시오.)
foo.com메인 프레임과 foo.com/other-page서브프레임은 동일한 프레임 트리의 일부분이며 동일한 프로세스에서 렌더링됩니다.그러나 두 프레임은 서로 다른 로컬 프레임 트리 조각의 일부분이기 때문에 여전히 독립적인 문서 라이프사이클을 가지고 있습니다. 이러한 이유로, 두 가지 모두에 대해 하나의 합성기 프레임을 한 번의 업데이트로 생성할 수 없습니다.렌더 프로세스에는 foo.com/other-page에 대해 생성된 컴포지터 프레임을 foo.com 메인 프레임의 컴포지터 프레임으로 직접 합성하기에 충분한 정보가 없습니다.예를 들어, 프로세스 외 bar.com 부모 프레임은 CSS로 iframe을 변환하거나 DOM의 다른 요소와 iframe의 일부를 차단함으로써 foo.com/other-url iframe의 표시에 영향을 줄 수 있습니다.
시각적 특성 업데이트 폭포
장치 축척 비율 및 뷰포트 크기와 같은 시각적 특성은 렌더링된 출력에 영향을 미치며 로컬 프레임 트리 조각 간에 동기화되어야 합니다.각 로컬 프레임 트리 조각의 루트에는 연결된 위젯 개체가 있습니다. 시각적 속성 업데이트는 나머지 위젯을 위에서 아래로 진행하기 전에 메인 프레임의 위젯으로 이동합니다.
예를 들어, 뷰포트 크기가 변경되면:
이 프로세스는 즉시 수행되지 않으므로 복제된 시각적 속성은 동기화 토큰도 포함합니다. Viz 합성자는 이 동기화 토큰을 사용하여 모든 로컬 프레임 트리 조각이 현재 동기화 토큰과 함께 합성기 프레임을 제출할 때까지 기다립니다.이 프로세스는 다른 시각적 특성과 합성기 프레임을 혼합하는 것을 방지합니다.
불변의 파편나무
불변의 파편 트리는 렌더링 파이프라인의 배치 단계의 출력물입니다. 페이지에 있는 모든 요소의 위치와 크기를 나타냅니다(변형을 적용하지 않음).
각 조각은 DOM 요소의 한 부분을 나타냅니다.일반적으로 요소당 파편이 한 장씩만 존재하지만, 인쇄할 때 다른 페이지로 분할되거나, 다중 열 컨텍스트에 있을 때 열이 더 있을 수 있습니다.
레이아웃 후 각 조각은 불변하게 되어 다시는 변하지 않습니다. 중요한 것은, 우리는 또한 몇 가지 추가적인 제한을 가한다는 것입니다.
다음을 수행하지 않습니다:
- 트리에서 "up" 참조를 허용(자식은 부모에 대한 포인터를 가질 수 없다.)
- 트리에 있는 데이터 제거(자식은 부모가 아닌 자식에게서만 정보를 읽는다).
이러한 제한으로 우리는 후속 배치를 위해 조각을 재사용할 수 있습니다.이런 제약이 없다면 우리는 종종 트리 전체를 재생시킬 필요가 있을 것입다. 그것은 비용이 많이 듭니다.
대부분의 레이아웃은 일반적으로 증분 업데이트로, 예를 들어 사용자가 요소를 클릭할 때 UI의 일부분을 업데이트하는 웹 앱입니다.이상적으로 레이아웃은 화면상에서 실제로 변경된 것에 비례하여 작동해야 합니다다.우리는 가능한 한 이전 나무의 많은 부분을 재사용함으로써 이것을 달성할 수 있습니다.이것은 (일반적으로) 나무의 척추만 재건하면 된다는 것을 의미합니다.
앞으로 이 불변의 디자인은 (다른 실에 대한 후속 단계를 수행하기 위해) 필요할 경우 스레드 경계를 넘어 불변의 단편 트리를 통과시키거나, 원활한 배치 애니메이션을 위해 복수의 트리를 생성하거나, 병렬적인 투기적 레이아웃을 수행하는 것과 같은 흥미로운 일들을 할 수 있게 해 줄 것입니다.또한 멀티 스레딩 레이아웃 자체의 가능성을 제공합니다.
인라인 조각 항목
인라인 콘텐츠(주로 텍스트 스타일)는 약간 다른 표현을 사용합니다.박스와 포인터가 있는 트리 구조보다는 나무를 대표하는 플랫 리스트로 인라인 콘텐츠를 표현합니다.주요 이점은 인라인에 대한 플랫 리스트 표현이 빠르고, 인라인 데이터 구조를 검사하거나 쿼리하는 데 유용하며, 메모리가 효율적이라는 것이다.텍스트 렌더링은 매우 복잡하고, 고도로 최적화되지 않는 한 파이프라인의 가장 느린 부분이 될 수 있기 때문에 웹 렌더링 성능에 매우 중요합니다.
흥미로운 것은 이것은 처음에 텍스트 편집기와 유사한 방식으로 만들어졌기 때문에 Internet Explorer가 이전에 그것의 DOM을 표현했던 방식과 매우 유사합니다.
플랫 목록은 각 인라인 형식 컨텍스트에 대해 해당 인라인 레이아웃 하위 트리의 깊이 우선 검색 순서에 따라 작성됩니다.목록의 각 항목은 (개체, 하위 수)의 튜플이다.예를 들어, 다음 DOM을 고려하십시오.
(참고:width속성은 0으로 설정하여 선이 "Hi"와 "there." 사이를 감싼다.) 이 상황에 대한 인라인 형식 컨텍스트를 트리로 나타내면 다음과 같이 보인다.
이 플랫 리스트는 다음과 같다.
- (Line box, 2)
- (Box <span>, 1)
- (Text "Hi", 0)
- (Line box, 3)
- (Box <b>, 1)
- (Text "there", 0)
- (Text ".", 0)
accessibilityAPI와 geometryAPI(예: getClientRects)와 같은 데이터 구조의 많은 소비자가 있습니다. 각각 요구 사항이 다릅니다.이러한 구성 요소는 편의 커서를 통해 플랫 데이터 구조에 액세스합니다.
커서에 다음과 같은 API가 있습니다. MoveToNext,MoveToNextLine,CursorForChildren.
이 커서 표현은 텍스트 내용에 대해 다음과 같은 여러 가지 이유로 매우 강력합니다.
- 깊이 우선 검색 순서에서 반복하는 것은 매우 빠릅니다. 이것은 캐럿 움직임과 비슷하기 때문에 매우 자주 사용됩니다.평면 목록이기 때문에 깊이 우선 검색은 배열 오프셋만 증가시켜 빠른 반복과 메모리 인접성을 제공합니다.
- 예를 들어 선과 인라인 박스의 배경을 그릴 때 필요한 너비 우선 검색 기능을 제공합니다.
- 하위 항목 수를 알면 다음 형제 항목으로 빠르게 이동(배열 오프셋만 해당 수로 증가)
속성 트리
아시다시피 DOM은 요소(와 텍스트 노드)의 트리로, CSS는 요소에 다양한 스타일을 적용할 수 있습니다.
이것들은 대부분 네 가지 효과로 나옵니다.
- Layout: 레이아웃 제약 알고리즘에 대한 입력.
- Paint: 원소를 페인트칠하고 래스터를 칠하는 방법(하지만 그 후손은 제외).
- Visual: 변환, 필터 및 클리핑과 같은 DOM 하위 트리에 적용되는 래스터/드로잉 효과.
- Scrolloing: 축 정렬 및 원형 코너 클리핑 및 포함된 하위 트리의 스크롤.
속성 트리는 시각적 효과와 스크롤 효과가 DOM 요소에 어떻게 적용되는지를 설명하는 데이터 구조입니다. 그들은 다음과 같은 질문에 대답할 수 있는 수단을 제공합니다: 화면과 관련하여 주어진 DOM 요소는 레이아웃 크기와 위치에 있는가?시각 효과와 스크롤 효과를 적용하기 위해 어떤 GPU 작동 순서를 사용해야 하는가?
웹에 대한 시각적 효과와 스크롤적 효과는 그들의 전성기에 있어서 매우 복잡합니다. 그러므로 속성 트리가 하는 가장 중요한 일은 그 복잡성을 그들의 구조와 의미를 정확하게 나타내는 단일 데이터 구조로 변환하는 동시에 DOM과 CSS의 나머지 복잡성을 제거하는 것입니다.이를 통해 훨씬 더 자신 있게 컴포지팅과 스크롤을 위한 알고리즘을 구현할 수 있습니다.
특히:
- 잠재적으로 오류가 발생하기 쉬운 기하학적 구조와 다른 계산은 한 곳에 집중될 수 있습니다.
- 속성 트리를 만들고 업데이트하는 복잡성은 하나의 렌더링 파이프라인 단계로 분리됩니다.
- 속성 트리를 풀 DOM 상태보다 다른 스레드 및 프로세스로 보내는 것이 훨씬 쉽고 빠르기 때문에 많은 사용 사례에 사용할 수 있습니다.
- 사용 사례가 많을수록 서로의 캐시를 재사용할 수 있기 때문에 위에 구축된 지오메트리 캐싱으로부터 더 많은 이득을 얻을 수 있습니다.
렌더링NG는 속성 트리를 다음과 같은 다양한 용도로 사용합니다.
- 합성물을 페인트에서 분리하고, 합성물을 메인 쓰레드에서 분리합니다.
- 최적의 합성/그리기 전략 결정
- IntersectionObserver 지오메트리를 측정.
- 오프스크린 요소 및 GPU 텍스처 타일에 대한 작업 방지.
- 페인트 및 래스터를 효율적이고 정확하게 무효화
- 핵심 웹 바이탈의 레이아웃 이동 및 최대 내용물 도장 측정.
모든 웹 문서에는 변환, 클립, 효과, 스크롤 등 4개의 개별 속성 트리가 있습니다. (*) 변환 트리는 CSS 변환 및 스크롤을 나타냅니다. (스크롤 변환은 2D 변환 매트릭스로 표시됨)클립 트리는 오버플로 클립을 나타냅니다. 효과 트리는 불투명도, 필터, 마스크, 혼합 모드 및 클립 경로와 같은 다른 종류의 클립 등 다른 모든 시각 효과를 나타냅니다. 스크롤 트리는 스크롤이 체인으로 연결된 방식과 같이 스크롤에 대한 정보를 나타내며, 합성기 쓰레드에 스크롤을 수행해야 합니다. 속성 트리의 각 노드는 DOM 요소에 의해 적용되는 스크롤 또는 시각 효과를 나타냅니다.다중 효과가 있는 경우, 각 트리에 동일한 요소에 대해 둘 이상의 속성 트리 노드가 있을 수 있습니다.
각 트리의 위상은 DOM의 희박한 표현과 같습니다. 예를 들어 오버플로 클립이 있는 DOM 요소가 3개 있는 경우 클립 트리 노드가 3개 있고 클립 트리의 구조는 오버플로 클립 사이의 포함 블록 관계를 따릅니다.트리 사이에도 연결이 있습니다.이 링크는 노드의 상대적인 DOM 계층 구조, 즉 애플리케이션의 순서를 나타냅니다. 예를 들어, DOM 요소의 변환이 필터가 있는 다른 DOM 요소 아래에 있으면 당연히 변환이 필터 앞에 적용됩니다.
각 DOM 요소에는 속성 트리 상태가 있으며, 속성 트리 상태는 해당 요소에 적용되는 가장 가까운 상위 클립, 변환 및 효과 트리 노드를 나타내는 4-투플(변환, 클립, 효과, 스크롤)이다.이것은 매우 편리합니다. 왜냐하면 우리는 이 정보를 가지고 그 요소에 적용되는 클립, 변환 및 효과의 목록과 그 순서를 정확히 알고 있기 때문입니다.이것은 스크린에 그것이 어디에 있는지 그리고 그것을 어떻게 그리는지를 우리에게 알려줍니다.
(*) 스크롤은 포함된 하위 트리에만 적용되므로 트리가 4개 있습니다. 요소는 스크롤할 때 스크롤러에 의해 포함되며, 스크롤 요소가 포함된 블록체인에 있지 않은 상황에서 'position:absolute' 및 'position: fixed' 요소는 상위 스크롤 요소를 벗어나는 경우가 많습니다.
그러나 다른 모든 시각 효과는 전체 DOM 하위 트리에 적용됩니다. 이러한 불일치 때문에 속성 트리의 클리핑 및 스크롤 측면의 토폴로지가 시각 효과와 상당히 다른 경우도 있습니다. 대부분의 시각적 효과가 모든 후손(예)에 대해 포함하는 블록을 유도하는 것도 이 때문이다.속성 트리의 전체 구조는 매우 복잡하다. 이 주제에 대한 자세한 내용은 여기에서 긴 코드 설명을 참조하십시오.
예
(출처)
앞의 예(소개서의 예와는 약간 다른)의 경우, 생성된 속성 트리의 주요 요소는 다음과 같습니다.
비주얼 뷰포트를 나타내는 노드, 페인트 오프셋 및 분리 등 엔진 내부 성능 최적화에 사용되는 노드 등 이 다이어그램에서 누락한 몇 가지 복잡성이 더 있습니다.또한, 이 도표는 나무들 사이의 연관성을 나타내지 않습니다. 예를 들어, 3px 블러(burl)는#one rotate공간을 개조합니다
'Chrome' 카테고리의 다른 글
Inside look at modern web browser (part 1) (0) | 2022.11.02 |
---|---|
Key data structures and their roles in RenderingNG(한글)(2) (0) | 2022.04.20 |
Overview of the RenderingNG architecture (한글) (1) | 2021.12.15 |