브라우저 동작과정, 렌더링 엔진, 파싱

라용·2022년 9월 16일
0

정종윤님의 재그지그 기술블로그 내용을 요약 정리했습니다. 더 자세하고 친절한 설명은 원본 글을 참고하세요.

브라우저 동작과정 왜 알아야 할까?

프론트엔드 개발자는 브라우저 위에서 동작하는 어플리케이션을 만듭니다. 처음에는 내가 생각한 로직대로 동작하는 것을 목표로 하지만 코드가 많아지고 다양한 기능이 추가된다면 (웹 어플리케이션의 복잡도가 증가하면) 브라우저 단에서 최적화를 고민해야 합니다. 아래 내용은 브라우저 동작 원리 중 렌더 과정에 대한 내용입니다.

브라우저 컴포넌트

브라우저는 위 다이어그램과 같은 여러 단의 레이어로 이루어져 있습니다.

User Inferface - 사용자가 보게 되는 페이지를 포함한 모든 UI 를 의미
Browser engine - 사용자 인터페이스와 렌더링 엔진 사이 중재자 역할, 사용자가 새로고침을 누르면 이를 이해하고 새로고침 명령 수행
Rendering engine - html, css, javascript 를 파싱하고 그 결과물을 화면에 그림. 브라우저별로 사용하는 엔진은 다양함
Networking - http 나 https 같은 프로토콜로 외부 리소스 얻어옴, 서버 요청 보낼 때 사용하는 레이어
JavaScript Interpreter - js 를 해석하고 실행. 가장 유명한 엔진은 크롬에 탑재된 구글 V8
UI Backend - 얼럿 창처럼 브라우저 운영체제에 저장되어 있는 UI 를 처리
Data Persistence - 데이터를 로컬에 저장할 경우 사용. 쿠키, 로컬스토리지, 세션 스토리지 등등

각 레이어의 역할은 다양하지만 개중에 렌더링 엔진은 어플리케이션이 직접 동작하는 레이어이므로 잘 알아두면 좋습니다.

렌더링 엔진 동작과정

웹페이지에 접속하면 네트워크를 통해 해당 웹페이지의 html 문서를 가져오고, 렌더링 엔진이 위 다이어그램 과정을 거쳐 html 문서를 해석합니다. 브라우저 엔진마다 해석 방식이 조금씩 다를 수 있지만 크게 아래 네 단계로 이루어집니다.

파싱(Parsing)
렌더 트리(Render Tree) 구축
레이아웃(Layout) 또는 리플로우(Reflow)
페인트(Paint)

위 과정을 중요 렌더링 경로(Critical rendering path)라고 부르고, 각 단계에서 리소스를 로드하는 순서나 작성한 스크립트 내용에 따라 웹 페이지의 반응 속도가 달라질 수 있습니다. 프론트 엔드 개발자는 이 과정을 최적화해 렌더링 시간을 개선할 수 있습니다.

파싱(Parsing)

파싱은 입력받은 문자열이 정해진 어휘나 문법 규칙을 따르는지 확인합니다. 브라우저는 html, css, javascript 언어를 해석할 수 있는데 개중 javascript 는 별도 해석기가 해석하고 렌더링 엔진에서는 html 과 css 만 파싱합니다.

렌더링 엔진은 파싱 과정에서 토큰화된 코드를 구조화하는데, (

코드를 토큰화하면 이런 형태 ['<', 'div', '>']) 이렇게 토큰화 된 문자열을 이용해 파스 트리를 만듭니다. 파스 트리는 브라우저가 읽어야 할 html 코드를 트리 모양으로 구조화한 것입니다.

그리고 나서 브라우저 파스 트리를 이용해 DOM(Document Object Model) 트리를 만듭니다. 파스 트리는 토큰화된 문자열을 단순 구조화한 것이고 DOM 트리는 우리가 실제 상호작용 할 수 있는 html 엘리먼트로 이루어져 있습니다. 자바스크립트로 상호작용할 수 있는 부부은 DOM 트리입니다.

html 은 파싱 도중 외부 태그(

CSS 파싱

CSS 는 공식 명세가 있어 파싱과정이 html 에 비해 덜 복잡합니다. 보통 html 코드 내에 CSS 를 링크하는 코드가 삽입되어 있어서 html 을 파싱하는 도중에 CSS 파싱이 시작됩니다. 네트워크를 통해 먼저 받아온 코드부터 해석하는 html 파서와 달리 css 파서는 전체 파일을 다운받은 후에 파싱을 시작합니다. 이후 DOM 과 같은 CSSOM 이라는 트리를 구성합니다. (스타일, 규칙, 선택자 등 정보가 노드에 들어감)

렌더 트리

위에서 이야기한 DOM 트리가 구성되는 동안 브라우저는 렌더 트리를 구성합니다. 프레임 트리라고도 합니다. 렌더 트리는 화면에 나타나는 요소들을 결정하는 트리입니다. 렌더 트리는 DOM 트리와 CSSOM 트리를 조합해 만들어지고, 이 때 화면에 그려지지 않은 요소들은 트리에 나타나지 않습니다. (,

레이아웃 또는 리플로우

렌더 트리 구성이 끝나면 레이아웃 단계로 이어지는데 모질라에서는 이 과정을 리플로우라고 부릅니다. 이 단계에서는 렌더 트리에서 계산되지 않았던 노드들의 크기와 위치, 레이어 간 순서등을 계산하여 좌표에 나타내 줍니다.

레이아웃은 계산 범위에 따라 전역적 레이아웃과 증분적 레이아웃이 있습니다. 전역적 레이아웃은 화면 전체의 레이아웃을 계산하는 것이고, 증분적 레이아웃은 레이아웃 과정에서 렌더 트리를 재귀적으로 탐색하다 레이아웃 변경이 발생하는 엘리먼트를 만나면 그 계산을 즉시 수행하지 않고 이후 비동기로 일괄 작업합니다. 이를 통해 연산의 횟수와 범위를 줄일 수 있습니다.

복잡한 레이아웃의 경우 브라우저 단의 최적화로 충분하지 않으므로 개발자 역시 레이아웃 과정의 연산을 최소화 하는 게 좋습니다. 때문에 브라우저처럼 행동하는 것이 필요합니다. DOM 레이아웃 관련 값을 직접 조작한다면 그런 구문들을 최대한 묶어야 합니다.

페인트

마지막 단계인 페인트는 레이아웃 단계를 통해 화면에 배치된 엘리먼트에 색을 입히고 레이어 위치를 결정합니다. 이 과정 역시 루트 오브젝트로부터 재귀적으로 실행되고, 전역적 증분적 페인팅이 있습니다. 블록 단위의 페인팅 순서는 CSS 페인팅 명세에 나와 있습니다.

가상 DOM

가상 DOM 은 실제로 렌더링되지 않았지만, 실제 DOM 구조를 반영한 상태로 메모리에 존재합니다. 메모리 상에 있지만 화면에 그려야할 필요는 없기 때문에 실제 DOM 보다 연산 비용이 적습니다.

profile
Today I Learned

0개의 댓글