브라우저의 작동 방식

무제·2021년 8월 29일
1
post-thumbnail

⚙️ 렌더링 엔진

렌더링 엔진의 역할은 서버와의 통신에서 응답으로 받은 내용들을 브라우저 화면에 표시하는 일이다. 그리고 파일에 따라서 필요한 파서(parser)를 실행시켜 트리 구조의 결과물을 만든다.

렌더링 엔진을 통해 HTML을 파싱하여 DOM 트리를, CSS 파일을 파싱하여 만든 CSSOM 트리, 두 개를 결합해서 만든 렌더 트리가 존재한다.

이 후, 렌더 트리에 존재하는 요소의 위치를 계산하는 레이아웃 또는 리플로우 작업, 스크린의 픽셀마다 필요한 색을 색칠하는 그리기(Paint) 작업이 이루어진다.

브라우저마다 사용하는 렌더링 엔진이 다른데, 크롬과 사파리는 웹킷이라는 렌더링 엔진을 사용하며, 파이어폭스는 겍코(Gecko)라는 렌더링 엔진을 사용한다.

🏭 파싱 ?

파싱이란

  • 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미한다. - 네이버 D2
  • Parsing means analyzing and converting a program into an internal format that a runtime environment can actually run. - MDN
  • 프로그램을 분석하고 현재 실행되는 환경에서 실행될 수 있는 구조로 변환하는 것 - MDN (해석 : 본인)

🏭 파싱 과정

파싱을 할 때 네 가지의 과정을 거친다.

문서 -> 어휘 분석 -> 구문 분석 -> 파싱 트리

어휘 분석 과정에서는 문서를 토큰으로 분해하는 과정이다. 그런 뒤, 분해된 토큰이 구문 분석의 규칙 기준에 맞다면 파싱 트리에 하나의 노드로 추가가 된다. 만약 기준에 부합되지 않는다면, 내부적으로 저장해놓고 다음 문자와 함께 파싱 과정을 순회한다. 순회하면서 기준에 부합되면 다시 파싱 트리의 노드로 추가 된다.

🏭 HTML Parsing

HTML 파서는 HTML 문서를 파싱한다. 즉, 브라우저가 알아 먹을 수 있도록 코드를 다른 구조로 변환한다. 파싱 결과는 🌳 DOM 트리.

🏭 CSS Parsing

CSS 파서는 CSS 문서를 파싱하여 결과로 🌳 CSSOM 트리를 만든다.

보통 link 태그를 사용하여 스타일 파일을 head 태그 안에 위치시킨다. 왜냐하면 HTML과 CSS를 병렬적인 구조로 렌더링 하여 웹의 렌더링 시간을 줄일 수 있기 때문이다. 이 말은 즉, HTML과 CSS는 동시에 파싱할 수 있다는 것을 의미한다.

🚫 Script Parsing과 Blocking

만약 script 태그 또한 동시에 파싱이 가능할까?

정답은 No or Yes이다.

만약 script 태그에 아무런 속성(async, defer)을 넣지 않고 body 태그에 넣었을 때에는 script 파일을 다운로드하고 실행이 완료될 때까지 HTML과 CSS 파싱이 중지된다. 이런 이유로, script 태그를 body 태그를 가장 마지막에 위치시킨다.

async 속성과 defer 속성

script 태그에 async나 defer 속성은 script 파일을 다운로드 하는 동안 HTML가 CSS 파싱을 멈추지 않는다. 다만 실행 시점의 차이가 존재한다.

async 속성은 script 파일이 다운로드가 되면 바로 실행까지 한다. 그러므로 여러 개의 script 파일이 존재하는 경우 다운로드가 완료되는 순서대로 실행이 되므로 실행 순서를 보장할 수 없다. HTML 파싱은 멈추지 않는다.

defer 속성은 script 파일이 다운로드가 되면 실행은 HTML 파싱이 완료된 후 실행한다.

🌳 렌더 트리

HTML과 CSS 파일이 파싱이 된 결과물 DOM 트리와 CSSOM 트리를 결합하여 렌더 트리를 만든다. 렌더 트리에는 정말 화면에 보여지는 요소들만 포함되어있다. meta, link, head 태그, 스타일 요소 중 displaynone 인 요소 들은 렌더 트리에 포함되어 있지 않다.

visibility : hidden 은 렌더 트리에 들어가 있다.

만들어진 렌더 트리를 기반으로 각 요소들을 레이아웃과 그리기 과정을 거쳐 브라우저 화면에 Content를 띄울 수 있다. 야호!

DOM Tree + CSSOM Tree = Render Tree

📐 레이아웃(Layout) or Reflow

레이아웃(Layout)리플로우(Reflow) 브라우저의 내용이 담길 공간의 실제 크기인 viewport의 크기를 결정하고 렌더 트리를 기반으로 각 요소의 위치나 크기 정보를 계산한다. viewport의 크기는 head 태그 안에 있는 meta 태그로부터 알 수 있다. 만약 meta 태그가 존재하지 않는다면 기본 viewport의 width값은 980px이다.

<meta name="viewport" content="width=device-width,initial-scale=1">

meta 태그의 속성에서 content 속성 안에 들어가있는 width는 DOM 컨텐츠의 크기는 기기의 넓이를 기본 width로 설정하라는 뜻,initial-scale은 HTML Document를 처음 로드 했을 때의 초기 줌 레벨을 뜻한다. 1 은 1 배

또한 각 요소들이 있어야 할 위치와 크기를 계산하고 줄 바꿈이나 요소들 간 관계를 설정한다. 계산할 것들이 많아 꽤 무거운 과정이다. 그래서 요소의 스타일이 변경됐을 때 layout 연산 과정을 피할 수 있다면 피하는 것을 지향한다.

👨🏻‍🎨 그리기(Paint)

렌더링 과정의 마지막인 그리기 과정은 각각의 요소를 스크린에 그리는 과정이다. 레이아웃 과정에서 계산이 된 박스들이 이제 실제로 스크린 위의 픽셀로 나타나는 단계이다. 텍스트, 테두리, 색깔과 같은 것들도 그려지게 된다.

자연스럽고 부드러운 애니메이션이나 스크롤링은 매번 리플로우(레이아웃)과 페인트 과정을 반복하는데 이 과정은 16.67ms 보다 적게 걸려야 한다. 왜냐하면 60fps 애니메이션은 부드러운 애니메이션을 보장하기 때문이다.

📎 참조

profile
표현할 수 없는 무제공책

0개의 댓글