0. 서론
프론트엔드 개발자에게 브라우저란 일을 제공해주는 플랫폼이고, 개발을 함에 있어서 기본이 되는, 꼭 알아야만 하는 것이라고 생각한다.
프론트엔드 면접 관련 질문을 찾아봐도 어딜가나 쉽게 찾아볼 수 있는것을 보면 아마 그러한 질문을 하는
면접관(시니어 개발자)들도 이 중요성을 알기때문에 질문하는 것이겠지? 라는 생각이 든다.
그렇다고, 모든 프론트엔드 개발자가 브라우저의 모든 원리에 대해 잘 알고 있는 것은 아니라고한다.
브라우저는 아주 많은 기능을 수행할 수 있는 복잡하고 고도화된 어플리케이션 이기 때문이다.
하지만, 더 나은 프론트엔드 개발자가 되기 위해서 결국에는 전 과정을 설명할 수 있는 단계까지 가야만 한다고 생각한다.
그래서 이번 기회에 되도록 최대한 많은자료들을 보고 정리를 해보려고 한다.
글 맨 아래 모든 출처들을 남겨놓도록 하겠다.
<목차>
0. 서론
0.1 브라우저의 핵심(주요)기능
0.2 브라우저 구성 요소
1. 렌더링 엔진의 동작 과정 한눈에 보기
2. 렌더링 엔진의 동작과정 자세히 알아보기
1. 요청과 응답
2. HTML 파싱과 DOM 생성
3. CSS 파싱과 CSSOM 생성
4. 렌더 트리 생성
5. 레이아웃과 페인트
6. composite (컴포지팅) 단계
7. 자바스크립트 파싱과 실행
8. 리플로우와 리페인트
0.1 브라우저의 핵심(주요) 기능
브라우저의 핵심(주요) 기능은 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것이다.
- 자원은 보통 HTML문서지만 PDF나 이미지 또는 다른 형태일 수 있다.
- 자원의 주소는 URI(Uniform Resource Identifier)에 의해 정해진다.
- 브라우저는 HTML과 CSS 명세에 따라 HTML 파일을 해석해서 표시하는데 이 명세는 웹 표준화 기구인
W3C(World Wide Web Consortium)에서 정한다.- 과거에는 브라우저들이 일부만 이 명세에 따라 구현하고 독자적인 방법으로 확장함으로써 웹 제작자가 심각한
호환성 문제를 겪었지만 최근에는 대부분의 브라우저가 표준 명세를 따른다.
- 과거에는 브라우저들이 일부만 이 명세에 따라 구현하고 독자적인 방법으로 확장함으로써 웹 제작자가 심각한
0.2 브라우저 구성 요소
<브라우저를 구성하는 요소>
User Interface (사용자 인터페이스(UI) 레이어) |
브라우저에서 볼 수 있는 거의 모든 것으로, 요청한 페이지를 보여주는 창외의 모든 UI를 의미 주소창, 뒤로가기, 앞으로가기, 새로고침, 북마크, 환경설정과 같은 UI 가 있다. |
Browser engine (브라우저 엔진) |
사용자 인터페이스와 렌더링 엔진 사이에서 중개자 역할 만약 내가 사용자 인터페이스 레이어에 있는 새로고침 버튼을 눌렀다면, 브라우저 엔진은 이를 이해하고 새로고침 명령을 수행한다. |
Rendering engine (렌더링 엔진) |
HTML, CSS , JS를 파싱하고 그 결과물을 바탕으로 페이지를 그려내는 역할 각 브라우저는 다양한 엔진을 사용한다. Chrome, Opera, Edge → Blink Firefox → Gecko(게코) Safari → WebKit(웹킷) |
Networking (네트워크 레이어) |
HTTP, HTTPS 같은 프로토콜을 이용해 외부의 리소스를 얻어오고, 서버에 요청을 보낼 때 사용되는 레이어 |
JavaScript Interpreter (JavaScript 인터프리터) |
JavaScript를 해석하고 실행하는 역할 가장 유명한 엔진으로 Chrome에 탑재된 구글의 V8이 있다. |
UI Backend (UI 백엔드) |
브라우저가 동작하고 있는 운영체제의 인터페이스를 따르는 UI들을 처리 Alert 이나 Select(셀렉트박스)가 운영체제 별로 다르게 동작하는 것을 쉽게 확인할 수 있다. |
Data Persistence (자료저장소) |
브라우저 자체에서 하드디스크와 같이 데이터를 로컬에 저장하기 위한 레이어 쿠키나 ,로컬스토리지, 세션스토리지, IndexedDB, 웹 SQL 파일시스템 등에 접근하고 데이터를 저장하는 데 사용된다. |
프론트엔드 개발자의 입장에서 봤을 때,
렌더링 엔진은 우리의 어플리케이션이 직접 동작하는 레이어인 만큼, 눈여겨 볼 필요가 있다.
1. 렌더링 엔진의 동작 과정 한눈에 보기
크게, 다음과 같은 네 단계로 이루어져 있다고 봐도 무방하다.
- 파싱(Parsing)
- 렌더 트리(Render Tree) 구축
- 레이아웃(Layout) 또는 리플로우(Reflow)
- 페인트(Paint)
위에서 이야기한 모든 과정을 일컬어 Critical Rendering Path(중요 렌더링 경로) 라고 부른다.
CHECK POINT1.
1. 각 단계에서 리소스를 로드하는 순서나 작성한 스크립트 내용에 따라 웹 페이지의 반응 속도가 달라질 수 있다.
이러한 과정의 최적화를 통해 프론트엔드 개발자는 렌더링에 걸리는 시간과 사용자 경험을 개선시킨다.
2. 렌더링 엔진의 동작과정 자세히 알아보기
1. 요청과 응답
브라우저는 서버에 요청을 전송하기위해 주소창을 제공한다.
1. 사용자가 브라우저의 주소창에 URL을 입력하고 엔터키를 누르면
2. URL의 호스트 이름이 DNS를 통해 IP 주소로 변환되고, 이 IP주소를 갖는 서버에게 요청을 전송한다.
4. 주소에 있는 서버는 약속된 HTML 파일을 브라우저로 전송한다.
2. HTML 파싱과 DOM 생성
- 전송받는 HTML 코드는 8bit의 데이터 형태로 전송된다. ---전문용어로 ‘Byte Stream'(바이트 스트림) 이라고 한다.
- 브라우저는 전송받은 바이트 데이터를 문자로 변환한다.
- 브라우저는 가지고 있는 토큰과 비교하여 해당 문자가 HTML 코드인지 확인하게 된다.
- 여기서 '토큰'이란,
- 브라우저에 저장되어 있는 HTML의 시작 혹은 종료 태그, 속성과 속성값등 약속된 여러가지 값들을 의미한다.
- 즉, 문자로 해석된 해당 문자가 HTML 코드인지 확인하는 일종의 설명서라고 보면된다.
- 토큰을 통해 문자가 HTML 코드인지 확인하는 과정을 ‘토큰화’ 한다고 한다.
- 여기서 '토큰'이란,
- 브라우저는 가지고 있는 토큰과 비교하여 해당 문자가 HTML 코드인지 확인하게 된다.
- 토큰화 과정을 통해 노드가 생성된다.
- '노드'란, 돔 트리를 이루는 거대한 구조의 한 단위라고 보면 된다.
- 작은 노드들이 모여 하나의 거대한 트리 구조를 이루게 되는데 이 트리가 바로 'DOM Tree' 이다.
- DOM tree 렌더링 과정에서 스크립트 태그를 만나게 된다면 브라우저는 DOM 생성을 중단하고
스크립트 태그 안에 들어있는 자바스크립트 코드를 해석하게된다.
자바스크립트를 해석하는 동안 DOM 트리 생성이 중단되게 되는 것이다.
즉, DOM은 HTML 문서를 파싱한 결과물이다.
3. CSS 파싱과 CSSOM 생성
1. 렌더링 엔진은 HTML을 처음부터 한 줄씩 순차적으로 파싱하여 DOM을 생성해 나간다.
2. DOM을 생성해 나가다가 CSS를 로드하는 link 태그나 style 태그를 만나면 DOM 생성을 일시 중단한다.
3. 그리고 link 태그의 href 어트리뷰트에 지정된 CSS 파일을 서버에 요청하여 로드한 CSS 파일이나 style 태그 내의 CSS를 HTML과 동일한 파싱 과정(바이트→문자→토큰→노드→CSSOM)을 거치며 해석하여 CSSOM을 생성한다.
4. CSS 파싱을 완료하면 HTML 파싱이 중단된 지점부터 다시 HTML을 파싱하기 시작하여 DOM을 생성한다.
4. 렌더 트리 생성
랜더링 엔진은 서버로부터 응답된 HTML과 CSS를 파싱하여 각각 DOM과 CSSOM을 생성한다.
그리고 DOM과 CSSOM은 렌더링을 위해 렌더 트리로 결합된다.
'렌더 트리'는 렌더링을 위한 트리 구조의 자료구조다.
CHECK POINT2.
- 따라서 브라우저 화면에 렌더링되지 않는 노드 (meta태그, script 태그)와 CSS 에 의해 비표시(display:none)되는 노드들은 포함하지 않는다.
- 즉, 화면을 읽어주는 스크린리더기 같은 프로그램들이 display: none 이 적용된 요소를 인식할 수 없는 문제가 생긴다.
- 따라서 접근성을 위해서 요소를 숨겨줄 때는 display: none; 과같은 속성을 사용하면 안된다.
- 다시말해, 렌더트리는 브라우저 화면에 렌더링되는 노드만으로 구성된다.
완성된 렌더 트리는 HTML 요소의 레이아웃(위치와 크기)을 계산하는 데 사용되며, 브라우저 화면에 픽셀을 렌더링하는 페인팅(painting) 처리에 입력된다.
5. 레이아웃 과 페인트
1. 레이아웃 단계에서는 앞서 만들어진 DOM과 계산된 스타일을 따라가면서 요소의 크기나 좌표와 같은 정보를 담은 레이아웃 트리를 생성하게 된다.
2. 앞서 봤던 아래사진과 같은 트리를 말한다.
DOM정보와 함께, CSSOM 트리에 들어있던 이런 CSS 관련 정보를 합친 하나의 모습이라고 생각하면 된다.
3. 레이아웃 단계가 끝나면 페인트 단계가 진행된다.
페인트 단계에서는 앞서 만들어진, 렌더 트리를 따라서 페인트 기록이 생성되는데,
이 페인트 기록에는
1. 요소를 렌더링하는 순서, 그리고 지금까지의 정보를 바탕으로
한 페이지를 여러 개의 레이어로 나눈 다음
2. 그 위에 텍스트, 색, 이미지, 테두리(border), 그림자 등 모든 시각적인 부분을 그리는 작업이 진행되게 된다.
이 페인트 단계가 끝나면 마지막으로 Composite(컴포지팅) 단계가 진행된다.
6. Composite (컴포지팅)단계
1. 앞서 페인트 단계에서 만들어진 여러가지 레이어를 스크린에 픽셀로 표현하게 되고
2. 나누어져 있던 레이어를 하나로 합성해서 페이지를 완성하게 된다.
이를 컴포지팅 단계라고 표현한다.
지금까지 살펴본 브라우저 렌더링과정은 반복해서 실행될 수 있다.
예를들어, 다음의 경우 반복해서 레이아웃 계산과 페인팅이 재차 실행된다.
1. 자바스크립트에 의한 노드 추가 또는 삭제
2. 브라우저 창의 리사이징에 의한 뷰포트(viewport) 크기 변경
3. HTML 요소의 레이아웃(위치, 크기)에 변경을 발생시키는 width/height, margin, padding, border, display, position,top/right/bottom/left 등의 스타일변경
레이아웃 계산과 페인팅을 다시 실행하는 리렌더링은 비용이 많이 드는 성능에 악영향을 주는 작업이다.
따라서 리렌더링이 빈번하게 발생하지 않도록 주의할 필요가 있다.
7. 자바스크립트 파싱과 실행
CHECK POINT3.
HTML 문서를 파싱항 결과물로서 생성된 DOM은 HTML 문서의 구조와 정보뿐만 아니라, HTML 요소와 스타일 등을 변경할 수있는 프로그래밍 인터페이스로서 DOM API를 제공한다.
즉, 자바스크립트 코드에서 DOM API를 사용하면 이미 생성된 DOM을 동적으로 조작할 수 있다.
1. CSS 파싱 과정과 마찬가지로 렌더링 엔진은 HTML을 순차적으로 파싱하며 DOM을 생성해 나가다 scirpt 태그를 만나면 DOM 생성을 일시 중단한다.
2. script 태그 내의 자바스크립트 코드를 파싱하기 위해 자바스크립트 엔진에 제어권을 넘긴다.
3. 자바스크립트 파싱, 실행이 종료되면 렌더링 엔진으로 다시 제어권을 넘겨 HTML 파싱이 중단된 지점부터 다시 HTML 파싱을 시작하여 DOM 생성을 재개한다.
CHECK POINT4.
자바스크립트의 파싱, 실행은 브라우저의 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다.
4. 렌더링 엔진으로부터 제어권을 넘겨받은 자바스크립트 엔진은 자바스크립트 코드를 파싱하기 시작한다.
5. 자바스크립트를 해석하여 AST(Abstract Syntax Tree)(추상적구문트리) 를 생성한다.
6. AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드인 바이트코드를 생성하여 실행한다.
(AST는 토근에 문법적 의미와 구조를 반영한 트리 구조의 자료구조다.)
7. 파싱의 결과물로서 생성된 AST는 인터프리터가 실행할 수 있는 중간 코드인 바이트코드로 변환되고 인터프리터에 의해 실행된다.
8. 리플로우와 리페인트
1. 자바스크립트 코드에 DOM이나 CSSOM을 변경하는 DOM API가 사용된 경우 DOM이나 CSSOM이 변경된다.
2. 이때 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합되고 변경된 렌더 트리를 기반으로 레이아웃과 페인트 과정을
거쳐 브라우저의 화면에 다시 렌더링한다.
- 이를 리플로우(reflow), 리페인트(repaint) 라 한다
브라우저에게 있어서 레이아웃을 중간에 변경하는 것은 상당히 부담되는 작업이라고 할 수 있다.
그리고 이러한 현상을 바로 리플로우 현상이라고 표현하게 되는 것이다.
리플로우 (reflow)
레이아웃을 다시하는 것을 말한다.
노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생한 경우에 한하여 실행된다.
ex) position, left, top, right, bottom, width, height, margin, padding, border, border-width, display, float, overflow, font-family, font-size, font-weight, text-align, vertical-align .....
리페인트(repaint)
재결합된 렌더 트리를 기반으로 다시 페인트를 하는 것을 말한다.
리플로우와 리페인트가 반드시 순차적으로 동시에 실행되는 것은 아니다.
레이아웃에 영향이 없는 변경은 리플로우 없이 리페인트만 실행된다.
(레이아웃 속성과 상관없고, 페인트 속성과 관련있는 CSS 속성만 변경시)
레이아웃(리플로우) 현상을 시각적으로 잘 나타낸 영상을 하나 소개하겠다.
CHECK POINT4.
transform, opacity는 리플로우, 리페인트 단계를 생략할 수 있다.
이 말은, 리플로우, 리페인트 없이도 레이아웃 변경이 가능하다는 얘기인데,
그 이유는, transform, opacity는 앞서 이야기한 DOM Tree를 변경하지 않도록 설계가 되어있다.
그렇기 떄문에 리플로우, 리페인트를 생략하게 되고, 브라우저는 더욱 쾌적하게 화면을 렌더링 할 수 있게되는 것이다.
따라서 이 transform 속성을 이용해서 애니메이션 작업을 많이 하게 된다.
( position 보다는 transform속성을 이용해 애니메이션을 구현하자)
\
마무리
브라우저 렌더링 과정에 대해서 사실 내가 모든것을 이해하고 글을 썼다기 보다는, 여러 자료들을 보고 정리한 글이라고 볼 수 있다.
최대한 핵심들, 꼭 알아야 할 내용들 위주로 정리해서 글을 작성하게되었는데, 생각보다 글이 길어진 것 같다.
이 글을 보게되었다면, 조금이라도 브라우저 렌더링 과정에 대해 이해가 됬으면 좋겠고,
브라우저 렌더링 과정에 대해 질문이 나온다면 자신있게 말할 수 있을때까지 나 또한 반복해야겠다.
<reference>
[브라우저 이해하기] 2. 브라우저 엔진 들여다보기 (Webkit)
브라우저를 구성하는 요소들중 단연 중요한것은 '엔진'일 것이다. 사용자가 주소를 입력하는 시점부터, 브라우저 영역안에 웹 컨텐츠들이 보여지기까지 어떤 일들이 일어나는지를 이해하기 위
codecraft.tistory.com
https://yozm.wishket.com/magazine/detail/1338/
프론트엔드 개발자라면 알고 있어야 할 브라우저의 동작 과정 | 요즘IT
프론트엔드 개발자에게 있어 브라우저는 거의 모든 것과도 같습니다. 하지만 그렇다고 해서 프론트엔드 개발자가 브라우저의 모든 원리에 대해 잘 알고 있는 것은 아니지만, 복잡한 웹 어플리
yozm.wishket.com
https://www.youtube.com/watch?v=z1Jj7Xg-TkU
https://yozm.wishket.com/magazine/detail/1338/
https://www.youtube.com/watch?v=sJ14cWjrNis&t=2s
https://www.youtube.com/watch?v=v8H5ujL4Tt8&t=8s
https://d2.naver.com/helloworld/59361
'웹 지식' 카테고리의 다른 글
[브라우저저장소(Web Storage)]localStorage, SessionStorage에 대해 알아보기 (0) | 2023.05.27 |
---|---|
[웹개발기술] Font를 Preload 하는 방법 (0) | 2023.05.07 |
[웹개발기술] 크로스 브라우징(Cross Browsing)에 대해 알아보기 (0) | 2023.04.30 |
Web Standards(웹 표준) 을 지키는 이유 , 그리고 web accessibility(웹 접근성)이란? (0) | 2023.04.24 |