Web/javascript

[JS] 브라우저는 어떻게 동작하는가? 요약 및 정리(1)

Razelo 2021. 2. 24. 11:42

브라우저의 동작에 대해서 아주 잘 설명해놓은 글이 있어 이를 읽고 간단하게 정리해보고자 한다. 

 

브라우저의 주요 기능은 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것이다. 

 

자원의주소는 URI로 표현된다.

 

최근 브라우저들이 표준 명세를 따르고 있기 때문에 호환성 문제가 줄어들었다. 

 

브라우저의 기본 구조 

 

브라우저의 기본 구조는 아래와 같다. 

 

 

 

각 구성을 간단하게 설명하면 아래와 같다. 

 

1. 사용자 인터페이스: 우리가 브라우저를 쓸때 보이는 화면이다. 이전버튼, 다음 버튼, 페이지 창 등이 있는 곳이다. 

2. 브라우저 엔진: 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다. 

3. 렌더링 엔진: 사용자가 요청한 컨텐츠를 표시한다. HTML같은 걸 파싱해서 화면에 표시한다고 보면 된다. 

4. 통신: HTTP 요청과 같은 네트워크 호출을 할때 사용된다. 

5. UI 백엔드: 콤보 박스와 창 같은 기본적인 장치를 그린다. 

6. 자바스크립트 해석기: 말 그래도 자바스크립트 코드를 해석하고 실행한다. 

7. 자료 저장소: 자료를 저장한다. 모든 종류의 자원을 하드 디스크에 저장할 필요가 있다고 한다. 

 

크롬의 경우 각 탭마다 별도의 렌더링 엔진  인스턴스를 유지한다고 한다. 그래서 각 탭이 독립된 프로세스로 유지된다고 한다. (개인적으로 이래서 크롬을 사용할 때 리소스를 많이 먹지 않았나 싶다.)

 

렌더링 엔진에 대해서는 파이어폭스는 모질라에서 직접 만든 Gecko 엔진을 사용하고 사파리와 크롬은 Webkit 엔진을 사용한다고 한다. 

 

웹킷은 리눅스를 타킷으로 만들어진 오픈소스이다. 

 

렌더링 엔진

 

렌더링 엔진은 통신으로부터 요청한 문서의 내용을 얻는 것으로 시작한다. 그리고 문서는 보통 8KB 단위로 전송된다고 한다. 

 

렌더링 엔진은 아래와 같은 동작 과정을 거친다고 한다. 

 

 

렌더링 엔진은 HTML 문서를  파싱하고 "콘텐츠 트리" 내부에서 태그를 DOM 노드로 변환한다고 한다. 

그리고 CSS 등 스타일 요소도 파싱한다. 스타일 정보와 HTML 표시 규칙은 렌더 트리라고 부르는 또 다른 트리를 생성한다고 한다. 

 

렌더 트리같은 경우는 색상, 면적과 같은 시각적 속성이 있는 사각형이 포하되있고 이것들이 정해진 순서대로 화면에 표시된다고 한다. 

 

이 렌더 트리 생성이 끝나면 배치가 시작된다. 즉 노드가 화면의 위치에 표시된다. 

 

아래는 UI 백엔드에서 렌더 트리의 각 노드를 가로지르며 형상을 만들어내는 그리기 과정이라고 한다. 

 

웹킷 동작 과정

 

모질라 게코 렌더링 엔진 동작 과정

 

모양새가 다르긴 한데 사실 기본적인 과정은 거의 동일하다고 한다. 

 

게코의 경우 시각적으로 처리되는 렌더 트리를 형상 트리라고 부르고 각 요소를 형상이라고 한다. 웹킷은 반면 렌더 객체로 구성되어 있는 렌더 트리라는 용어를 사용한다고 한다. 

또한 웹킷은 배치라는 용어를 쓰지만 게코는 리플로(reflow)라고 부른다. 

 

파싱과 DOM 트리 구축 

 

파싱은 렌더링 엔진에서 중요한 개념이라고 한다. 

 

2+3-1 을 파싱한 트리 노드

 

문서 파싱은 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 과정이라고 한다. 

그 결과는 문서 구조를 나타내는 노드 트리이고 parse tree 혹은 syntax tree 라고 부른다고 한다. 

 

파싱은 어휘 분석과 구문 문석이라는 두 가지로 구분할 수 있다고 한다. 

어휘 분석은 자료를 토큰으로 분해한다. 

토큰은 용어집이라고 볼 수 있는데 즉 사전에 등장하는 모든 단어 정도로 이해하면 된다. 

 

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

 

파서는 두 가지 일을 하는데 자료를 유효한 토큰으로 분해하는 어휘 분석기(토큰 변환기)가 있고 언어 구문 규칙에 따라 문서 구조를 분석함으로써 파싱 트리를 생성하느 ㄴ파서가 있다. 어휘 분석기의 경우 공백과 줄 바꿈 같은 의미 없는 문자를 제거한다. 

 

문서 소스로부터 파싱 트리를 만드는 과정

 

