브라우저 렌더링 & React 렌더링

joseph·2024년 3월 22일
0

개념정리

목록 보기
14/16

웹 브라우저의 구조

User Interface → 웹 페이지를 제외하고 사용자와 상호작용하는 사용자 인터페이스

Browser Engine → 유저 인터페이스와 렌더링 엔진을 연결하는 브라우저 엔진

  • Rendering Engine → HTML, CSS를 파싱해 요청한 웹 페이지를 표시하는 렌더링 엔진
    • Networking → 네트워크 요청을 수행
    • Javascript Interpreter → 자바스크립트 코드를 실행하는 인터프리터
    • UI Backend → 기본적인 위젯을 그려줌

Data Persistence - localStorag, Cookie와 같이 보조 기억장치에 데이터를 저장

*브라우저별 렌더링 엔진

Chrome → Blink

Safari → Webkit

Firefox → Gecko

렌더링 엔진의 목표

  • HTML, CSS Javascrip, 이미지 등 웹 페이지에 포함된 모든 요소들을 화면에 보여줌
  • 업데이트가 필요할 때, 효율적으로 렌더링을 할 수 있도록 자료구조를 생성

Critical Rendering Path → 브라우저 렌더링의 핵심 과정

DOM Tree 생성 과정

  • 브라우저에 어떤 사이트의 주소를 입력하면 그 주소의 서버가 약속된 html파일을 브라우저로 8비트의 형태로 전송
  • 전송받은 byte데이터를 문자로 변환
  • 변환된 문자를 태그, 속성 텍스트 등의 토큰으로 분리한다. → 토큰화
  • 토큰화를 통해 노드 생성
    • 노드 : 돔 트리를 구성하는 한 단위
    • img, link : 해당 태그들 안에 명시되어 있는 리소스를 다운받는다
    • script : 해당 태그를 만나면 브라우저는 dom생성을 중단하고 해당 태그 안에 있는 JS를 해석
      <!DOCTYPE html> 
      <html lang="en">
      <head> // HTMLhead Element
          <meta charset="UTF-8" /> // 렌더와 관계 없으니 렌더트리에 포함X
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
          <link rel='stylesheet' href='style.css' />
      </head>
      <body>
          <div> // element node
            <p>지금은 공부시간 입니다</p> // text node
            <img src='study.jpg' alt='이미지' /> // Attribute node
          </div>
      </body>
      </html>
  • 노드들로 구성된 DOM tree 생성

CSSOM(CSS Object Model) Tree 생성 과정

→ DOM이 어떻게 화면에 표시될지 알려주는 역할

  • 마찬가지로 브라우저로 받은 8비트 byte데이터를 문자로 해석
  • 토근화 및 비교해서 노드 생성
  • 노드들이 모여서 CSSOM Tree생성

Layout

이렇게 생성된 DOM tree와 CSSOM tree를 합쳐서 Render Tree를 생성하는 단계

→ Render Tree : 화면에 표시되어야 할 모든 노드의 컨텐츠, 스타일 정보를 포함하는 트리

요소의 크기나 좌표와 같은 정보를 담고 있다

*display: none, meta는 렌더 트리에 요소가 포함되지 않는다.

Paint

렌더 트리를 따라 Layout 정보를 바탕으로 여러 레이아웃으로 나눈 다음 그 위에 텍스트, 색, 이미지, 보더 등 시각적인 이미지를 그리는 작업

Composite

페인트에서 만들어둔 여러 레이어들을 스크린에 픽셀로 표현, 나누어져있던 레이어들을 하나로 합성해서 페이지 완성

브라우저를 리렌더링 했을 때

Layout → Reflow

  • 요소의 위치, 크기가 변경되었을 때, 브라우저의 창의 크기가 바뀌었을 때 실행
  • position, left, top, right, bottom, width, height, margin, border, padding, display, float, overflow, font-family, font-size, text-align 등

Paint → Repaint

  • 텍스트 색상, 배경 이미지, 보더 등 시각적인 이미지가 변경되었을 때 실행
  • background, box-shadow, border-radius, border-style, color 등

