All Articles

[Frontend] 브라우저 렌더링 엔진이 어떻게 컨텐츠를 그려내는가

렌더링 엔진

  • Html/ Xml와 이미지 같은 요청한 컨텐츠를 브라우저 화면에 표시한다.
  • -

Render Tree 생성

HTML Parsing

  • HTML텍스트를 읽어 AST를 형성 -> 파싱
  • 어휘분석 텍스트를 읽어 토큰을 형성한다. (타입, 값)으로 형성하여 모든 읽어들인 텍스트를 유효하게 구성된 집합으로 만든다. 공백/ 줄바꿈은 제거한다.
  • 구문분석 위에서 토큰화한 데이터를 해당 언어의 구문 규칙에 따라 분해하는 과정이다. (시작태그. 종료태그, 속성이름, 속성 값)
  • 구문분석 데이터 파싱 구문 규칙에 따라 생성한 데이터를 조합해 파싱 트리html-(DOM) css-(CSSOM)를 생성한다. <반복> 어휘분석으로 얻어진 토큰을 구문 규칙에 따라 분해한 데이터를 생성하고 해당 데이터에 해당하는 노드는 파싱트리(DOM)에 추가된다.
  • 파싱트리 콘텐츠트리 내부에서 DOM 요소와 속성 노드의 트리로서, 출력 트리가 된다. HTML 문서의 객체로서 외부 컨텐츠를 요청하는 (예 자바스크립트, CSS)와 같은 요소와 연결되는 지점이다. 브라우저와 자바스크립트가 이해 가능한 트리구조의 객체이다.
  • 렌더트리 {display:none}의 속성이 적용된 노드는 렌더트리에 존재하지 않는다.
  • attachment: 렌더 트리를 생성하기 위해 DOM 노드와 시각 정보(CSSOM)을 연결하는 과정
  • 렌더링 엔진이 HTML을 파싱하는 과정은 해당 파일을 아래로 읽어나가며 순서대로 진행된다. 읽은 텍스트 토큰화 -> 구문분석하여 토큰을 분해 -> 구문 규칙에 따라 생성된 데이터로 파싱트리 생성 -> 렌더 트리에 배치(reflow) -> 그리기(repaint)

Reflow Repaint

reflow (렌더트리 배치)

  • CSS Box모델 : 문서 트리의 요소들이 가지고있는 스타일이 적용된 사각형 박스. 예를들어, div>span 여러 다양한 형태의 요소들이 있다. 여기서 상위 div는 span요소에 따라 최종적으로 판단됨 상위는 자식엘리먼트의 영향을 받음 div 형제들은 자기 형 노드의 영향을 받음 어떻게 repaint를 적게할것인가? 변경사항을 한쪽으로 몰아준다. 변경이 자주일어날 곳은 브라우저에서 디바운싱한다. 유발인자들만 한 함수에 작성해준다.

아래와 같은경우 좋지 못한 예임으로 속성 변화는 한곳이 몰아주는것이 맞다

div.style.width = '96px';
let c = a + b;
div.style.height = '48px'

position이 absolute인경우는 자식에만 영향. 전체 리플로우를 막울수 있다.

div.getBoundingClientRect()
div.offsetWidth
div.getComputedStyle();

호출되는 수만큼 리플로우가 일어난다. 필요한 순간 몰아서 계산해야한다. 정확한 정보를 찾기위함으로, 다시 그리는 것이아니라 repaint가 일어나지 않는다.

-> reflow는 복싱에서 쨉과 같다

repaint

렌더 트리가 탐색되고 호출된다. 실제 요소들이 픽셀로 그려지도록 변환하는 과정이다.

  • 변경된 렌더러는 화면 위에 그려진 사각형(Box model)을 무효화하고, paint(이벤트)를 실행시킨다.
  • 크롬의 경우 렌더러가 별도로 처리해야 하는 과정이라 복잡하게 이루어진다.
  • 변경된 부분 몇 개의 영역을 합쳐서 효과적으로 OS는 처리하며, 크롬 또한 해당 동작을 모방한다.
  • 해당 이벤트는 변화가 이루어지는 부분을 합치기 때문에 렌더 상위로 올라가 변화를 준다.
  • 렌더 트리는 유효한 렌더러까지 올라가서 변화를 주며 탐색을 이어나가고 그 부분까지 자식과 다시 그려진다.

엘리먼트가 변할 때 마다 새로 그려줘야한다 값이 더 비싸다.(실행비용이 비쌈) 예를들면 캔버스위에 svg, html 에니메이션!! 또는 fixed 한 position의 요소가 opacity를 가져서 겹친 앨리먼트를 또한 그려줘야 하는경우.. 스타일이 복잡하면 회피방법이 거의 없다. 반면에 리플로우 관련 성능 최적화 방법이 많다.

-> repaint는 복싱으로 따지면 훅날리는거..

이벤트 순환

  1. 브라우저의 주요 스레드는 이벤트 순환으로 처리하기 위해 무한 순환한다. repaint/reflow 이벤트 처럼 지속적으로 변화가 있는 경우를 위해 대기를 하다 이벤트를 처리한다. while문을 사용하여 처리 - 파이어폭스

DOM 위치를 결정하기

  • normal : 렌더 트리에 구성된 객체의 순서에 따라 해당 DOM의 위치가 적용된다. Box model 유형과 면적에 따른다.
  • Float : 왼쪽에서 오른쪽 방향으로 배치된다
  • Absolute : 객체는 DOM트리 자리와 다른 렌더 트리에 놓인다. ( reflow 성능 최적화에 유용)

렌더링 엔진의 스레드

  1. 탭 프로세스의 스레드는 단일 스레드로 동작
  2. 통신의 경우 병렬 스레드에 의해 진행될 수 있다.

레퍼런스 브라우저는 어떻게 동작하는가 Astexplorer SuperTinyCompiler