📌 브라우저의 주요 기능
- 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시하는 것
- 자원의 주소는
URI(Uniform Resource Indentifier)에 의해 정해진다.
- 자원은 HTML, PDF, 이미지 혹은 다른 형태이다.
📌 브라우저의 호환성
- 웹 표준: 웹에서 표준적으로 사용되는 기술이나 규칙
- 웹 상에서 사용되는 모든 파일은 이러한 '웹 표준'을 가지게 되어 브라우저 내에서 어떠한 데이터 및 파일과도 상호작용이 가능하다.
- 이러한 웹 표준은
W3C(World Wide Web Consortium)라는 기구에 의해 명세되었고, 이들은 웹 상호운용성('어떠한 소프트웨어나 하드웨어에서도 웹에 접근할 수 있어야 한다')를 위해 노력 중이다.
📌 브라우저의 기본 구조

1. 사용자 인터페이스
- 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분
- URI를 입력할 수 있는 주소 표시줄
- 이전 버튼과 다음 버튼
- 북마크
- 새로 고침 버튼과 현재 문서의 로드를 중단할 수 있는 정지 버튼
- 홈 버튼
- 사용자 인터페이스는 표준 명세가 없음에도 불구하고, 수 년간 서로의 장점을 모방하면서 현재에 이르게 되었다.
- HTML5 명세는 주소 표시줄, 상태 표시줄, 도구 모음과 같은 일반적인 요소를 제외하고 브라우저의 필수 UI를 정의하지 않았다.
- 브라우저 엔진
- 사용자 인터페이스와 렌더링 엔진 사이의 동작 제어
- 렌더링 엔진
- 서버에 요청해서 가져온 컨텐츠 표시 (HTML을 요청하면 HTML과 CSS를 파싱하여 표시)
- 통신
HTTP 요청과 같은 네트워크 호출에 사용된다.
- 플랫폼 독립적인 인터페이스이고 각 플랫품 하부에서 실행된다.
- UI 백엔드
- 콤보박스와 창 같은 기본적인 UI 장치를 그린다.
- 예를 들어,
<button>이나 <input> 태그를 그랠 때, 이 태그에 관한 스타일을 따로 적용하지 않아도 브라우저는 이에 맞는 UI 화면을 그리게 된다.
- 자바스크립트 해석기
- 자료 저장소
- 모든 종류의 자원을 하드 디스크에 저장 (쿠키, 로컬 스토리지 등)
** 크롬은 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지한다. 각 탭은 독립된 프로세스로 처리된다.
📌 렌더링 엔진
- 렌더링 엔진은 요청 받은 내용을 브라우저 화면에 표시한다.
- 파이어폭스는 모질라에서 직접 만든 게코(
Gecko) 엔진을 사용하고 사파리와 크롬은 웹킷(Webkit) 엔진을 사용한다.
📙 동작 과정

1. HTML 문서를 파싱하여 DOM(Document Object Model) 트리를 구축한다.
2. 외부 CSS 파일과 함께 임베디드 스타일, 인라인 스타일, 브라우저 상에서 기본적으로 가지고 있는 스타일 요소들을 파싱하여 CSSOM 트리를 생성한다.
3. DOM 트리와 CSSOM 트리를 결합하여 렌더 트리를 생성한다.
4. 렌더 트리의 각 노드의 화면(뷰포트 기준)에서의 정확한 위치와 크기를 결정한다.
5. UI 백엔드가 동작하여 렌더 트리의 각 노드의 정해진 스타일, 위치, 크기에 따라 화면의 픽셀 값으로 나타내어 그린다.
- 일련의 과정들이 점진적으로 진행된다.
- 좀 더 나은 사용자 경험을 위해 모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다.
- 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시하는 것이다.
- 웹킷의 동작 과정

- 게코의 동작 과정

✨ DOM (Document Object Model) 트리 생성
- 브라우저는 읽어들인 HTML 바이트 데이터를 해당 파일에 지정된 인코딩 방식에 따라 문자열로 바꾸고, HTML 표준에 따라 문자열을 토큰으로 변환한다.
- 토큰들을 다시 노드로 바꾸는 과정을 거쳐 DOM 트리가 생성된다.
✨ CSSOM (CSS Object Model) 트리 생성
- CSS 또한 HTML과 마찬가지로, 바이트를 문자로 변환 -> 토큰화 -> 노드로 변환 -> CSSOM 트리 구축 과정을 거치게 된다.

