본문 바로가기

Develop/Frontend 가이드

[FE] 브라우저 렌더링 Browser rendering - 1단계 파싱 'parse'

반응형

브라우저 렌더링
https://docs.google.com/presentation/d/1boPxbgNrTU0ddsc144rcXayGA_WF53k96imRH8Mp34Y

브라우저 렌더링 Browser rendering

브라우저는 'content (콘텐츠)' 를 'rendering (렌더링)' 해서 'pixel image(픽셀 이미지)' 즉 화면을 만듭니다.

  1. 브라우저 렌더링 Browser rendering - 0단계 소개
  2. 브라우저 렌더링 Browser rendering - 1단계 파싱 'parse'
  3. 브라우저 렌더링 Browser rendering - 2단계 스타일링 'style'
  4. 브라우저 렌더링 Browser rendering - 3단계 레이아웃 'layout'
  5. 브라우저 렌더링 Browser rendering - 4단계 페인팅 'paint'
  6. 브라우저 렌더링 Browser rendering - 5단계 변경 'change'

렌더링 파이프라인 Rendering pipeline

Blink 렌더링 파이프라인
Blink 렌더링 파이프라인

1단계 파싱 'parse'

렌더링 엔진이 콘텐츠를 입력받고 제일 먼저 하는 작업은 해석할 수 있는 형태로 만드는 작업입니다. HTML 은 파이프라인에 입력될 때 단순한 텍스트로 입력됩니다. 렌더링 엔진은 입력된 HTML 텍스트를 조작할 수 있는 객체로 변환하는데, 이렇게 텍스트를 객체로 변환하는 과정을 파싱 이라고 합니다.

Blink 는 HTML 을 객체로 파싱할 때 HTMLDocumentParser 로 텍스트를 읽으면서 HTMLTreeBuilderDocument Object Model (DOM) 트리를 하나씩 완성합니다. 이 'Document Object Model (DOM)' 이라는게 굉장히 중요한 모델인데, 렌더링하는 모든 과정의 기준이 되는 모델이면서, DOM API 로 노출되어 JavaScript 가 콘텐츠를 조작할 때 사용하는 모델입니다. DOM 을 설명하자면 너무 길어지니 MDN 글을 참고하여 주시길 바라고, DOM 을 '렌더링하는데 기준이 되는 모델이며 트리 구조로 되어 있다.' 정도로만 이해하시면 됩니다. DOM 을 그림으로 표현하자면 아래와 같이 생겼습니다.

Document Object Model (DOM)
Document Object Model (DOM)

실제로 어떻게 동작하는지 가늠할 수 있도록 소스코드 일부를 아래에 첨부합니다.

HTMLDocumentParser

// third_party/blink/renderer/core/html/parser/html_document_parser.h
class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser,
                                       private HTMLParserScriptRunnerHost {
public:
    // HTMLTokenizer 로 텍스트로 구성된 HTML 을 각 요소 별로 토큰화하여 의미있는 단위로 처리할 수 있도록 보조합니다.
     HTMLTokenizer* Tokenizer() const { return tokenizer_.get(); }

protected:
    // 의미있는 단위로 토큰화된 HTML 을 적절히 처리해서 HTMLTreeBuilder 로 DOM Tree 에 추가합니다.
    HTMLTreeBuilder* TreeBuilder() const { return tree_builder_.Get(); }

    NextTokenStatus CanTakeNextToken();
    bool PumpTokenizer();
    void ConstructTreeFromHTMLToken();
}

// third_party/blink/renderer/core/html/parser/html_document_parser.cc
void HTMLDocumentParser::ConstructTreeFromHTMLToken() {
  AtomicHTMLToken atomic_token(Token());
  // HTMLTreeBuilder 에게 HTML 토큰을 제공하고 DOM Tree 를 구성할 수 있도록 합니다.
  tree_builder_->ConstructTree(&atomic_token);
}

HTMLTreeBuilder

// third_party/blink/renderer/core/html/parser/html_tree_builder.h
class HTMLTreeBuilder final : public GarbageCollected<HTMLTreeBuilder> {
    // ...
    public:
        // HTMLDocumentParser 가 DOM Tree 를 만들 때 사용하는 함수입니다.
        void ConstructTree(AtomicHTMLToken*);
        // HTML 토큰을 타입에 따라 처리하도록 지시하는 함수입니다.
         void ProcessToken(AtomicHTMLToken*);
   // ...
}

// third_party/blink/renderer/core/html/parser/html_tree_builder.cc
void HTMLTreeBuilder::ConstructTree(AtomicHTMLToken* token) {

    // ...
      else
        // 토큰을 처리하도록 지시합니다.
        ProcessToken(token);
   // ...
}

void HTMLTreeBuilder::ProcessToken(AtomicHTMLToken* token) {
  // ...
  // HTML 토큰 타입에 따라 다르게 처리합니다.
  switch (token->GetType()) {
    case HTMLToken::kUninitialized:
    case HTMLToken::kCharacter:
      NOTREACHED();
      break;
    case HTMLToken::DOCTYPE:
      ProcessDoctypeToken(token);
      break;
    case HTMLToken::kStartTag:
      ProcessStartTag(token);
      break;
    case HTMLToken::kEndTag:
      ProcessEndTag(token);
      break;
    case HTMLToken::kComment:
      ProcessComment(token);
      break;
    case HTMLToken::kEndOfFile:
      ProcessEndOfFile(token);
      break;
  }
  // ...
}

참고

Life of a pixel (Chrome University 2019)
Life of a pixel
How Blink works

반응형