본문 바로가기
FrontEnd/React.js

[React & 브라우저] 브라우저의 동작 과정 (feat. 렌더링 실행)

by 위그든씨 2022. 12. 23.

프론트엔드(FE) 개발자가 브라우저(Br) 동작 원리를 알아야 하는 이유

  • FE에게 Br는 거의 모든 것.
  • Br를 통해 개발, Br를 통해 테스트 및 배포 진행, 사용자들은 Br를 통해 웹에 접속
  • FE는 Br의 모든 것이 아닌 HTML, CSS, JS가 의도대로 동작하는지 확인해도 큰 문제x
  • 하지만 기능이 많고 다양한 동작이 발생한다면 최적화가 필요해짐
  • Br의 최적화를 위해선 결국 Br의 동작 원리를 이해하는 것에서부터 시작
  • 해당 포스트에서 알아볼 것 => Br의 렌더 과정 & 원리 ( 아래는 선 4줄 요약 )
    1. HTML로부터 DOM 트리를, CSS로부터 CSSOM 트리를 빌드
    2. DOM & CSSOM을 결합하여 렌더 트리를 형성
    3. 렌더 트리에서 레이아웃을 실행 => 각 노드의 기학학적 형태를 계산
    4. 개별 노드를 화면에 페인트

브라우저 컴포넌트

브라우저를 구성하는 레이어들간의 관계

  1. 사용자 인터페이스(UI) 
    • Br에서 볼 수 있는 거의 모든 것. 
    • 요청한 페이지를 보여주는 창 외의 모든 UI
    • eg) 주소창, 뒤로가기, 앞으로가기, 새로고침,북마크, 환경설정
  2. 브라우저 엔진
    • UI 와 렌더링 엔진 사이에서의 중재자 역할 
    • eg) UI에 있는 새로고침을 누르면, 브라우저 엔진은 이를 이해하고 새로고침 명령을 수행함
  3. 렌더링 엔진 ( 이 글에서 우리가 알아볼 것)
    • HTML & CSS & JS를 파싱하고, 그 결과물을 페이지에 그려내는 역할
    • 브라우저마다 다양한 엔진 존재
    • Chrome, Opera, Edge: Blink
    • Firefox: Gecko
    • Safari: Webkit
  4. 네트워크:
    • HTTP(S) 프로토콜을 이용해 외부의 리소스를 얻어오고, 서버에 요청을 보낼때 사용
  5. JS 인터프리터
    • JS 해석 및 실행
    • eg) Chrome: 구글의 V8
  6. UI 백앤드
    • 브라우저가 동작하고 있는 OS의 인터페이스를 따르는 UI들을 처리
    • eg) 얼럿 || 셀렉트 박스가 OS별로 다르게 동작
  7. 자료 저장소
    • 브라우저에서의 데이터를 로컬에 저장하기 위한 레이어
    • eg) 쿠키, 로컬, 세션, indexedDB, 웹SQL, 파일 시스템 등

 

렌더링 엔진의 동작 과정

선요약 4줄에 해당하는 그림

  • 유저가 웹에 접속하면, 네트워크를 통해 HTML 문서를 얻어 올 수 있다.
  • 그러면 렌더링 엔진은 HTML 문서를 해석함. (브라우저 엔진마다 방식 조금씩 다르지만 큰 틀은 같다)
    1. 파싱
    2. 렌더 트리 구축
    3. 레이아웃 || 리플로우 
    4. 페인트
  • 이러한 과정을 일컫어 중요 렌더링 경로 라고 부름. (초당 60회 정도의 주기로 계산, 3-4번이 비용 가장 많이 듬)
  • 웹 페이지의 반응 속도는 각 단계에서 리소스를 로드하는 순서스크립트 내용에 따라 차이가 생김
    • 위의 과정들을 최적화 시키는 것이 곧 렌더링 시간을 개선시키는 것

중요 렌더링 경로의 각 단계별 정리

1. 파싱

  • 파싱이란 토큰화된 코드를 구조화하는 과정 (cf 토큰화란 최소 단위로 코드를 쪼개는 것을 의미)
  • eg) <div></div> 라는 코드를 토큰화하면, ['<', 'div ', '>','<', 'div ', '/', '>' ] 처럼 나타냄
  • 파싱과정이란 입력받은 문자열이 정해진 문법들을 모두 따르나 확인하는 과정
  • 파서(parser)는 이러한 파싱 과정을 전문적으로 해주는 부분
  • HTML & CSS는 렌더링 엔진이 해석 & JS는 JS해서기라는 별도 레이어에서 해석
    • 렌더링 엔진에서는 HTML과 CSS를 파싱
    • 아래는 HTML 파싱 흐름도

파싱 흐름도

