브라우저(Browser)는 웹 서버의 모든 정보를 볼 수 있도록 하고, 문서 검색을 도와주는 응용 프로그램이다. 우리가 인터넷에 접속하기 위해 사용하는 chrome, safari, edge, firefox 등이 바로 브라우저다.
웹 브라우저는 웹 페이지를 가져오기 위해 대부분의 웹 서버가 사용하는 HTTP로 통신한다. HTTP를 이용해 웹 페이지를 가져올 뿐 아니라 웹 서버에 정보를 송신하기도 한다.
브라우저의 주요 기능은 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것이다. 자원은 HTML, CSS, PDF, 이미지 또는 다른 형태일 수 있다. 자원의 주소는 URI에 의해 정해진다.
URI와 URL의 차이점
URI(Uniform Resource Identifier)는 특정 리소스를 식별하는 통합 자원 식별자를 의미한다. 웹 기술에서 사용하는 논리적 또는 물리적 리소스를 식별하는 고유한 문자열 시퀀스다.
URL은 흔히 웹 주소라고도 하며, 컴퓨터 네트워크 상에서 리소스가 어디에 있는지 알려주기 위한 규약이다. URI의 서브셋이다.
각 브러우저는 서로 다른 데이터 해석 방식을 가지고 HTML 파일을 해석해서 표시한다. 이로 인해 발생할 수 있는 호환성 문제를 해결하기 위해 최근 대부분의 브라우저는 웹 표준화 기구인 W3C(World Wide Web Consortium)에서 정한 명세를 따른다. 브라우저 사용자 인터페이스의 경우 표준 명세가 없음에도 불구하고 수 년간 서로의 장점을 모방하면서 비슷한 요소들을 갖추게 되었다.
사용자 인터페이스 : 검색창, 새로고침, 뒤/앞으로 가기 버튼 등 사용자가 접근할 수 있는 영역이다.
브라우저 엔진 : 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다.
렌더링 엔진 : 요청한 콘텐츠를 화면에 표시한다. HTML과 CSS 등을 파싱하여 화면에 표시하는 엔진이다.
통신 : HTTP 요청과 같은 네트워크 호출에 사용된다. 이것은 브라우저마다 독립적인 인터페이스이고 각 브라우저 하부에서 실행된다.
UI 백엔드 : 기본적인 위젯을 그린다. OS 사용자 인터페이스 체계를 사용한다.
자바스크립트 해석기 : 자바스크립트 코드를 해석하고 실행한다.
자료 저장소 : 자료를 저장하는 계층이다. Cookie, Local Storage, Indexed DB 등 브라우저 메모리를 활용하여 저장하는 영역이다.
크롬은 대부분의 브라우저와 달리 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지한다. 즉, 각 탭은 독립된 프로세스로 처리된다.
렌더링 엔진은 HTML, XML 문서, 이미지 등 요청받은 내용을 브라우저 화면에 표시해준다. 플러그인이나 브라우저 확장 기능을 이용해 PDF와 같은 다른 유형도 표시할 수 있다.
파이어폭스와 크롬, 사파리는 두 종류의 렌더링 엔진으로 제작되었다. 파이어폭스는 게코(Gecko)엔진을, 사파리와 크롬은 웹킷(Webkit)엔진을 사용한다.
각 브라우저마다 렌더링 엔진이 다르기 때문에 같은 웹 페이지더라도 다르게 보이는 경우가 있다. 개발자 도구 Elements 탭에서 아래와 같은 코드를 본 적이 있을 것이다. 브라우저마다 적용되는 옵션이나 지원하는 표준이 다르기 때문에 적용되는 코드가 다른 것을 볼 수 있다.
-moz-border-radius: 1em; // 파이어폭스 브라우저에 적용
-ms-border-radius: 2em; // 익스플로어에 적용, 보통 생략
-o-border-radius: 3em; // 오페라에 적용
-webkit-border-radius: 4em; // 구글, 사파리 브라우저에 적용
다음은 렌데링 엔진의 동작 과정이다.
렌더링 엔진은 통신으로부터 요청한 문서의 내용을 얻는 것으로 시작하는데 문서의 내용은 보통 8KB 단위로 전송된다. 브라우저는 렌더링 할 문서를 HTML과 CSS로 나눠서 읽게 된다. 이 둘은 단순한 텍스트이므로 각각 연산과 관리가 가능하도록 HTML 파서와 CSS 파서를 사용해 관리가 가능한 Object Model로 만든다.
렌더링 엔진은 좀 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시하는데 모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다. 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시하는 것이다.
DOM(Document Object Model, 문서 객체 모델)은 문서의 구조화된 표현을 제공한다. 그리고 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다.
CSSOM(CSS Object Model)은 Javascript에서 CSS를 조작할 수 있는 API 집합이다. HTML 대신 CSS가 대상인 DOM이라고 생각할 수 있으며, 사용자가 CSS 스타일을 동적으로 읽고 수정하라 수 있는 방법이다.
DOM 트리와 CSSOM 트리를 결합하여 표시해야 할 순서로 내용을 그려낼 수 있도록 하기 위해 렌더 트리(Render Tree)를 구축한다. 렌더 트리는 표시되는 각 요소의 레이아웃을 계산하는데 사용되고, 픽셀을 화면에 렌더링하는 페인트 프로세스에 대한 입력으로 처리된다.
렌더 트리가 생성된 후, 각 노드에 대해 화면 상에서 배치될 정확한 위치와 크기를 계산한다. 이때 모든 상대적인 값이 픽셀 값으로 변환된다. 이 과정을 배치(Layout) 또는 Reflow라고 한다.
UI 백엔드에서 렌더 트리의 각 노드를 그린다.
Reflow와 Repaint
렌더링 과정을 모두 마친 후 최종적으로 브라우저에 페이지가 그려진다. 하지만 특정 액션이나 이벤트에 따라 레이아웃 수치가 변하면 해당 요소의 영향을 받는 자식 노드나 부모 노드들을 포함하여 Reflow 과정을 다시 수행하게 된다.
이 경우 각 요소들의 크기와 위치를 다시 계산하는데 이 과정을 Reflow라 하고, Reflow 된 렌더 트리를 다시 화면에 그려주는 과정을 Repaint 라고 한다.
다음은 렌더링 엔진 중 하나인 웹킷 엔진의 동작 과정을 나타낸 그림이다.
여기서 어태치먼트(attachment)는 웹킷이 렌더 트리를 생성하기 위해 DOM 노드와 시각 정보를 연결하는 과정이다.
위에서 설명한 동작 과정과 유사하다. 정리하자면, 응답 받는 HTML, CSS 파일들은 HTML 파서와 CSS 파서에 의해 파싱되어 각각 DOM, CSSOM 트리로 변환되고 렌더 트리로 결합하여 화면에 렌더링 해준다.
브라우저는 어떻게 동작하는가?
DOM이란?
DOM, CSSOM, 브라우저 렌더링 용어 설명
DOM, CSSOM 생성 과정