관리 메뉴

Jerry

#12. 브라우저의 동작원리(How Browsers Work) 본문

CS/Terminology

#12. 브라우저의 동작원리(How Browsers Work)

juicyjerry 2021. 2. 1. 00:21
반응형

Index

들어가는 말
브라우저의 주요 기능 
브라우저의 기본 구조
렌더링 엔진
파싱과 DOM 트리 구축
HTML 파서와 DTD, DOM
파싱 알고리즘: 토큰 알고리즘 & 트리 구축 알고리즘
파싱이 끝난 이후의 동작
css 파싱
배치
그리기
마치는 말
출처

 

 

들어가는 말

브라우저는 어떻게 동작하는지 적어보려고 한다. 내가 검색창에 '브라우저 동작원리'라고 검색해보면 아래 첨부한 페이지가 나오거나 첨부한 페이지를 토대로 쓴 블로그 글이 나온다. 다른 관련 글도 있지만 첨부한 이 글이 가장 많이 인용이 되었고 코드스테이츠에서도 보라고 했던 페이지로서 이번 기회에 정리해보려고 한다. 

 

참고로, 네이버에서 원본을 번역한 글이다.

웬만하면 영어 버전으로 읽어보려고 하는데 번역본 자체의 길이가 있고 익숙하지 않은 용어가 있는 탓에 이해하는데 한계가 있기에 글쓴이는 번역본을 선택하여 읽었다. 글쓴이 자신이 다시 볼 때 괜찮을 정도로 요약을 하려고 시도했고 관련 지식의 수준이 높지 않기에 풀어서 쓰지는 못했다.

 

 

www.html5rocks.com/en/tutorials/internals/howbrowserswork/#The_browsers_we_will_talk_about

 

How Browsers Work: Behind the scenes of modern web browsers - HTML5 Rocks

In this comprehensive primer, you will learn what happens in the browser between when you type google.com in the address bar until you see the Google page on the browser screen.

www.html5rocks.com

 

 

 

브라우저의 주요 기능 

현재 글쓴이 살고 있는 시점에서 존재하는 브라우저는 크롬, 사파리, 파이어폭스, 삼성 인터넷, 오페라, IE 등 여러 가지의 브라우저가 있다. 그중에서 많이 사용되고 있는 브라우저를 꼽으면 아래 페이지 통계상(2019년 12월-2020년 12월 통계 기준) 크롬이 압도적이며 그 뒤를 사파리가 위치해 있다. 아무쪼록 이 글에서는 크롬과 파이어폭스를 예시를 들고 있다.  

 

브라우저의 주요 기능은 사용자가 선택한 자원(HTML, PDF..)을 서버에 요청하고 브라우저에 표시하는 것이다. 최근의 브라우저들은 과거로부터 발전하면서 서로의 브라우저의 장점을 모방하면서 발전을 하였고 W3C에서 정한 웹 표준을 지키기 시작했다. 이런 브라우저들이 가지고 있는 사용자 인터페이스의 요소들은 아래와 같다.

 

URI를 입력할 수 있는 주소 표시 줄
이전 버튼과 다음 버튼
북마크
새로 고침 버튼과 정지 버튼
홈 버튼

 

 

gs.statcounter.com/

 

StatCounter Global Stats - Browser, OS, Search Engine including Mobile Usage Share

Tracks the Usage Share of Search Engines, Browsers and Operating Systems including Mobile from over 10 billion monthly page views.

gs.statcounter.com

 

 


브라우저의 기본 구조

 

출처: html5rocks, 네이버 D2

기본 구조를 알아야 아래 나올 내용들을 이해하기가 조금 수월해진다. 

위에서 아래 순으로 하나씩 살펴보자.

  1. 사용자 인터페이스
    • 요청한 페이지를 보여주는 창을 제외한 나머지 부분이다. ex. 주소 표시줄, 이전/다음 버튼, 북마크 메뉴...
  2. 브라우저 엔진
    • 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다.
  3. 렌더링 엔진
    • 요청한 콘텐츠를 표시한다. 다시 말해, HTML 요청 -> HTML과 CSS를 파싱(분석) 하여 화면에 보이게 한다.
  4. 통신
    • 네트워크 호출에 사용된다. ex.HTTP
  5. 자바스크립트 해석기
    • 자바스크립트 코드를 해석하고 실행한다.
  6. UI 백엔드
    • 기본적인 장치를 그린다. ex. 콤보 박스, 창
    • 플랫폼별로 명시되지 않은 일반적인 인터페이스를 제공하며 OS UI(Operating System User Interface)를 사용한다.
  7. 자료 저장소
    • 자료를 저장하는 계층이다. 쿠키와 같은 종류의 데이터를 브라우저는 필요하게 되는데 로컬 저장소, IndexedDB, WebSQL and FileSystem와 같은 저장소 메커니즘을 지칭한다.

 