이 파싱 과정은 반복된다. 

 

파서가 어휘 분석기로부터 새로운 토큰을 받아서 구문 규칙과 일치하는지 확인한다. 그리고 규칙에 맞다면 토큰에 해당하는 노드가 파싱 트리에 추가되고 파서는 계속해서 또 다른 토큰을 요청하게 된다.

 

물론 규칙에 맞지 않는다면 파서가 토큰을 내부적으로 저장하고나서 토큰과 일치하는 규칙이 발견될 때까지 계속 요청한다.

 

맞는 규칙이 아예 없으면 예외인데 이것은 문서 자체가 유효하지 않고 구문 오류를 포함하고 있다는 뜻으로 해석된다. 

 

물론 결과물로 나온 이 파서 트리가 최종 결과물은 아니다. 소스 코드를 기계 코드로 만드는 컴파일러는 파싱 트리 생성 후에 이것응ㄹ 기계 코드 문서로 변환하게 된다.

 

아래가 그 예시이다. 

 

컴파일 과정

 

어휘와 구문에 대한 공식적인 정의 

 

어휘는 보통 정규 표현식으로 표현된다. 

구문은 보통 BNF 라고 부르는 형식에 따라 정의된다고 한다. 

문법이 문맥 자유 문법이라고 한다면 언어는 정규 파서로 파싱할 수 있다. 

문맥 자유 문법이라함은 완전히 BNF 로 표현 가능한 문법이라고 볼 수 있다. 

 

파서의 종류 

 

파서에는 두 가지가 있다고 한다.

 

하향식 파서와 상향식 파서. 

 

말 그대로 하향식 파서는 구문의 상위 구조로부터 일치하는 부분을 찾기 시작하고 상향식 파서는 낮은 수준에서 점차 높은 수준으로 찾는다고 한다. 

 

파서 자동 생성 

파서를 생성해 줄 수 있는 도구를 파서 생성기라고 한다. 파싱을 사람이 직접 하기도 어렵고 수동으로 파서를 최적화하기도 어려운 일이기 때문에 파서 생성기를 사용하는 것이 유용하다고 한다. 

 

웹킷의 경우 두 개의 파서 생성기를 사용하는데 어휘 생성을 위한 플렉스(Flex)와 파서 생성을 위한 바이슨(Bison)이다. 

플렉스는 토큰의 정규 표현식 정의를 포함하는 파일을 입력 받고 바이슨은 BNF 형식의 언어 구문 규칙을 입력 받는다. 

 

HTML 파서 

HTML 파서는 HTML 마크업을 파싱 트리로 변환한다. 

 

HTML은 너그럽다고 한다. 암묵적으로 태그에 대한 생략이 가능하기 때문이다. 

그래서 XML 에 비해서 HTML이 유연한 문법이라고 한다. 

 

이 차이가 큰 차이를 만들었는데 실수를 용서하고 편하게 만들어줬기 때문에 HTML이 인기를 끌게 되었다. 

그런데 이게 또 한편으론 공식적인 문법으로 작성하기 어렵게 만들어서 HTML은 파싱하기 어렵고 전통적인 구문 분석이 불가능하기 때문에 문맥 자유 문법이 아니라는 것이다. 

 

DOM

문서 객체 모델 즉 Document Object Model 의 줄임말이다. 

 

아래와 같은 코드가 있다고 가정해보자. 

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

그렇다면 우리는 아래와 같은 DOM 트리로 변환할 수 있게 된다. 

 

파싱 알고리즘 

이전에도 말했지만 HTML은 일반적인 하향식, 상향식 파서로 파싱이 안된다.

 

그 이유는 다음 세 가지 속성 때문이다. 

1. 언어의 너그러운 속성

2. 잘 알려진 HTML 오류에 대한 브라우저의 관용

3. 변경에 의한 재파싱. 일반적으로 소스는 파싱하는 동안 변하지 않지만 HTML에서 document.write 을 포함한 스크립트 태그는 토큰을 추가할 수 있기 때문에 실제 입력 과정에서 파싱이 수정된다고 한다. 

 

 

그래서 브라우저는 HTML 파싱을 위해 별도의 파서를 생성한다. 

 

그것은 토큰화와 트리 구축이라는 두 단계로 이뤄져있다. 

 

토큰화는 어휘 분석으로서 입력 값을 토큰으로 파싱한다. HTML에서 토큰은 시작 태크, 종료 태그, 속성 이름 및 속성 값이다. 

 

토큰화가 토큰을 인지해서 트리 생성자에 넘기고 다음 토큰을 확인하기 위해 다음 문자를 확인한다. 그리고 마지막까지 이 과정을 계속 반복한다. 

 

아래는 HTML 파싱 과정이다. 

 

 

 

 


굉장히 좋은 글이다. 

 

아래 링크의 글을 한번쯤은 읽어보길 권한다. 

 

물론 기억이 잘 나지 않으면 다시 읽어보자. 

 

d2.naver.com/helloworld/59361

반응형