
브라우저(Browser)란?
브라우저는 웹 서버에서 이동하며(navigate) 쌍방향으로 통신하고 HTML 문서나 파일을 출력하는 GUI 기반의 응용 소프트웨어다.
우리는 흔히 크롬(Chrome), 파이어폭스(Firefox), 사파리(Safari) 등 다양한 브라우저를 통해 원하는 정보를 찾곤 합니다. 이 뜻은 우리가 브라우저라는 소프트웨어를 이용하여 웹 서버에 리소스를 요청(Request)하는 것과 같습니다.
즉, 사용자(Client)가 브라우저(Browser)를 통해 어떠한 데이터를 서버로 요청하면 서버는 브라우저에게 해당 데이터에 해당하는 HTML문서를 전달하여 브라우저는 해당 데이터를 해석 후, 사용자(Client)에게 보여주는 역할을 수행합니다.
요약하자면 브라우저(Brower)는 서버와 쌍방향으로 통신할 수 있으며 HTML 문서나 파일 혹은 정보 등을 주고 받을 수 있는 GUI 응용 소프트웨어를 말합니다.

브라우저의 핵심 기능은 사용자가 참고하고자 하는 페이지를 서버에 요청(Request)하고 서버의 응답(Response)를 받아 브라우저에 표시하는 것 입니다. - poiemaweb
사용자가 브라우저를 통해 서버에 요청을 한다면 서버로부터 HTML, CSS, Javascript 혹은 다양한 미디어 파일 등을 응답받게 됩니다. 이때, HTML, CSS 파일은 렌더링 엔진의 HTML 파서와 CSS 파서에 의해 파싱(Parsing)되어 DOM, CSSOM 트리로 변환되며 렌더 트리로 결합됩니다.
이렇게 생성된 렌더 트리를 기반으로 브라우저는 사용자에게 웹 페이지를 표시하게 됩니다.
브라우저는 웹 표준화 기구 W3C(World Wide Web Consortium)에서 정한 HTML과 CSS 명세에 따라 HTML을 해석하여 표시합니다. 과거에는 다양한 브라우저들이 해당 명세의 일부만 구현하거나 준수하지 않고 계속 확장하여 호환성 문제를 수없이 겪었지만 최근 대부분 브라우저가 표준 명세를 따르기에 이러한 현상은 사라졌습니다.

브라우저의 주요 구성 요소로는 사용자 인터페이스, 브라우저/렌더링 엔진, 통신, UI 백엔드, JS 해석기, 저장소가 있습니다.
사용자 인터페이스는 주소 표시줄, 이전 / 다음버튼, 북마크 메뉴와 같은 요청한 페이지를 보여주는 화면을 제외한 모든 부분을 말합니다.
브라우저 엔진은 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어합니다.
렌더링 엔진은 사용자가 요청한 콘텐츠를 표시합니다. 만약, 사용자가 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시시키게 됩니다.
렌더링 엔진은 HTML과 XML 문서, 이미지, PDF 등 많은 확장 기능을 사용한다면 다양한 유형의 자료 또한 표시할 수 있습니다. 브라우저 별 사용하는 렌더링 엔진이 다르기 때문에 모든 브라우저가 동일한 소스를 화면에 동일하게 표시하지 않습니다. 이 때문에 크로스 브라우징 이슈가 발생하기도 합니다. 각 브라우저 별 사용되는 렌더링 엔진은 아래와 같습니다.


대중적으로 많이 사용되는 크롬, 사파리의 렌더링 엔진 웹킷(Webkit)의 동작 방식

렌더링 엔진은 서버로부터 전달받은 HTML 문서를 네트워크 계층(Network Layer)에서 가져온 뒤 아래와 같은 순서를 진행합니다.
(1) HTML 파싱 후 DOM 트리 만들기
렌더링 엔진은 네트워크 계층을 통해 전달받은 HTML문서를 파싱하여 각 요소(Element)들을 DOM Tree를 구성하는 각각의 노드로 전환하게 됩니다.
<html>
<body>
<p>I wanna go home.. now..</p>
<div><img src="dxxh_e.png"></div>
</body>
<html>
위 html 코드는 아래와 같은 DOM 트리로 변환할 수 있습니다.

(2) 렌더 트리(Render Tree) 만들기

위 사진은 DOM 트리와 렌더 트리의 대응 관계를 시각화한 이미지.
HTML문서를 파싱하여 DOM 트리가 만들어졌다면 렌더링 엔진은 CSS, Style 데이터를 파싱하고 해당 데이터들로 렌더 트리(Render Tree)를 만듭니다.
즉, DOM 트리는 화면에 나타낼 내용을 구현한다면 렌더 트리는 어떻게(시각적) 나타낼 지 구성합니다.
(3) 렌더 트리 레이아웃(Render Tree Layout) 만들기
(1)과 (2)에서 만든 트리 기반의 노드들에게 스크린의 어느 공간에 위치해야할 지 각각의 값을 부여시킵니다.
(4) 렌더 트리 페인팅(Render Tree Painting)
렌더 트리가 만들어져 레이아웃까지 구현이 완료되었다면, UI 백엔드가 동작하여 각 노드들을 정해진 스타일과 위치 정보대로 화면에 배치시킵니다.
이때, 렌더링 엔진은 각 컨텐츠를 가능한 빨리 출력시켜야 하기 때문에 모든 HTML 요소들을 렌더링 엔진으로 한 번에 출력시키는 것이 아닌, 일부 컨텐츠는 순차적으로 먼저 트리 과정을 거쳐 스크린에 출력시키게 됩니다. 출력시키는 중에 나머지 컨텐츠들은 네트워크를 통해 렌더링으로 읽어들여 순차적으로 입출력을 진행합니다.
통신은 HTTP 요청과 같은 네트워크 호출에 사용됩니다. 즉, 서버와 통신이 가능하도록 도와주는 역할을 수행합니다.
UI 백엔드는 렌더 트리 페인팅을 통해 그려진 컨텐츠들을 구동이 가능하도록 도와줍니다. 또한 OS 사용자 인터페이스 체계를 사용합니다.
JS 해석기는 뜻 그대로 자바스크립트 코드를 해석(파싱)하고 실행하는 역할을 수행합니다.

자바스크립트는 렌더링 엔진이 아닌 자바스크립트 엔진이 처리합니다.
렌더링 엔진에서 작업중인 HTML 파서는 script 태그를 만나면 JS 코드를 실행하기 위해 DOM 생성 프로세스를 중지하고 자바스크립트 엔진으로 제어 권한을 넘기게 됩니다.
제어 권한을 받은 JS 엔진은 script 태그의 JS 파일을 로드하고 실행합니다. JS의 실행이 완료되면 다시 HTML 파서로 제어 권한을 넘겨 브라우저(렌더링 엔진)가 중지했던 시점부터 DOM 생성을 재개합니다.
이때, 브라우저는 동기(Synchronous)적으로 HTML, CSS, JS를 처리합니다. 이는 script 태그의 위치에 따라 블로킹이 발생하여 DOM 생성에 영향이 끼친다는 것을 의미합니다. 따라서 우리가 흔히 아는 script 태그의 위치가 중요한 이유는 위와 같은 이유가 있기 때문입니다.
저장소는 자료를 저장하는 계층이며 쿠키와 같은 로컬 데이터를 저장하는 역할을 수행합니다.