렌더링 엔진

렌더링 엔진은 사용자가 요청한 내용을 브라우저에 보여주는 것(rendering)이다.

PDF와 같은 유형도 보여주게 할 수 있지만 이 글에서는 HTML, CSS를 중점을 두었다. 

 

렌더링을 하기 위해서는 렌더링 엔진이라는 것이 필요하다. 위에서 언급했듯이 이 글에서 다루는 브라우저는 크롬과 파이어폭스, 2가지라고 이야기했듯이 렌더링 엔진도 크롬과 파이어폭스의 렌더링 엔진을 이야기할 것이다. 

 

렌더링 엔진은 통신으로부터 요청한 문서의 내용을 얻는 것으로 시작한다. 

*바로 나오는 흐름을 잘 기억하면 이후 내용에 도움이 된다.

 

 

 

출처: html5rocks

 

출처 네이버 D2

 

 

DOM 트리 구축 위한 HTML 파싱

렌더링 엔진이 HTML 문서를 파싱 하며 "콘텐츠 트리"라고 불리는 태그를 DOM 노드로 변환한다. 

 

렌더 트리 구축

그다음 외부 CSS 파일과 스타일 요소를 파싱 한다. 

스타일 정보와 HTML 표시 규칙은 "렌더 트리"라고 부르는 트리를 생성한다.

렌더 트리는 정해진 순서대로 화면에 표시한다.

 

렌더 트리 배치

이후, 각 노드가 화면의 정확한 위치에 표시되는 "배치"가 시작된다. 

 

렌더 트리 그리기

마지막으로, UI 백엔드에서 렌더 트리의 노드를 탐색하여 해당하는 형상을 그리게 된다. 

 

위의 점진적인 과정의 흐름을 이해하는 것이 중요하다. 더 나은 사용자 경험을 위해, 렌더 트리가 다 만들어지지 않았음에도 불구하고, 렌더링 엔진에서는 가능하면 빨리 화면에 콘텐츠를 띄우려고 한다.  다시 말해, 네트워크로부터 나머지 내용이 오는 것을 기다리는 동시에 이미 받은 내용을 화면에 표시를 한다고 이야기할 수 있다.  - 비동기 처리를 한다는 것을 말하는 것 같다.

 

브라우저마다 렌더링 동작 과정이 다르게 되는데 크롬의 렌더링 엔진인 웹킷(Webkit) 엔진과

파이어폭스의 렌더링 엔진인 게코(Gecko) 엔진의 동작 과정을 살펴보자.

 

 

크롬의 렌더링 엔진: 웹킷(Webkit) 엔진의 동작 과정

출처: 네이버 D2, Slideshare(Saltlux)

 

 

 

두 렌더링 엔진의 동작 과정에서 다루는 용어상 차이는 존재하지만 기본적인 동작 과정은 같다는 것을 확인할 수 있다.

 

 

 

파이어폭스의 렌더링 엔진: 게코(Gecko) 엔진의 동작 과정

 

출처: 네이버 D2, Slideshare(Saltlux)

 

 


파싱과 DOM 트리 구축

파싱은 렌더링 엔진에서 매우 중요한 과정이므로 더 자세히 다룰 필요가 있다. 

문서를 파싱 하는 것은 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미한다. 파싱 결과는 문서 구조를 나타내는 노트 트리이다. 노트 트리는 파싱 트리와 문법 트리라고 부른다.

 

 

예)  표현식 '2 + 3 - 1' 이 트리로 나타내면 

출처: 네이버 D2

 

파싱 할 수 있는 모든 형식은 정해진 용어와 구문 규칙을 따라야 하는데 이것은 문맥 자유 문법(context free grammar)이라고 한다. 파싱은 어휘 분석과 구문 분석으로 구분할 수 있다. 

 

먼저, 어휘 분석은 자료를 토큰으로 분해하는 과정이다. 토큰은 인간의 언어에 비유하면 사전의 등장하는 단어를 나타낸다. 

다음 구문 분석은 언어의 구문 규칙을 적용하는 과정이다.

 

어휘 분석은 어휘 분석기(혹은 토큰 분석기)가 있고 구문 분석은 (문서 구조 분석하여 나오는) 파싱 트리를 생성하는 파서가 있다. 

 

