1. 브라우저의 구조
웹브라우저의 기능이 다양화되면서 많은 역할을 수행하고 있습니다. 그러나 웹브라우저의 근본적인 역할은 웹페이지를 다운받아 렌더링하여 화면에 보여주는 것입니다.
<브라우저의 구성요소>
- User Interface : 요청한 페이지를 보여주는 창 이외에 사용자가 컨트롤 할 수 있는 부분이다. (주소표시줄, 이전/다음, 새로고침 ...)
- Browser Engine: 주소표시줄에 URI를 요청하는 등의 사용자 인터페이스를 렌더링 엔진에 전달해주고 동작을 제어한다. 또는 Data Persistence(자료저장소)에서 필요한 정보를 가져온다.
- Rendering Engine : 요청한 URI를 브라우저엔진에게 받아서 server에 요청한다. 이후 데이터를 받아 파싱한 후 렌더링한다. (렌더링 과정은 2장에!)
- Networking : 렌더링엔진으로부터 server에 HTTP 요청을 하라는 명령을 받아 수행한다. 응답을 받으면 렌더링엔진에 반환한다.
- JavaScript Interpreter: (크롬에서는 V8을 사용하여) 자바스크립트를 파싱한다.
- Display Backend(=UI 백엔드) : 렌더링 엔진에서 최종적으로 완성된렌더트리를 브라우저에 실제로 그린다.
이 중 렌더링 엔진의 프로세스에 대해 살펴보겠습니다 👻
2. 렌더링 Process
본격적인 렌더링 과정을 알아보기 전에, 자주 언급될 용어들을 정리하고 가도록 하겠습니다.
1) 파싱(parsing): 구문 분석으로, 데이터를 분해하고 분석하여 원하는 형태로 조립하는 프로그램을 말합니다. 즉 주어진 정보를 내가 원하는 토큰으로 분해해 문법적인 의미를 가진 채로 가공하는 것
2) 렌더링(rendering) : HTML, CSS 및 화면 출력 소스를 위해 작성된 문서를 파싱하여 브라우저에 시각적으로 출력하는 것
3) 렌더링 엔진: 요청한 콘텐츠를 화면에 출력하는 역할로, HTML, CSS등을 파싱하여 최종적으로 화면에 그림
<Rendering Process>
1. 사용자가 사용자 인터페이스의 주소표시줄에 URI 를 입력하여 브라우저 엔진에 전달한다.
2. 입력받은 사용자 인터페이스의 URI에 해당하는 자료를 자료저장소(Data persistence)에 데이터가 있는지 먼저 찾는다(없다면 HTTP 요청을 필요로 한다.)그후 렌더링 엔진에 전달한다.
3. 렌더링엔진은 가져온 자료를 분석하고, 동시에 networking, JavaScript Interpreter, UI 백엔드에 전달한다.
4. 렌더링엔진은 HTML, CSS를 파싱하고 JavaScript는 JavaScript 인터프리터가 파싱하고 그 결과를 렌더링 엔진에 전달한다.
5. 생성된 DOM node는 render object로 바뀐다.
5. UI 백엔드는 render object를 브라우저에 띄워준다.
3. 렌더링엔진의 working proccess
브라우저의 렌더링엔진이 하는 역할의 과정은 아래와 같습니다.
왼쪽부터 살펴보면
1. 렌더링에 필요한 HTML과 CSS, 폰트 등 필요한 리소스들을 응답받는다.
2. HTML을 파싱해 DOM Tree를 생성하고, CSS를 파싱해 CSSOM 을 생성한다.
3. DOM과 CSSOM를 결합하여 Render Tree를 생성한다.
4. 브라우저의 자바스크립트 엔진은 자바스크립트를 요청받아 파싱하고 실행한다. (이 때, 자바스크립트는 DOM 이나 CSSOM 을 변경할 수 있고, 변경된 요소는 Render Tree로 결합됨)
5. Render tree 를 기반으로 HTML 요소의 Layout(위치와 크기)을 계산하고 브라우저 화면에 HTML 요소를 실제 픽셀로 Paint 한다.
이 렌더링 과정을 최적화하면 브라우저의 렌더링 속도를 높여 사용성을 개선할 수 있습니다.
렌더링 과정은 브라우저 화면에 보여줄 필요한 리소스들을 서버에 요청(HTTP request)하고, 그 요청을 받아오는 것으로 시작됩니다.
html 파일을 요청하고, html을 파싱하는 도중 외부 리소스 파일을 필요로 하면 해당 파일을 서버로 요청하게 됩니다. (이미지, script 태그 등)
1) DOM Tree 생성하기
Parsing HTML into the DOM
HTML문서는 순수한 텍스트로 이루어져 있습니다. 이를 프로그램이 이해할 수 있도록 하려면 객체로 변환하여 메모리에 저장해야합니다. 그래서 브라우저가 이해할 수 있는 자료구조인 DOM(document object model)을 생성하게 됩니다.
위 사진을 보면 각 태그별로 객체들이 생성되고, 트리구조로 엮인 형태를 볼 수 있습니다. 트리구조로 저장하는 이유는, 시작태그와 종료태그 사이에 많은 태그들이 존재하기 때문에 서로가 중첩관계 (부모-자식) 를 가지고 있기 때문입니다. 그래서 생성된 각 객체들은 노드라고 부르며 DOM을 구성하는 기본 요소입니다.
DOM 생성 과정
1. 바이트 읽어오기 : 10110100001011... (이후 인코딩해 문자열로 변환)
2. 문자: <hml><head><meta>...</html>
3. 토큰화:
{
startTag: 'html',
contents: {
startTag: 'head',
contents: {...}
},
endTag: 'html'
}
4. 렉싱(Lexing): 토큰을 객체 Nodes 로 변환
5. DOM 생성!
2) CSSOM 생성하기
렌더링 엔진이 HTML파일을 먼저 한줄씩 읽어나가다가, CSS를 import 하는 <link> 태그 또는 <style>태그를 발견하게 됩니다. 그러면 DOM 생성을 잠시 중단하고 CSS 파일을 요청하여 로드하고, 이를 HTML과 동일한 파싱과정을 거칩니다. 이를 통해 CSSOM(css object model)을 생성하게 됩니다.
CSS가 스타일을 계산할 때는 해당 노드에 적용 가능한 가장 일반적인 (상위의) 규칙으로 시작해 각자가 가지고 있는 더 구체적인 규칙을 적용하는 하향식 규칙을 적용합니다.
CSS 파싱을 완료하면 다시 DOM 생성을 재개합니다.
3) Render Tree 생성하기
DOM과 CSSOM은 결합되어 Render Tree 를 만들게 되는데요. 이는 렌더링을 위한 자료구조로 페이지에 표시되는 모든 DOM 콘텐츠와 각 노드에 대한 CSSOM 스타일 정보를 가집니다.
렌더트리 생성 과정은 이렇습니다.
1. DOM 트리의 루트에서 시작하여 노드들을 각각 탐색한다.
(이 때, 화면에 표시되지 않는 script, meta tag 등은 렌더 트리에 반영되지 않음 / display: none; 도 반영되지 않음)
2. 각 노드에 대해 적절하게 일치하는 CSSOM 규칙을 찾아 적용한다.
3. 화면에 표시되는 노드를 콘텐츠 및 계산된 스타일과 함께 내보낸다.
4) Layout
렌더 트리 생성 후 기기의 뷰포트 내에서 각 노드들의 정확한 위치와 크기를 계산하는 과정입니다. Reflow 라고 하기도 하며 em, rem, % 등의 상대적인 단위의 측정값들이 여기서 절대적인 px 단위로 변환됩니다.
5) Painting
렌더트리의 각 노드를 화면의 실제 픽셀로 페인트하는 과정 (혹은 rasterizing)입니다. 이후 브라우저 화면에 원하는 화면이 그려지게 됩니다.
Reference:
https://www.youtube.com/watch?v=oLC_QYPmtS0&t=18s
https://kingpodo.tistory.com/8
https://beomy.github.io/tech/browser/browser-rendering/
https://beomy.github.io/tech/browser/browser-rendering/
'Computer Programming > Javascript' 카테고리의 다른 글
자바스크립트의 Scope 스코프 (렉시컬 환경, 호이스팅, var, let과 const) (0) | 2023.06.19 |
---|---|
WIL - JS ECMAScript(ES)란? ES5와 ES6의 주요 발전 (0) | 2023.06.18 |
자바스크립트의 비동기 처리 동작 원리 | 콜스택, 이벤트루프, Promise, fetch, async/await (1) | 2023.06.14 |
JavaScript 숫자야구 - slice(), splice(), filter()의 차이와 문제점 (0) | 2023.06.13 |
자바스크립트 자료구조 Map과 Set Object의 사용 (0) | 2023.06.12 |