브라우저 주소창에 woong-jae.com을 입력했을 때, 어떤 과정을 거쳐 블로그가 보이게 될까? 간단하게 알아보자
Browser?
브라우저의 주요 기능은 사용자가 참조하고 싶은 웹페이지를 서버에 요청하고, 서버의 응답을 받아 브라우저에 보여주는 것이다. 흔히 사용하는 크롬, 인터넷 익스플로러 등 인터넷 프로그램이다. 서버의 응답은 주소를 통해 요청하는데, 이 주소를 URI(Uniform Resource Identifier)라고 한다.
브라우저의 기본 구조
- 사용자 인터페이스 : 검색창, 새로고침, 뒤로가기/앞으로가기 버튼 등 사용자가 접근할 수 있는 영역이다.
- 브라우저 엔진 : 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다.
- 렌더링 엔진 : 브라우저의 핵심이다. 요청한 콘텐츠를 화면에 표시한다. HTML과 CSS등을 해석해서 표시하는 엔진이다.
- 통신 : HTTP요청같은 네틑워크 호출에 사용된다. 브라우저마다 독립적인 인터페이스다.
- UI 백엔드 : 기본적인 위젯을 그린다. OS 사용자 인터페이스 체계를 사용한다.
- 자바스크립트 해석기 : 이름 그대로 자바스크립트 코드를 해석하고 실행한다.
- 자료 저장소 : 이름 그대로 자료를 저장하는 계층이다. Local Storage, Indexed DB, 쿠키 등 브라우저 메모리를 활용하여 저장하는 영역이다.
크롬은 대부분의 브라우저와 달리 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지한다고 한다. 각 탭이 독립된 프로세스로 처리되니까 메모리를 상대적으로 많이 잡아먹게 된다.
렌더링 엔진
렌더링 엔진은 요청 받은 내용을 브라우저 화면에 표시한다. HTML 및 XML 문서와 이미지를 표시할 수 있다. 플러그인이나 브라우저 확장 기능을 이용해 PDF와 같은 다른 유형도 표시할 수 있다.
파이어폭스와 크롬, 사파리는 두 종류의 렌더링 엔진으로 제작되었다. 파이어폭스는 모질라에서 직접 만든 Gecko엔진을 사용하고 사파리와 크롬은 Webkit엔진을 사용한다.
동작 과정
- DOM 트리 구축을 위한 HTML 파싱 : 브라우저는 서버로부터 HTML 문서를 모두 전달받는다. 렌더링 엔진은 전달받은 HTML문서를 파싱해서 DOM트리를 구축한다. 그리고 외부 CSS파일과 스타일 요소도 파싱한다.
- 렌더 트리 구축 : DOM(Document Object Model) 트리와 스타일 정보를 합쳐서 렌더 트리를 만든다.
- 렌더 트리 배치 : 렌더 트리의 각 노드에 대해서 화면 상에서 어디에 배치할 지 결정한다.
- 렌더 트리 그리기 : UI 백엔드에서 렌더 트리를 그리게 되고, 우리가 보는 화면에 출력한다.
위 사진은 웹킷의 동작 방식이다.
파싱과 렌더 트리 구축
파싱이란 코드를 브라우저가 이해할 수 있도록 변환하는 것이다. 파싱 결과는 보통 문서 구조를 나타내는 노드 트리인 파싱 트리/문법 트리이다. 파서를 생성해 줄 수 있는 도구를 파서 생성기라고 한다. 웹킷은 잘 알려진 두 개의 파서 생성기를 사용한다. 어휘 생성을 위한 Flex와 파서 생성을 위한 Bison이다. 플렉스는 토큰의 정규 표현식 정의를 포함하는 파일을 입력받고, 바이슨은 BNF 형식의 언어 구문 규칙을 입력받는다. 생성된 파서로 CSS와 자바스크립트를 파싱한다.
HTML의 경우 일반적인 상향식/하향식 파서로는 파싱이 안된다.
- 언어의 너그러운 속성
- HTML 오류에 대한 브라우저의 관용
- 변경에 의한 재파싱
위 세가지 이유 때문에 브라우저는 HTML 파싱을 위해 별도의 파서를 만든다.
브라우저는 HTML을 받아서 어휘와 구문을 분석해서 파싱해 파싱 트리를 만든다. 파싱 트리를 기반으로 DOM 요소와 속성 노드를 가지는 DOM 트리를 생성한다. 그리고 DOM을 생성할 때 거쳤던 과정을 CSS에 반복해서 CSSOM(CSS Object Model)을 생성한다. DOM 트리가 구축되는 동안 브라우저는 DOM 트리를 기반으로 렌더 트리를 생성한다. 렌더 트리는 위치와 크기를 가지고 있지 않기 때문에 객체들에게 위치와 크기를 결정해주고, 렌더 트리의 각 노드를 화면에 그리면 화면에 콘텐츠가 표현된다.
웹 브라우저의 구조
User Interface : (주소 표지술, 이전/ 다음/새로고침 버튼 등) 웹페이지를 제외하고 사용자와 상호작용하는 사용자 인터페이스
Rendering Engine: HTML과 CSS를 파싱하여 요청한 웹 페이지를 표시하는 렌더링 엔진
Browser Engine : 유저 인터페이스와 렌더링 엔진을 연결하는 브라우저 엔진
Safari는 Webkit, Firefox는 Gecko, Chrome은 Blink 렌더링엔진을 사용.
렌더링 엔진의 목표
1. HTML, CSS, JS, 이미지 등 웹페이지에 포함된 모든 요소들을 화면에 보여준다.
2. 업데이트가 필요할 때, 효율적으로 렌더링을 할 수 있도록 자료구조를 생성한다.
이러한 목표를 수행하기 위해 거쳐야하는 렌더링엔진의 과정을 Critical Rendering Path라고 한다.
Critical Rendering Path의 시간을 줄이면 Browser가 웹페이지를 보여주는데 걸리는 시간도 줄일 수 있다.
사용자 동작으로 자바스크립트가 실행되어서 CSS가 변경되거나 애니메이션 재생이 일어났을 때
1. 다시 Layout이 발생하는 경우
주로 요소의 크기나 위치가 바뀔 때, 혹은 브라우저 창의 크기가 바뀌었을 때 다시 발생
2. 다시 Paint부터 발생되는 경우
주로 배경 이미지나 텍스트 색상, 그림자 등 레이아웃의 수치를 변화시키지 않는 스타일의 변경이 일어났을 때 발생
3. 레이어의 합성만 다시 발생하는 경우
Layout과 Paint를 수행하지 않고 레이어의 합성만 발생하기 때문에 성능상으로 가장 큰 이점을 가짐
근본적으로 웹브라우저는 웹페이지를 다운 받아 렌덜링하고 이를 사용자에게 보여주는 프로그램이라는 것.
웹페이지는 HTML,CSS,Javascript로 구성되어 있다.
HTML은 문서의 내용, CSS는 문서의 스타일, Javascript는 문서의 동작
개발자도구 Network탭 상태에서 새로고침하면 탭하단에
종합된 정보가 나오는데 각각
다운로드 요청 갯수, 수신한 데이터 크기, 웹페이지 총 크기, 다운로드 소요 시간, HTML로드 시간, 웹페이지 렌더링 완료 시간
- 왜 다운로드 크기와 페이지 크기가 서로 다르지?
이유는 웹 서버가 압축된 리소스를 전송했기 때문
-finish와 load가 시간이 다른데 그 이유는?
finish는 다운로드 완료 시간이고 load는 페이지 로드 완료 시간.
그러니까 HTML,css등이 다운로드되고 렌더링된 후에 웹페이지가 바로 보여진 것이고, 이미지는 그 이후에 다운로드 받아 표시되었기 때문에 시간대가 다른 것이다.(사용자의 편의를 위해 파일이 큰 이미지를 포함한 모든 데이터들이 전부 다운로드 되기 전에 미리 로드되어야함)
이번 시간에는 웹 브라우저의 동작 순서에 대해 알아보겠습니다.
우리가 웹 브라우저를 열고 웹사이트에 접속을 하면 웹 브라우저 내부에서는 어떤 일이 벌어질까요?
먼저 웹 브라우저는 DNS서버에게 물어봅니다.
'요청한 호스트의 IP주소를 알려줄래?'
받아온 IP주소에 있는 서버를 찾아갑니다.
이 때, 랜덤한 숫자를 적은 번호표(Random Sequence)를 가지고 갑니다.
브라우저와 서버는 서로 번호표를 주고 받으면서 데이터를 주고 받기 위한 3wayHandshake를 완료한다.
이 HandShake 과정이 끝나면 브라우저는 서버에게 자료를 요청합니다.
'서버야 이 주소에 있는 데이터를 보내줄래?' (HttpRequest)
'여기 있다 받아.' (Http Response)
'자 이제 데이터를 받았으니까 사용자가 이해할 수 있도록 예쁘게 그려줘야겠다.'
이제 브라우저는 사용자에게 데이터를 출력할 일만 남았습니다.
그런데 데이터를 출력하기에 앞서 브라우저는 서버로부터 받은 데이터를 해석해야 합니다.
대부분의 브라우저는 웹 표준화 기구인 W3C명세에 따라 HTML과 CSS를 해석합니다.
그리고 이렇게 해석하는 것을 Parsing이라고 합니다.
먼저 브라우저의 렌더링 엔진은 HTML을 Parsing하여 DOM Tree를 생성합니다.
'먼저 HTML을 해석해볼까?'
(Parsing함..)
이 때 렌더링 엔진이 스타일 태그를 만난다면 HTML Parsing작업을 중지하고
CSS Parsing작업을 시작하여 CSSOM Tree를 생성합니다.
CSS Parsing을 마치면 조금 전에 HTML Parsing이 중단된 시점부터 다시 Parsing을 시작합니다.
그러다가 스크립트 태그를 만나면 다시 Parsing작업을 중지하고 이번에는 자바스크립트 엔진에게 제어 권한을 넘깁니다.
자바스크립트엔진은 코드를 해석하여 추상 구문 Tree인 AST(Abstract Syntax Tree)를 만들고 실행합니다.
그 다음으로 아까 중단했던 HTML Parsing작업을 완료합니다.
그리고 브라우저는 DOM Tree와 CSSOM Tree를 합쳐서 Render Tree를 생성합니다.
Render Tree를 생성하는 과정까지를 Construction이라고 합니다.
---(construction)
그리고 렌더링 엔진은 Layout작업을 수행하는데 이것은 Render Tree의 노드들을 화면의 올바른 위치에 표시하는 것을 의미합니다. 그 다음 UI Backend가 Render Tree의 노드들을 그리면서 UI를 그립니다.
그 다음이 노드들의 레이어를 순서대로 구성하는 Composition단계입니다.
z-index가 낮은 요소를 먼저 놓고 그 다음에 높은 요소를 놓는 것입니다.
Layout작업부터 Composition까지의 과정을 operation이라고 합니다.
--(operation)
이러한 Parsing과 배치(Layout) 그리고 UI를 그리는 과정(Paint)은 서버로부터 모든 데이터를 받고 시작하지 않습니다.
브라우저는 사용자에게 더 빠르게 화면을 출력해주기 위해 서버로부터 데이터의 일부를 받고 나서 화면에 표시하고 또 데이터를 받게 되면 화면에 표시하는 것을 반복합니다.
이 때문에 웹페이지의 화면이 한 번에 뜨지 않고 부분적으로 뜨는 현상이 나타나는 것입니다.
(요약)
1. 사용자가 브라우저로 웹 사이트에 접속
2. 브라우저가 DNS를 통해 서버의 아이피 주소를 파악
3. 브라우저와 서버가 3 way handshake
4. 브라우저가 서버에게 Http Request
5. 서버가 브라우저에게 Http Response
6. HTML Parsing하여 DOM Tree 생성하다가..
7. 중간에 스타일태그가 나오면 CSSOM Tree 생성
8. 또 중간에 스크립트 태그가 나오면 AST 생성
9. DOM Tree + CSSOM Tree합쳐서 Render Tree 생성 (여기까지 과정이 Construction)
10. Layout -> Render Tree에 있는 Node를 배치
11. Paint-> UI백엔드는 Render Tree에 있는 Node의 UI를 그림
12. Composition -> Render Tree에 있는 Node를 순서대로 구성 (여기까지 과정이 Operation)
13. 웹 사용자에게 결과 화면을 출력
Browser Elements
- 사용자 인터페이스 : 주소표시줄, 이전/다음버튼,홈버튼, 새로고침/정지 버튼 등 요청한 페이지를 보여주는 창 외에 사용자가 컨트롤할 수 있는 부분
- 브라우저 엔진 : 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다. + 자료 저장소 사용
- 렌더링 엔진 : 요청한 URI를 브라우저 엔진에게 받아서 server에게 요청한다(통신).
server로부터 URI에 해당하는 데이터(HTML, CSS, Javascript)를 받아서 파싱한 후에 렌더링한다. (ex. chrome blink) - 통신 : 렌더링 엔진으로부터 HTTP요청등을 받아서 네트워크 처리 후 응답을 전달한다.(OS단에서 실행)
- 자바스크립트 해석기 : Javascript를 Parsing한다(ex.chrome v8)
- UI백엔드 : render Tree를 Browser에 그리는 역할(Paint)을 담당한다.
Browser Rendering process
브라우저가 렌더링하는 과정을 간단하게 설명한다(uri입력부터 서버와 통신하여 렌더링까지)
이 때 브라우저의 각 요소(element)의 기능을 함께 설명한다.
- 사용자가 사용자 인터페이스의 주소표시줄에 URI를 입력하여 브라우저 엔진에 전달한다.
- 브라우저 엔진은 자료 저장소에서 URI에 해당하는 자료를 찾고, 해당 자료를 쿠키로 저장했다면 그 자료를 렌더링 엔진에 전달한다.
- 렌더링 엔진은 브라우저 엔진에서 가져온 자료(HTML, CSS, image등)를 분석한다. 동시에 URI데이터를 통신, 자바스크립트 해석기, UI백엔드로 전파한다.
- 또한 렌더링 엔진은 통신 레이어에 URI에 대한 추가 데이터(필요하다면)를 요청하고 응답할 때까지 기다린다.
- 응답받은 데이터에서 HTML, CSS는 렌더링엔진이 Parsing한다.
- 응답받은 데이터에서 Javascript는 Javascript해석기가 Parsing한다.
- Javascript해석기는 Parsing한 결과를 렌더링엔진에 전달하여 3번과 5번에서 Parsing한 HTML의 결과인 DOM Tree를 조작한다.
- DOM Tree + CSSOM Tree -> Render Tree
- UI백엔드가 Render Tree의 Node를 브라우저에 Paint한다.
브라우저(Browser)의 동작 원리
■ 프롤로그
우리가 가장 많이 사용하는 소프트웨어 중 하나를 뽑으면 브라우저를 빼 놓을 순 없다. 이 글을 통해, 브라우저가 어떻게 동작하여 우리 화면에 보여지는지 정리를 해 보려고 한다.
■ 브라우저의 주요 기능
사용자가 화면에서 어떠한 이벤트(행위)를 발생시켰을 때, 이벤트를 읽어 해당 내용을 서버에 요청하고 요청 결과를 해석하여 화면에 표시합니다. 보통 HTML 문서이지만, PDF나 이미지 또는 다른 형태의 파일일 수도 있습니다. 이런 자원의 주소는 URI(Uniform Resouece Identifier)에 의해 정해진다.
브라우저 UI는 서로 닮은 모습인 것을 볼 수 있는데 보통 다음과 같은 요소들이 일반적으로 포함된다.
1. URL을 입력할 수 있는 표시 줄
2. 이전 페이지, 다음 페이지 버튼
3. 북마크(즐겨찾기)
4. 새로고침 버튼과 현재 문서의 로드 중 중도 정지 할 수 있는 버튼
5. 홈 버튼
1. 사용자 인터페이스 - 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등. 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분
2. 브라우저 엔진 - 사용자인터페이스와 렌더링 엔진사이의 동작을 제어
3. 렌더링 엔진 - 요청한 콘텐츠를 표시. 예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시
4. 통신 - HTTP요청과 같은 네트워크 호출에 사용됨. 이것은 플랫폼 독립적인 인터페이스이고 각 플랫폼 하부에서 실행
5. UI 백엔드 - 콤보 박스와 창 같은 기본적인 장치를 그림. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용
6. 자바 스크립트 해석기 - 자바스크립트 코드를 해석하고 실행
7. 자료 저장소 - 이 부분은 자료를 저장하는 계층이다. 쿠키를 저장하는 것과 같이 모든 종류의 자원을 하드 디스크에 저장할 필요가 있다.
■ 렌더링 엔진
위에 설명한 브라우저 기본 구성요소 중 렌더링 엔진의 역할은 브라우저 화면에 표시하는 일이다. HTML 및 XML문서와 이미지를 표시하고, 플러그인이나 브라우저 확장 기능을 이용해 PDF나 다른 유형도 표시할 수 있다. 크롬이나 사파리의 대표적인 렌더링 엔진 웹킷(webkit)으로 렌더링 동작과정을 살펴보자.
■ 동작과정
렌더링 엔진은 통신으로부터 요청한 문서의 내용을 얻는 것으로 시작하는데 문서의 내용은 보통 8KB단위로 전송된다.
HTML과 Style Sheet를 각자 따로 요청 및 파싱 후 합쳐지는 과정(어태치먼트)을 거치고, DOM트리에 CSS 규칙을 적용하여 새로운 렌더 트리를 생성하는 작업을 말한다. 위 그림의 마지막인 "표시"까지 이뤄지면 우리가 보던 브라우저 창이 실제 화면에 표현이 된다. 그럼 조금 더 렌더링 과정에 대해 자세히 살펴보도록 하자.
■ HTML 파서
Webkit에서는 파서 생성기인 플렉스(Flex)와 문법 파서 생성기인 바이슨(Bison)을 이용한다. 이 두개의 생성기에서 파서를 생성하고 그걸 기반으로 CSS와 Javascript만을 파싱할 수 있다. HTML코드는, 오류가 발생하여도 실행을 중지하는 것이 아니라 제작자의 실수를 알아서 수정하여 알아서 올바르게 표시해주고, 별도의 HTML 전용 파서(jSoup, BeautifulSoup)로 HTML파싱해준다.
■ DOM
DOM(Document Object Model)은 HTML문서에 작성한 문자열 내용들을 브라우저에서 사용할 수 있는 Object 객체 데이터로 형상화한 것이 DOM인 것이다.
DOM은 HTML 마크업과 1:1의 관계를 맺으므로, HTML문서 작성되어 있는 모든 요소가 DOM으로 생성된다.
■ CSS 파싱
HTML파싱과 동일한 파서 생성기를 통해 파싱이 가능하다
DOM과 결합하여 별도의 CSSOM(CSS Object Model)이라는 스타일 관련 객체 모델이 생성된다. CSSOM은 HTML의 DOM과 같이 스타일 객체에 접근할 수 있는 인터페이스 객체가 된다.
■ Render Tree
attachment라는 과정이 끝나면 실제 화면에 그려질 정보를 담을 Render Tree를 생성하게 되는데, DOM트리와 스타일시트를 읽고 내용을 합쳐 Render Tree(DOM Tree + CSSOM Tree)를 만든다. 단, 이 때 생성은 비동기로 일어난다.
Render Tree는 DOM Tree와 1:1로 대응이 일어나지 않는데, 그 이유는 다음과 같다.
- 비시각적인 요소는 제외한다.
-Render Tree에는 화면에 그려질 정보들을 담은 데이터이기에, 화면에 그려지지 않는 비시각적인 요소들은 Render Tree에 포함되지 않는다. ex) 태그, display:none 속성 - 속성에 display "none"으로 할당된 요소는 트리에 나타나지 않는다.
- 특정 요소에는 여러 번 렌더링이 필요하다.
-<input type='select'> 태그를 그리려면, '표시 영역, 드롭다운 목록, 버튼' 표시를 위한 3개의 렌더러를 필요로 한다.
■ 배치
Render Tree를 이용해서 실제로 페이지에 그리는 과정이다. 그리기 단계에서는 화면에 내용을 표시하기 위한 Render Tree가 전체적으로 탐색되고, 각 렌더러의 'paint'메서드가 호출된다. 각각의 요소들은 블록 렌더러 순서에 따라 그리기 시작한다. 이는 CSS에 명세가 되어있는 순서이다.
1. 배경 색/ 2. 배경 이미지/ 3. 테두리/ 4.자식/ 5. 아웃라인
모든 요소가 그려진 후 브라우저에서 일부 변경이 생길 경우엔, 해당 렌더러와 그 자식의 배치과정(reflow)과 repaint메서드가 발생한다. 이러한 렌더링 엔진의 과정을 통하여 HTML과 CSS문서가 아래와 같은 웹 페이지로 그려지게 된다.
출처 : https://woong-jae.com/web/210821-how-does-browser-work
출처 : https://www.youtube.com/watch?v=sJ14cWjrNis
출처 : https://www.youtube.com/watch?v=FQHNg9gCWpg
'백엔드' 카테고리의 다른 글
호스팅은 무엇일까요? (0) | 2022.09.09 |
---|---|
DNS와 작동원리 (2) | 2022.09.09 |
HTTP는 무엇일까요? (0) | 2022.08.21 |
인터넷은 어떻게 작동될까요? (0) | 2022.07.04 |
백엔드 로드맵/커리큘럼 (0) | 2022.07.04 |