✨ 렌더 트리 (DOM + CSSOM) 생성
- 렌더 트리에는 페이지를 렌더링하는데 필요한 노드(화면에 유효한 노드)만 포함된다.
- 렌터 트리는 페이지에 표시되는 모든 DOM 컨텐츠와 각 노드에 대한 모든 스타일 정보를 갖고 있다.
렌터링 트리 생성 과정
- DOM 트리의 루트에서 시작하여 순회한다.
- 렌더링이 되지 않는
<script>, <meta> 태그와 같은 노드들은 렌더링 트리에서 생략된다.
- 일부 노드는 CSS를 통해 숨겨지며, 렌더링 트리에서도 생략된다. 예를 들면
display:none 속성을 갖는 노드는 렌더링 트리에서 생략된다.
- 표시된 각 노드에 대해 매칭되는 CSSOM 규칙을 찾고, 적용한다.
- 표시된 노드를 컨텐츠와 스타일과 함께 내보낸다.

✨ 렌더 트리 배치 - 레이아웃, 리플로우
- 렌더 트리는 위치와 크기에 대한 정보가 없기 때문에, 뷰포트를 기준으로 각 노드들의 화면에서의 위치와 크기를 결정해준다.
- 모든 상대적인 측정값은 화면에서의 절대적인 픽셀값으로 변환된다.
✨ 렌더 트리 그리기 - 'painting' or 'rasterizing'
- 렌더 트리를 전체적으로 탐색하며 각 렌더러(노드)의
paint 메서드가 호출된다.
UI 백엔드가 동작하여 렌더 트리의 각 노드를 화면에 그린다.
- 모든 노드가 그려진 후 일부 변경이 생길 경우에는, 해당 렌더러와 그 자식의 배치 과정과
repaint 메서드가 발생한다.
❗ 자바스크립트는?
- 자바스크립트는 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다.
HTML 파서는 script 태그를 만나면 자바스크립트 코드를 실행하기 위해 DOM 생성 프로세스를 중지하고 자바스크립트 엔진으로 제어 권한을 넘긴다.
- 제어 권한을 넘겨 받은 자바스크립트 엔진은
script 태그 내의 자바스크립트 코드 또는 script 태그의 src 어트리뷰트에 정의된 자바스크립트 파일을 로드하고 파싱하여 실행한다.
- 자바스크립트의 실행이 완료되면 다시
HTML 파서로 제어 권한을 넘겨서 브라우저가 중지했던 시점부터 DOM 생성을 재개한다.
- 예외 :
script 태그가 defer 속성을 가질 경우 HTML 파싱은 계속 실행되고 완료된 후에 자바스크립트가 실행된다.
❗ JS와 CSS
브라우저는 동기(Synchronous)적으로 HTML, CSS, Javascript을 처리한다.
JS
- 자바스크립트는 파서 차단 리소스이다. (
parser blocking resource)
- 앞서 살펴봤듯이 HTML 파서가
script 태그를 만나면 진행하던 파싱을 중단하고 자바스크립트 엔진에게 제어 권한을 넘겨 자바스크립트 코드를 파싱하고 실행한다.
- 따라서 script 태그의 위치에 따라 블로킹이 발생하여 DOM의 생성이 지연될 수 있다.
- 그래서 보통 자바스크립트를
head 태그가 아닌 body 태그가 닫히기 바로 전에 위치시킨다.
- 스크립트 로딩 지연으로 인해 HTML 요소들의 렌더링에 지장 받는 일이 발생하지 않아 페이지 로딩 시간이 단축된다.
DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작한다면 에러가 발생한다.
CSS
- CSS는 렌더링 차단 리소스 이다. (
render blocking resource)
- CSS는 렌더링을 할 때 반드시 필요한 리소스이기 때문에 브라우저는 빠르게 CSS를 파싱하는 것이 좋으므로
<head> 태그 안에서 정의하여 빠르게 리소스를 받을 수 있도록 해야 한다.
참고