<aside> 💡

성능을 위해서 Javascript로 동적인 화면을 그릴 때 Reflow 보다는 Repaint가 되게 하자

</aside>

1. 브라우저 렌더링 방식 (렌더링 엔진의 동작 원리)


1-1) Render 순서

스크린샷 2022-04-01 오후 9.11.02.png

  1. URI에 접속

  2. 브라우저는 서버로부터 HTML 문서를 모두 전달 받아 읽는다 (브라우저가 아는 언어는 HTML,CSS,JS,Web Assembly 뿐이며 php, jsp, asp 같은 서버 템플릿 언어도 기본적으로는 HTML로 내려주게 되어 있다.)

    1. <link> : 외부 리소스와 연결시켜주는 태그, 보통 CSS파일에서 많이 쓰며 해당 태그도 만나면 연결된 주소를 통해 외부 리소스를 다운 받음
      1. <link rel="stylesheet">는 HTML 파싱을 멈추고 CSS를 다운로드·파싱한 뒤에야 렌더 트리를 계속 만든다. ⇒ 단순히 “연결”만 하는 게 아니라 렌더 블로킹(render-blocking) 리소스
    2. <script> : JS 파일과 연결시켜주는 태그, 해당 태그를 만나면 잠시 렌더링을 멈추고 다운로드를 받기 시작함(JS 파일이 크면 렌더링이 느려지는 이유이다)
      1. <script>도 기본적으로 파싱을 멈추고 다운로드·실행까지 마친 뒤에야 DOM 파싱을 재개한다. 다만 asyncdefer 속성을 쓰면 동작 방식이 달라진다.
  3. 렌더링 엔진은 전달받은 HTML 문서를 파싱하여 DOM 객체 모델을 만든다. (파싱 : 브라우저의 렌더링 엔진이 HTML 파일을 위에서 아래로 한 줄씩 읽어 내려가는 것) HTML 문서 ⇒ DOM 객체 모델

  4. 다운 받았던 외부 CSS 파일과 함께 포함된 스타일 요소를 파싱해 CSSOM 객체 모델을 만듬

    1. HTML 문서 + CSS파일 ⇒ CSSOM 객체 모델
    2. HTML 파싱과 CSS 파싱은 거의 병렬로 일어나며, CSS 로드가 늦으면 렌더 트리 생성이 지연된다. 따라서 리소스 로딩 최적화가 매우 중요하다.
  5. 3에서 만든 DOM 트리와 4에서 만든 CSSOM 트리를 합쳐 렌더 트리를 구축함 모든 HTML은 기본적으로 다 스타일을 가지고 있기 때문에 CSS가 없는 HTML은 없음 반드시 둘이 결합 되어야지 렌더 트리가 생성이 됨 (display:none 스타일을 갖는 DOM 객체는 렌더트리에서 탈락)

  6. Reflow (Layout) 렌더 트리의 각 노드에 대해서 화면 상에서 어디에 배치할 지 결정함 (브라우저 화면 어디에 위치하는지, 크기는 얼마로 해야하는지 계산) ⇒ 화면에 배치하는 단계

    1. javascript로 화면 조작 시 Reflow(레이아웃이 바뀜) 발생
    2. Reflow로 위치가 바뀌면 다른 노드 위치도 다 바뀌기 때문에 이런 것들을 다 계산해야해서 성능을 잡아먹음
  7. Paint (Repaint)를 함 UI 백엔드에서 렌더 트리를 그리게 됨 ⇒ border 형태나 컬러 등을 적용 (색칠하기 놀이) 실질적으로 브라우저 화면을 그리는 과정, 여기까지 해야 유저의 눈에 보이게 됨

    1. javascript로 화면 조작 시 Repaint(페인트가 바뀜) 발생
    2. Reflow가 성능을 잡아먹기 때문에 Repaint 위주로 하는게 최적화이다.
  8. JS 실행 자바스크립트 파일 다운로드 후 V8 엔진(크롬)으로 실행하고,반복되는 코드는 JIT 컴파일러에 의해 컴파일 된다.