출처: 네이버 D2

 

 

파싱 과정은 보통 어휘 분석기로부터 새 토큰을 받아서 구문 규칙과 일치하는지 확인한다.  

만약, 규칙이 맞으면 토큰에 해당하는 노드가 파싱 트리에 추가되고 파서는 또 다른 토큰을 요청한다.

 

 

 

출처: 네이버 D2

 

 

이후, 파싱은 기존의 문서를 다른 양식으로 변환하는 '컴파일'을 한다.

즉, 소스 코드를 기계 코드로 변환하는 컴파일러는 파싱 트리를 만들고 이를 기계 코드로 변환한다.

 

 

위에서 예로 든 '2 + 3 - 1'를 파싱을 해본다면,

 

구문(Syntax):
1. 언어 구문의 기본적인 요소는 표현식, 항, 연산자이다.
2. 언어에 포함되는 표현식의 수는 제한이 없다.
3. 표현식은 "항" 뒤에 "연산자" 그 뒤에 또 다른 항이 따르는 형태로 정의한다.
4. 연산자는 더하기 토큰 또는 빼기 토큰이다.
5. 정수 토큰 또는 하나의 표현식은 항이다

 

구문 5를 기준으로, '2'는 하나의 항이 된다.

구문 4를 기준으로, '2' 다음 + 가 올 수 있다.

구문 3을 기준으로, '항'이나 '연산자' 다음에 또 다른 항이 올 수 있으므로, '2 + 3' 이 성립된다.

구문 4와 3을 기준으로, '2 + 3'은 (새로운) 항이므로 '2 + 3' 다음에 '-'와 '1'이 올 수 있다.

결국, '2 + 3 - 1'은 하나의 표현식이 된다. 

 

 

HTML 파서와 DTD, DOM

파싱은 CSS와 자바스크립트를 파싱 하는 데 사용된다. HTML은 파서가 요구하는 문맥 자유 문법에 의해 쉽게 정의할 수 없다. DTD라고 HTML를 위한 공식적인 형식이 있지만 문맥 자유 문법이 아니다. 

 

(확실한 것은 확인해봐야겠지만, 문맥상) 그래서 DOM이 HTML를 파싱 하는 데 사용 과정의 일부분으로 추측된다. 

 

파싱 트리는 DOM 요소와 속성 노드의 트리로서 출력 트리가 된다. DOM은 문서 객체 모델(Document Object Model)의 줄임말로서 HTML 문서의 객체 표현이자 HTML 요소의 연결 지점이다. 

 

DOM은 마크업과 1:1 관계를 맺는다.

 <html>
  <body>
   <p>Hello World</p>
   <div><img src="example.png" /></div>
  </body>
</html>  

 

 

위 마크업이 아래의 DOM 트리로 변환한다.

 

 

출처: 네이버 D2

 

 

 

 

파싱 알고리즘: 토큰 알고리즘 & 트리 구축 알고리즘

 

파싱 알고리즘은 토큰화와 트리 구축, 2단계로 되어 있다. 

토큰화는 토큰을 인지하여 트리 생성자로 넘기고 다음 토큰을 확인하기 위해 다음 문자를 확인한다. 

입력의 마지막까지 이 과정을 반복한다.

 

 

출처: 네이버 D2

 

 

다음은 토큰 알고리즘이다.

 

 <html> -- 1
   <body> -- 2
      Hello world -- 3
   </body> -- 4
</html>  -- 5

 

 

초기 상태는 "자료 상태"이다. 

 

1번

상태는 '<'에서 "태그 열림 상태"로 변하며, '>'를 만나기 전까지 a ~ z까지 문자를 만나면 "시작 태그 토큰"을 생성하고 상태는 "태그 이름 상태"로 변한다. 이때 각 문자에 새로운 토큰 이름이 붙는데 이 토큰을 html 토큰이라고 한다.

 

2번

'>'를 만나게 되면 현재 토큰이 발행되고 상태는 "자료 상태"로 바뀐다.  body 토큰도 윗 문장의 절차대로 생성이 된다.

 

3번

현재 자료 상태이다. Hello world의 H  문자를 만나게 되면 "문자 토근"이 생성되고 발생될 것이다. Hello world 각 문자에 각 문자 토큰이 발행된다.

 

4번 , 5번

'/' 문자는 종료 태그 토큰을 생성하고 "태그 이름 상태"로 변경된다. 이 상태는 '>'를 만날 때까지 유지된다. 그리고 새로운 태그 토큰이 발행되고 다시 "자료 상태"가 된다.

 

 

 