*transform, opacity는 reflow, repaint 생략 → DOM tree를 변경하지 않도록 설계가 되었기 때문

브라우저가 리렌더링 될 때 항상 reflow와 repaint가 순차적으로 실행되는 것이 아니다. 레이아웃의 수치에 영향이 없을 경우 리플로우만 실행

React 렌더링

Render Phase

컴포넌트를 실행시키면 호출된 컴포넌트의 요소들을 React Element로 변환

05-49d2-a7d3-64b0ea94602f/d727f558-1425-42a6-b017-d711342dac62/Untitled.png)

  • jsx는 js가 아니기 때문에 Babel과 같은 컴파일러로 js로 컴파일
    • js로 변환될 때 React.createElement()함수로 오른쪽과 같은 자바스크립트 객체를 생성한다
      // 아래와 같은 컴포넌트가
      return <Component id='test' b="text">Test Component</Component>
      
      // createElement함수로 아래와 같이 호출되고
      return React.createElement(Component, {id: 'test', b:'text'}, "Test Component")
      
      // 아래와 같은 React Element 객체가 된다
      {
      	type: Component, 
      	props: {
      			id: 'test', 			
      			b: 'text',
      			children: {
      				"Test Component"
      			}
      		}
      }
    • type : DOM node의 태그 이름
    • props : jsx에 포함된 모든 속성
    • children : 하위 노드들

전체 컴포넌트 렌더 결과물로 React는 새로운 객체 트리(Virtual DOM)를 만들고 실제 DOM(Actual DOM)에 적용시켜야 할 모든 변경사항 목록을 Prev Virtual DOM과 비교하여 수집한다. 이때 diffing 알고리즘을 사용하는데, 이러한 과정을 Reconciliation이라 한다.

Commit Phase : Virtual DOM을 Actual DOM에 반영함

Actual DOM과 Virtual DOM의 변경사항을 감지해 변화가 있다면 Critical Rendering Path를 진행해 브라우저 랜더링 진행

업데이트 발생시 Render Phase를 처음부터 다시 실행 → 새로운 Virtual DOM생성

DOM수정을 최소화 하기 위해서

리액트를 각 컴포넌트를 재귀호출하여 렌더링을 진행한다. 각 컴포넌트마다 피버노드를 만든다. 피버 노드는 상태를 저장하는 공간

리렌더링 되는 조건

  • state가 변경되었을 때
  • 부모로 부터 받은 props가 바뀌었을 떄
  • 중앙 상태값(redux store, Mobx store, Recoil Atom)등이 바뀌었을 때

Diffing Algorithm
React가 두개의 트리를 비교할 때 두 엘리먼트의 root부터 비교하는데 이후 동작은 root 엘리먼트 타입에 따라 달라진다.

- 엘리먼트 타입이 다른 경우
이전 트리를 버리고 새로운 트리를 생성

- 엘리먼트 타입이 같은 경우
두 element의 속성을 비교해서 변경된 속성만 갱신

DOM 노드의 처리가 끝나면 해당 노드의 자식들을 재귀적으로 처리

// 해당 리스트에 요소를 추가할 때
<ul>
	<li>first</li>
	<li>second</li>
</ul>
// 아래와 같은 경우 문제 없음
<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
// 하지만 추가된 요소가 맨 앞으로 올 때, 고유한 key값을 부여해서 React는 기존 트리와 이후 트리의 자식 노드들이 일치하는지를 확인하고 새로운 노드를 앞에 추가해준다.
<ul>
  <li>third</li>
  <li>first</li>
  <li>second</li>
</ul>

https://www.youtube.com/watch?v=sJ14cWjrNis

https://www.youtube.com/watch?v=idgsruQl9f4

https://www.youtube.com/watch?v=N7qlk_GQRJU

https://s0ojin.tistory.com/m/72

https://narup.tistory.com/272

profile
내일도 모레도 글피도 엉금엉금

0개의 댓글