브라우저 주소창에 "naver.com"을 입력하면 어떤 과정이 일어날까?
단, 이 글에서 설명하는 브라우저란 파이어 폭스, 크롬, 사파리와 같은 오픈소스 브라우저를 말한다.
TL; DR
- 주소창에 url을 입력 후 Enter를 누르면, 서버에 요청이 전송된다. 해당 페이지에 존재하는 여러 자원(text, image 등)이 보내진다.
- 브라우저는 해당 자원이 담긴 html과 스타일이 담긴 css를 W3C 명세를 따라 해석한다. (렌더링 엔진이 이를 수행한다.)
- html 파서가 DOM 트리를 구성한다.
- CSS 파서가 CSSOM 트리를 구성한다.
- DOM과 CSSOM을 연결시켜 렌더 트리를 형성한다. 렌더 트리를 통해 문서가 시각적 요소를 포함한 형태로 구성된다.
- 화면에 배치를 시작하고, UI 백엔드가 노드를 돌며 형상을 그린다.
- 위의 과정은 전송을 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.
브라우저(Browser)
브라우저의 주요 기능
사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시한다.
자원
보통 HTML 문서이지만 PDF나 이미지 또는 다른 형태도 가능하다.
자원의 주소는 URI(Univorm Resource Identifier)에 의해 정해진다.
브라우저는 HTML과 CSS 명세에 따라 HTML 파일을 해석해서 표시한다.
여기서 말하는 "명세"는 웹 표준화 기구인 W3C(World Wide Web Consortium)에서 정한다.
일반적인 브라우저의 사용자 인터페이스
표준 명세는 없지만, 서로의 장점을 모방하면서 갖춰졌다.
- URI를 입력할 수 있는 주소 표시줄
- 이전 버튼, 다음 버튼
- 북마크
- 새로 고침 버튼, 로드 정지 버튼
- 홈 버튼
브라우저의 기본 구조
브라우저의 주요 구성요소
- 사용자 인터페이스(User Interface)
- 주소 표시줄, 이전 / 다음 버튼, 북마크 메뉴 등 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분
- 브라우저 엔진(Browser Engine)
- 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어
- 렌더링 엔진(Rendering Engine)
- 요청한 콘텐츠를 화면에 출력 (HTML, CSS, JavaScript를 파싱하고 그 결과를 바탕으로 화면에 출력)
- 통신(Networking)
- HTTP 요청과 같은 네트워크 호출에 사용된다. 플랫폼 독립적인 인터페이스
- UI 백엔드
- 플랫폼에서 명시하지 않은 일반적인 인터페이스. 콤보 박스와 같이 창 같은 기본적인 장치를 그림
- 자바스크립트 해석기(JavaScript Interpreter)
- 자바스크립트 코드를 해석하고 실행
- 자료 저장소(Web Storage)
- 쿠키 등의 모든 종류의 자원을 하드디스크에 저장하는 계층
크롬은 대부분의 브라우저와 달리 각 탭마다 별도의 엔진 인스턴스를 유지한다. 각 탭은 독립된 프로세스로 처리된다.
렌더링(Rendering)
렌더링 엔진
렌더링 엔진은 요청받은 내용을 브라우저 화면에 표시한다. HTML 및 XML 문서와 이미지를 표시할 수 있다.
추가 플러그인이나 확장 기능으로 PDF 등의 다른 유형도 표시할 수 있다.
렌더링 엔진 종류
- 파이어폭스: 게코(Gecko) 엔진
- 사파리, 크롬: 웹킷(Webkit) 엔진
웹킷(Webkit)
최초 리눅스 플랫폼에 동작하기 위한 오픈소스 엔진
중요 렌더링 경로(Critical Rendering Path, 렌더링 동작 과정)
각 단계에서 리소스를 로드하는 순서나 작성한 스크립트의 내용에 따라 웹 페이지의 반응 속도가 달라질 수 있다.
- 파싱(Parsing)
- 렌더 트리(Render Tree) 구축
- 레이아웃(Layout) 또는 리플로우(Reflow)
- 페인트(Paint)
렌더링 엔진의 기본적인 동작 과정
- HTML 문서를 파싱 한다.
- 콘텐츠 트리 내부에서 태그를 DOM 노드로 변환한다.
- 외부 CSS 파일과 함께 포함된 스타일 요소도 파싱 한다.
- 스타일 정보와 HTML 표시 규칙은 “렌더 트리”라는 또 다른 트리를 생성한다.
- 렌더 트리는 정해진 순서대로 화면에 표시된다.
- 렌더트리 생성이 끝나면 배치가 시작된다. 배치: 각 노드가 화면의 정확한 위치에 표시되는 것
- 그리기 과정: UI 백엔드에서 렌더 트리의 각 노드를 가로지르며 형상을 만들어 낸다.
위의 과정들이 점진적으로 진행되며, 사용자 경험을 위해 HTML 파싱을 기다리지 않고 배치와 그리기 과정을 진행한다.
즉 전송을 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.
웹킷의 동작 과정 | 게코의 동작 과정 |
![]() |
![]() |
용어 차이를 제외하면 동작 과정은 기본적으로 동일하다. |
파싱(Parsing)
파싱(Parsing): 토큰화(Tokenize)된 코드를 구조화하는 과정.
파서(Parser): 파싱 과정을 전문적으로 해주는 부분
정확히는 어휘 분석기(Lexical scanner, Lexer)를 통해 토큰화된 코드가 생성되고, 이를 파서가 해석한다.
토큰화는 의미가 있는 최소 단위로 코드를 쪼개는 것을 의미한다.
파싱은 문자열이 정해진 문법을 모두 따르는지 확인하는 과정이다. 각 문법은 어휘와 문법 규칙으로 구성되어 있다.
브라우저는 HTML, CSS, JavaScript 세 종류의 언어를 해석할 수 있다. 그중 JavaScript는 렌더링 엔진이 아닌 JavaScript 해석기에서 언어를 해석한다. 따라서 렌더링 엔진은 HTML과 CSS를 파싱 한다.
파서는 어휘 분석과 구문 분석을 거쳐 파싱 트리를 구축한다.
- 어휘 분석: 자료를 토큰으로 분해하는 과정
- 구문 분석: 언어의 구문 규칙을 적용하는 과정
파서는 어휘 분석기로부터 새 토큰을 받아서 구문 규칙과 일치하는지 확인한다.
규칙에 맞으면 토큰에 해당하는 노드가 파싱 트리에 추가되고 파서는 또 다른 토큰을 요청한다.
규칙에 맞지 않으면 토큰을 내부적으로 저장하고 토큰과 일치하는 규칙이 발견될 때까지 요청한다.
맞는 규칙이 없는 경우 예외로 처리한다. 이는 문서가 유효하지 않고 구문 오류를 포함하고 있다는 것이다.
HTML 파싱
HTML의 문자열들을 이용해 파스 트리(Parse Tree 또는 문법 트리(syntax tree))를 생성한다.
파스 트리는 브라우저가 읽어야 할 HTML 코드를 트리 모양으로 구조화하여 나타낸 것이다.
브라우저는 파스 트리를 이용해 DOM(Document Object Model) 트리를 새로 만든다.
DOM(Document Object Model, 문서 객체 모델)
웹 브라우저가 HTML 페이지를 인식하는 방식 웹페이지 소스에는
<html>, <body> 같은 태그들이 존재하는데, 이를 JavaScript가 활용할 수 있는 객체로 만들면 “문서 객체”가 된다.
HTML 파서의 특징
- forgiving nature 속성
- HTML을 파싱 하는 도중 에러가 발생하면, 자체적으로 에러를 복구하려 한다.
- HTML 규칙들은 HTML Document Type Definition(DTD)에 의해 정의되어 있고, HTML 파서는 명세된 규칙들을 따르는 예외 처리를 따로 해주어야 한다.
- 파싱 과정이 중단될 수 있다.
- <script>, <link>와 같은 외부 태그를 만나게 되면 HTML 파싱을 즉시 중단하고 해당 태그의 해석을 실행한다.
- 외부 콘텐츠들을 증분적(Incrementally)으로 해석할 수 없고, DOM을 직접 수정하는 내용이 해당 태그에 있을 수 있기 때문이다.
- 재시작(Reentrant)
- 위에서 설명한 것처럼 외부의 요인으로 DOM이 추가, 변경, 삭제될 수 있다. 이때 HTML은 처음부터 파싱 과정을 다시 거친다.
CSS 파싱
CSS 파싱은 공식 명세에 따라 진행한다.
HTML 코드 내에 CSS 링크가 있기 때문에, HTML을 파싱 하는 도중에 파싱이 시작된다.
CSS 파서는 전체 파일을 모두 다운로드할 때까지 파싱을 시작할 수 없다.
CSS 파싱 과정이 끝나면, 코드에서 명세한 내용과 순서를 바탕으로 DOM과 같은 트리를 구성한다.
이를 CSSOM(CSS Object Model) 트리라 부른다.
렌더 트리(Render Tree)
DOM 트리가 구성되는 동안 브라우저는 렌더 트리( 또는 프레임 트리(Frame Tree))를 구성한다.
렌더 트리는 화면에 나타나는 요소들을 결정하는 트리이다.
어떤 요소가 보여야 할지, 어떤 스타일이 적용되어야 하는지, 어떤 순서로 나타낼 것인지를 명세한다.
DOM 트리와 CSSOM 트리를 조합하여 만들어지고, 화면에 그려지지 않는 요소들은 트리에 나타나지 않는다. 즉, 렌더 트리는 DOM 트리와 1:1로 매칭되지는 않는다.
레이아웃 또는 리플로우
렌더 트리에서 계산되지 않았던 노드들의 크기와 위치, 레이어 간 순서와 같은 정보를 계산하여 좌표에 나타낸다.
레이아웃은 계산의 범위에 따라 전역적 레이아웃(Global Layout)과 증분적 레이아웃(Incremental Layout)으로 구분할 수 있다.
페인트
레이아웃 단계를 통해 화면에 배치된 엘리먼트들에 색을 입히고 레이어의 위치를 결정한다.
페인팅도 전역적 페인팅과 증분적 페인팅으로 구분할 수 있다. 또한 페인팅은 "z-index"가 낮은 순서대로 먼저 페인팅된다.
+ 가상 DOM(Virtural DOM)
일반적으로 중요 렌더링 경로는 초당 60회 정도의 주기로 계산을 수행한다.
이때 가장 비용이 많이 드는 단계는 레이아웃과 페인트 단계이다.
성능 최적화를 고려한다면 두 단계에서의 연산을 최소화해야 한다.
JavaScript를 이용해 DOM을 직접 조작하면, 변경사항이 있을 때마다 잠재적인 레이아웃과 페인트 단계를 초래하게 된다. 때문에 일반적으로 DOM을 직접 조작하는 것은 비용이 크다.
가상 DOM은 실제로 렌더링 되지는 않았지만, 실제 DOM 구조를 반영한 상태로 메모리에 있는 가상의 DOM이다.
실제 화면에 그릴 필요는 없기 때문에 실제 DOM보다 연산 비용이 적다.
가상 DOM은 변경 사항들을 한 번에 묶어서 실제 DOM에 반영한다. 때문에 레이아웃과 페인트 단계에서 한 번에 변경되어야 하는 사항은 많아지지만, 단 한 번의 계산만으로 DOM을 바꿀 수 있기 때문에 연산의 횟수는 최소한이 된다.
DOM에 변경사항을 유발하는 스크립트를 묶어서 실행하는 방법도 있지만, 가상 DOM을 사용함으로써 이 과정을 모두 자동화하고, 관리할 포인트를 줄일 수 있다.
React와 Vue은 가상 DOM을 사용하는 대표적인 라이브러리, 프레임워크이다
가상 DOM에 대해서는 다음에 자세히 알아보도록 하자
참고
https://gyoogle.dev/blog/web-knowledge/브라우저-동작-방법.html
https://d2.naver.com/helloworld/59361
https://yozm.wishket.com/magazine/detail/1338/
'Learning' 카테고리의 다른 글
[WEB] 렌더링 방식 CSR과 SSR (0) | 2024.01.15 |
---|---|
[WEB] 쿠키와 세션 (2) | 2024.01.09 |
[이산수학] 동치관계 (1) | 2024.01.04 |
[이산수학] 역, 이, 대우 (0) | 2024.01.04 |