HTML 파싱

  1. 브라우저는 토큰화된 HTML의 문자열들을 이용해 파스 트리를 생성
    • 파스 트리: 브라우저가 읽어야 할 HTML 코드를 트리 모양으로 구조화한 것
  2. 이후 브라우저는 파스 트리를 통해 DOM(Document Object Model) 트리를 만듬.
    • 파스트리 : 토큰화된 문자열을 단순하게 구조화 한것
    • DOM 트리 : 실제로 상호 작용 할 수 있는 HTML 엘리먼트로 이루어진 트리 (JS로 상호작용하는 트리)
  3. HTML 파서의 특징
    1. 오류에 너그러운 속성 ( forgiving nature) - HTML 파싱도중 에러 발생시, 브라우저가 자체적으로 복구 시도
    2. 파싱 과정이 중단 될 수 있음. - <script>, <link> 같은 외부 태그를 만나게 되면 HTML 파싱 즉시 중단 후 태그 해석
      • 이러한 이슈를 해결하기 위해 Async와 Defer 속성이라는 옵션 제공됨
    3. 재시작 (ReEntrant) -
      • 어떠한 요인으로 파싱이 중단되는 듯 방해가 생기면 DOM의 변화가 생길 수 있음
      • 이러한 경우 HTML은 처음부터 다시 파싱 과정을 거침.  -> 파싱 시간 증가 요인

 

CSS 파싱

CSSOM

  1. CSS 파싱은 공식적인 명세가 있기에 HTML에 비해 복잡x
  2. 보통 CSS를 링크하는 코드가 HTML 코드 내에 삽입되어 있어서 HTML파싱 도중에 CSS파싱 시작됨
  3. 네트워크를 통해 먼저 받아온 코드부터 해석하는 HTML파서와는 달리. 전체 파일을 다운로드 한 후 파싱 시작
  4. CSS 파싱 과정이 끝나면, 코드에서 명세한 내용과 순서를 바탕으로 CSSOM 트리를 구조화 함(CSS Object Model)
    • 해당 트리에는 스타일, 규칙, 선택자 등의 정보가 노드에 들어가있음

2. 렌더 트리

  • DOM 트리가 구성되는 동안 브라우저는 렌더 트리(프레임 트리) 를 구성하기 시작 
  • 렌더 트리는 화면에 나타나는 요소들을 결정하는 트리 -> 보여질 요소들, 적용될 스타일, 나타낼 순서 명세화
  • 렌더 트리 = DOM트리 + CSSOM 트리 -> <head>,<script>, display:none 등 화면에 보이지 않는 요소들은 렌더 트리x 
    • 따라서 렌더 트리는 DOM+CSSOM 와 정확하게 1:1 매칭 x 

3. 레이아웃 || 리플로우

  • 렌더 트리 구성이 끝나면 레이아웃 단계 시작 ( 모질라에서는 reflow 라고 부름 ) 
  • 이 단계에서는 렌더 트리에서 계산되지 않았던 노드들의 크기, 레이어간 순서 같은 정보를 계산하여 좌표에 나타냄
  • 이 과정은 HTML의 root Obj 로부터 재귀적으로 실행됨 
  • 계산 범위에 따라 Global(전역적) Layout , Incremental(증분적) Layout 으로 구분됨
    1. 전역적 레이아웃
      • 화면 전체의 레이아웃을 계산하는 것.
      • 폰트 및 사이즈, 뷰포트의 사이즈 변경 등 새롭게 적용되는 것이 있다면 전체 레이아웃 다시 계산
      • 전역적 레이아웃은 모든 렌더 트리에 대해 기학학적 계산을 수행하므로 속도 저하 요인이 됨(브라우저는 최적화 로직 탑재 되어 있음) - eg) Dirty bit system - 특정 부분만 다시 계산하여 리소스 낭비 줄임
    2. 증분적 레이아웃
      • 위에서 말한 더티 비트 시스템을 활용한 것.
      • 렌더 트리를 재귀적으로 탐색하다가, 레이아웃 변경 요소를 만나면 스케줄러를 통해 비동기로 일괄 작업
    3. 이러한 브라우저의 최적화만으로는 복잡한 레이아웃을 감당 못하기 때문에 개발자가 신경써야함
      • DOM의 레이아웃과 관련 값에 변화를 주는 JS 코드 작성시에는 최대한 묶어주기

4. 페인트

  • 말 그대로 레이아웃 단계를 통해 화면에 배치된 요소들에게 색을 입히고 레이어의 위치를 결정하는 단계
  • root Obj로부터 재귀적으로 실행됨
  • 전역적&증분적 페인팅으로 나뉨
  • 스타일이 복잡할수록 페인팅 시간 늘어남

 

가상 DOM

  • 가상 DOM이란?
    • React & Vue 를 써봤다면 익숙한 용어
    • 가상 DOM은 실제로 렌더링 되지 않지만, 실제 DOM 구조를 반영한 상태로 메모리에 있는 가상의 DOM이다
  • 기존 DOM의 문제점
    • 중요 렌더링 경로 중 가장 많은 비용이 드는 것은 레이아웃&페인팅 단계이므로 이 연산을 최소화 하는 것이 성능 최적화
    • JS를 이용해 DOM을 직접 조회하면, 변경 사항 있을때마다 윗 단계들을 다시 초래함.
  • 가상 DOM으로 이슈 해결
    • 가상 DOM은 실제 화면에 그릴 필요가 없어서 실제 DOM 보다는 연산 비용 적음
    • 변경 사항들을 한번에 묶어서 실제 DOM에 반영
    • 레이아웃&페인트 단계에서 한번에 변경되는 점은 많아지겠지만 연산은 최소화됨.
    • 가상 DOM의 자동화로 관리 포인트를 줄여줌. (React, Vue ) 

 

https://wormwlrm.github.io/2021/03/27/How-browsers-work.html 님의 글을 거의 복붙 수준으로 작성