출처: 네이버 D2

 

 

마지막 트리 구축 알고리즘이다.

트리 구축 단계의 입력 값은 토큰화 단계에서 만들어지는 일련의 토큰이다. 

출처: 네이버 D2

 

 

 

1. 받은 html 토큰은 "html 이전" 모드가 되고 토큰은 이 모드에서 처리된다. 이것은 HTMLHtmlElement 요소를 생성하고 문서 객체의 최상단에 추가된다.

2. 상태는 "head 이전" 모드로 바뀌었고 "body" 토큰을 받았다. "head" 토큰이 없더라도 HTMLHeadElement는 묵시적으로 생성되어 트리에 추가될 것이다.


3. "head 안쪽" 모드로 이동했고 다음은 "head 다음" 모드로 간다. body 토큰이 처리되었고 HTMLBodyElement가 생성되어 추가됐으며 "body 안쪽" 모드가 되었다.


4. "Hellow world" 문자열의 문자 토큰을 받았다. 첫 번째 토큰이 생성되고 "본문" 노드가 추가되면서 다른 문자들이 그 노드에 추가될 것이다.


5. body 종료 토큰을 받으면 "body 다음" 모드가 된다. html 종료 태그를 만나면 "body 다음다음" 모드로 바뀐다. 마지막 파일 토큰을 받으면 파싱을 종료한다.

 

 

 

출처: 네이버 D2

 

 

파싱이 끝난 이후의 동작

브라우저는 이제 문서와 상호 작용할 수 있게 되었고 문서 파싱 이후에 실행되어야 하는 "지연" 모드 스크립트를 파싱 하기 시작한다.

문서 상태는 "완료"가 되고 "로드" 이벤트가 발생한다. 

 

 

 

CSS 파싱

CSS 파일은 스타일 시트 객체로 파싱 되고 각 객체는 CSS 규칙을 포함한다. CSS 규칙 객체는 선택자와 선언 객체 그리고 CSS 문법과 일치하는 다른 객체를 포함한다.

 

 

 

출처: 네이버 D2

 

 


배치

DOM 트리가 구축되는 동안 브라우저는 렌더 트리를 구축한다. 표시해야 할 순서와 문서의 시각적인 구성 요소로써 올바른 순서로 내용을 그려낼 수 있도록 하기 위한 목적이 있다.

파이어폭스는 이 구성 요소를 "형상(frames)"이라고 부르고 웹킷은 "렌더러(renderer)" 또는 "렌더 객체(render object)"라는 용어를 사용한다.

렌더러는 자신과 자식 요소를 어떻게 배치하고 그려내야 하는지 알고 있다.

 

런더러가 생성되어 트리에 추가될 때 크기와 위치 정보는 없는데 이런 값을 계산하는 것을 배치 또는 리플로라고 부른다.

 

배치는 반복되며 HTML 문서의 <html> 요소에 해당하는 최상위 렌더러에서 시작한다. 배치는 프레임 계층의 일부 또는 전부를 통해 반복되고 각 렌더러에 필요한 크기와 위치 정보를 계산한다.

 

 

 

그리기

그리기 단계에서는 화면에 내용을 표시하기 위한 렌더 트리가 탐색되고 렌더러의 "paint" 메서드가 호출된다. 그리기는 UI 기반의 구성 요소를 사용한다.

 

 

 

마치는 말

글쓴이가 들어가는 말에서 밝힌 출처의 글을 기준으로 글을 정리해보았다. 생각보다 정리하기 힘든 과정이었다. 힘들었던 만큼 정리가 잘 되어서 읽었을 때 머릿속에 정리가 잘 되었으며 하는 바람이 있지만 아직 많이 부족한 터라 노력이 더 필요해 보인다. 아무쪼록 이 요약한 글을 통해 이해가 조금이라도 더 되었으면 좋겠다. 가능하다면, 본문과 번역본을 비교해보는 것도 좋은 방법일듯하다. 번역으로부터 오는 매끄럽지 않은 부분은 필연이라고 본다.  

 

 

 

출처

 

 

반응형

'CS > Terminology' 카테고리의 다른 글

npm init -y 란?  (1) 2021.08.11
#9. Method vs Function in Javascript  (0) 2021.04.09
#11. What is a Fork in Git  (0) 2021.01.24
#10. HTTP Method Anatomy  (0) 2021.01.24
#8. res.json vs res.send vs res.end  (0) 2020.12.17