본문 바로가기
개발/기타

브라우저의 동작원리

by 문둘기 2021. 2. 10.

브라우저란?

월드 와이드 웹(www)을 기반으로한, 인터넷컨텐츠를 검색 및 열람하기위한 소프트웨어

간단하게 말하면, 편안한 웹서핑을 도와주는 소프트웨어다

전세계 5대 브라우저

  • Google Chrome
  • MS Edge (원래 Internet Explorer 였다)
  • Firefox
  • Opera
  • Safari

브라우저의 핵심기능

브라우저의 핵심 기능은 사용자가 보려고하는 웹페이지의 자원을 서버에 요청하고, 응답 받아서 보기좋게 화면에 띄워주는것이다.

여기서 말하는 자원은 보통 HTML 이지만, Image나 PDF 등등 다양하다. 자원의 주소는 URI에 의해 정해진다.

브라우저는 HTML과 CSS를 명세에 따라 해석해서 보여주는데, 명세는 웹 표준화 기구인 W3C에서 정한다. 예전에는 자기 맘대로 해석해서 파편화가 심했지만 지금은 대부분 웹 표준을 따르고있다.

브라우저의 인터페이스(주소창,새로고침버튼,뒤로가기,북마크등등)들은 서로 거의 똑같은데, 딱히 표준은 아니고 서로 장점을 모방하면서 거의 표준처럼 굳어졌다.

브라우저의 기본 구성요소

UI → 우리가 보는 유저 인터페이스

브라우저 엔진 → UI 와 렌더링 엔진 사이의 동작 제어

렌더링 엔진 → 서버에게 응답받은 자원을 파싱해서 화면에 띄우는 작업함(중요)

네트워크 → HTTP 요청과 같은 네트워크 호출을 하는 브라우저 내부 계층

자바스크립트 인터프리터(해석기) → Js 해석하고 실행

UI 백엔드 → 기본적인 위젯 그리는용도(button이나 input 등은 따로 스타일 정의안해도 OS의 UI 체계를 사용)

자료저장소 → 쿠키나 로컬스토리지 등 브라우저 메모리를 활용하여 저장하는 영역

렌더링 엔진의 동작방식

상술했듯이 자원을 화면에 띄우는 작업을한다.

렌더링 엔진은 webkit , blink , gechko 등이 있다. 엔진별로 약간 다르지만 기본적인 동작방식은 비슷하다

  1. HTML을 파싱해서 DOM 트리 빌드
  2. CSS를 파싱해서 CSSOM 트리 빌드
  3. DOM 과 CSSOM 을 결합해 렌더트리 빌드
  4. 렌더 트리에서 레이아웃을 실행하여 각노드의 기하학적 형태 계산
  5. 노드를 화면에 그린다

여기서 Render Tree 는, DOM Tree에 있는것중 실제로 보이는애들로만 구성된다.

예를들면 css에서

display: none→ 화면에 안보이고 레이아웃에서 공간도 차지하지않는다, 그래서 렌더트리에 없다.

visibility: hidden → 화면에 안보이지만 공간을 차지하고있다, 렌더트리에 있다 (비어 있는 상자로 렌더링됨 )

head 태그도 화면에 보이지 않는 요소이므로 렌더 트리에서는 제외된다

6번은 Render Tree가 만들어진뒤, 각 노드 위치를 계산하는과정인데
위치관련된 position, width, height등을 계산한다. 만약 width 100% 인 상태에서 브라우저 사이즈를 조절하면 Render Tree는 그대로고 이후 과정만 다시 반복한다

7번 paint는 화면에 그리는건데
색이 바뀐다거나 노드의 스타일이 바뀌는 걸로는 Layout 과정을 거치지 않고 Paint만 일어난다.

위 일련의 과정들이 점진적으로 진행된다. 렌더링 엔진은 가능하면 빠르게 화면에 표시하기 위해 모든 HTML을 파싱할 때까지 기다리지 않고 배치와 그리기 과정을 시작한다. 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시한다.

Gecko 의 렌더링 과정

JS는 렌더링엔진이 아닌, JS엔진이 처리한다 크롬은 V8이라는 Js엔진을 쓰고있다.

HTML파서는 script태그를 만나면 Js코드실행을위해 DOM생성프로세스를 중지하고 JS엔진으로 제어권한을 넘긴다 제어 권한을 받은 JS엔진은 JS코드를 실행하고, 완료되면 다시 HTML파서로 권한을넘긴다

이처럼 브라우저는 동기적으로 HTML,CSS,JS를 처리한다 script태그의 위치에 따라 블로킹이 발생하여, DOM생성이 지연될수도 있다는뜻이고, 때문에 script태그 위치가 중요하다. 보통 body태그 가장 아래에 둔다

이렇게 할경우 장점은 HTML 파싱할때 스크립트 로딩때문에 블로킹으로 지장 받는 일이 발생하지 않아 페이지 로딩 시간이 단축되고, 아직 DOM이 완성되지 않은 상태에서 JS가 DOM을 조작한다면 에러가 발생하는데 그것도 방지할수있다

<script src="app.js" async></script>
<script src="app.js" defer></script>

스크립트에 async 와 defer 옵션을 줄수도있는데 아래 영상 8:37~부터 정말 잘 설명되어있다.

렌더링 엔진 관련 이야기들

  • 사파리는 Webkit을 사용한다, webkit은 애플에서 개발
  • 크롬은 원래 Webkit을 썼는데, 애플과 경쟁하면서 2013년부터 Blink로 변경, blink는 webkit을 fork한건데, 구글이 파일 7천개를 지우고 최적화하면서 많이 바꿨다고한다. 참고로 오페라,네이버 웨일, 삼성 인터넷앱도 blink를 쓴다.
  • 파이어폭스는 Gechko를 사용한다.
  • IE 는 Trident 를 사용한다.
  • Edge도 원래 Trident fork한 EdgeHTML이라는것을 썼었는데, 포기하고 blink로 변경했다
  • iOS용 웹 브라우저는 webkit 아니면 바로 퇴짜를 맞기때문에 ios용 크롬app 은 blink가 아니고 Webkit이다..ㅋㅋ

참고글

how-browsers-work

Naver D2 브라우저는 어떻게 동작하는가?

브라우저는 웹페이지를 어떻게 그리나요? - Critical Rendering Path