본문 바로가기
CS

브라우저의 동작 과정을 알아보자!

안녕하십니까, 야생에서 등장한 하프 입니다 🤔

개발자로 일을 하다보니, 브라우저는 어떻게 html, css, js를 인식하고 화면에 보여지는지 궁금해서 제가!!! 알아봤습니다!

너무 방대하고 글이 많다보니,, 요약을 좀 해서 알려드릴까 합니다!

 

📝 목차

 


브라우저

1. 서론

요약해서 말씀 드리면 브라우저(browser)는 단일 스레드 입니다.

즉, 다른 작업을 시작하기 전에 처음부터 끝까지 순차적으로 작업을 실행합니다.

스크롤, 터치와 같은 인터렉션을 보장하지요!

 

 

2. 탐색

탐색은 웹 페이지를 로드하는 단계라고 보시면 됩니다!

사용자가 주소 표시줄에 URL을 입력하거나 링크를 클릭, 제출양식(form)을 통해 요청을 할 때마다 발생하게 됩니다.

웹 성능의 목표 중 하나는 탐색하는 시간을 최소화를 목표로 한다고 보면 됩니다.

 

 

3. DNS 조회

DNS(Domain Name Service)조회란 자산이 있는 위치를 찾는것을 의미합니다!

https://www.naver.com 페이지는 ip가 223.130.195.95인것을 알 수 있고

이 사이트를 방문한적이 없다면 DNS 조회가 이루어져야 합니다~!

 

 

확인해보기 위해서 dns 캐시를 지우고 naver에 접속한 뒤, dns 캐시를 확인해보도록 합시다!

왜인지는 모르겠지만 beacons.gvt2.com 으로 뭔가 조회가 되는것 같은데!,, 찾아보니 구글 클라우드 인 것 같더라구요.

보통은 아래와 같이 dns 조회가 됩니다

 

 

4. TCP 핸드쉐이크 (TCP HandHake)

이렇게 IP 주소를 알고난 후 부터는 서버와TCP 3 Way Hand Shake를 통해 연결을 설정합니다.

아래 사진의 설명은 https의 대한 설명이고 총 8번의 왕복이 있어야 보안성이 있는 요청을 할 수 있게 됩니다.

8번이나 하는데 속도에 큰 무리가 있지는 않을까? 싶지만 보안성있는 연결은 지연시간이라는 비용을 낼 만큼 충분한 가치가 있다고 할 수 있습니다!

 

 

5. TCP 슬로우 스타드 (TCP Slow Start)

브라우저는 사용자를 대신해서 대상 서버에 Http Get Request요청을 보냅니다.

무조건 첫 응답 패킷은 14kb 입니다. 으.. 아닛 ?! 14kb 라고?

그럼 별로 안되는것이 아닌가??!! 싶지만 text로 따지면 의외로 많이 들어가는 양입니다 🤣

1024byte * 14 = 14kb

알파뉴메릭(숫자, 영문자, 아스키)는 1byte

한글 및 특수문자는 2byte

전부 2byte로 가정한다면, 7,168글자를 넣을 수 있습니다!

아래의 코드가 2byte로 계산 시 906(공백포함)글자이니.. 어느정도일지 예상이 되시겠죠?

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>My simple page</title>
    <link rel="stylesheet" src="styles.css" />
    <script src="myscript.js"></script>
  </head>
  <body>
    <h1 class="heading">My Page</h1>
    <p>A paragraph with a <a href="https://example.com/about">link</a></p>
    <div>
      <img src="myimage.jpg" alt="image description" />
    </div>
    <script src="anotherscript.js"></script>
  </body>
</html>

 

 

엥? 그러면 왜 14kb를 처음에 보내지?

처음부터 다 받으면 되는거 아닌가?

 

 

 

초반에 네트워크의 최대 대역폭을 파악할 수 없으니까!!

즉, 네트워크의 혼잡 현상을 방지하고, 네트워크의 최대 용량을 찾을 때 까지 확산되는 정보의 양을 천천히 늘려야 하기 때문이다!

 

 

흠, 그러면 초반에 14kb를 넘으면 어떡하지? 🤔

그럴 땐 다음 요청때는 24kb, 그 다음 요청때는 48kb로 2배씩 늘어나게 됩니다.

하지만 계속 늘어나는게 아니라 패킷의 미리 정의한 임계치나, 혼잡의 징후가 나타나기 전 까지만입니다.

점진적으로 적당한 전송 속도를 찾고자 속도를 높여나가게 되는것이죠!

 


구문 분석 (Parsing)

브라우저가 첫 데이터의 청크(14kb)를 받으면, 수신된 정보를 구문 분석하기 시작합니다.

구문 분석이란 받은 데이터를 DOM이나 CSSOM으로 변환하는 단계 입니다.

웹 성능 최적화를 위해서 적어도 첫 렌더링에 필요한 HTML이나 CSS만이라도 첫 14kb에 포함이 되어야 하는 이유입니다.

 

1.DOM 트리 구축

첫 청크를 받게 되면 HTML을 처리하여 DOM 트리를 만들게 됩니다.

 

 

이 때 토큰화 라는 과정을 거치게 됩니다.

토큰화란 HTML의 시작과 끝, 각종 속성들을 알아낼 수 있고 이게 HTML 문서다! 라는걸 알아낼 수 있게 하는 과정입니다.

자세한 문서는 여기에서 확인해주시면 됩니다.

결과적으로는 아래와 같은 과정을 거치게 됩니다.

 

 

토큰화 까지는 대충 알겠어! 그러면 노드화는 어떻게 하는걸까? 🤔

노드화의 경우는 각 태그들을 말 그대로 노드로 생성합니다.

CSS를 임포트하기 위한 link, 이미지를 받아오기 위한 img의 경우 만나게 되면 다운로드를 진행하게 되고

Javascript를 만나게 되면 브라우저는 DOM 생성을 중단하고 스크립트를 해석하게 됩니다.

이러한 과정을 거치면 DOM Tree를 생성하게 됩니다.

 

 

2. 프리로드 스캐너

브라우저가 DOM 트리를 만드는 프로세스는 메인 쓰레드를 차지하게 되는데, CSS나 Javascript, 웹 폰트 처럼 우선순위가 높은 자원을 요청하게 됩니다.

프리로드 스캐너 덕분에 외부 자원 css, img 등 자원을 백그라운드에서 미리 요청하게 됩니다.

<link rel="stylesheet" src="styles.css" />
<script src="myscript.js" async></script>
<img src="myimage.jpg" alt="image description" />
<script src="anotherscript.js" async></script>

앞에서도 언급했듯이 자바스크립트를 분석하기 시작하면 DOM Tree 생성을 중단 합니다.

이럴 때 자바스크립트의 크기가 크다면, 분석되는 동안은 아래의 페이지가 보여지지 않게 됩니다.

이러한 현상을 방지해주기 위해 프리로드 스캐너로 비동기 처리를 위한 async 또는 defer를 사용합니다.

async와 defer의 자세한 내용은 여기에서 확인해보시면 되겠습니다.

 

 

3. CSSOM 트리 구축

CSSOM은 DOM Tree 구성과 유사 합니다.

DOM과 CSSOM은 둘 다 트리구조이고 각각의 독립적인 자료구조 입니다.

CSSOM을 만드는건 매우 매우 빠르고 개발자 도구에서는 표시가 되지 않는다고 합니다.

웹 성능 최적화를 위해 CSSOM을 고려한다 라고 생각을 해보면, DNS 조회하는 시간보다도 짧기 때문에 큰 기여를 할 수 있는 영역은 아니라고 합니다 !

 

 

렌더(Render)

만들어진 DOM과 CSSOM을 합성한 후 Render Tree를 만들어내게 됩니다.

합성하는 과정을 Attachment라고 하며 스타일, 레이아웃 과정을 거쳐 Render Tree가 나오게 됩니다.

 

1. 스타일 (Style)

Render Tree를 만드는 중 display: none과 같은 속성은 자리를 차지하지 않기 때문에 Render Tree가 인식할 수 없습니다.

접근성을 위해서는 display: none이 아닌 visibility: hidden 속성을 사용하는게 맞을 것 같습니다 !

 

 

2. 레이아웃 (Layout)

렌더링 과정 중 렌더 트리를 기반으로 각 노드의 도형 값을 계산하기 위해 레이아웃을 실행 합니다.

left, right, top, width, height, margin, paddin 등등 위치와 관련된 부분들 계산해 주는것이 레이아웃 단계라고 하며

다시 레이아웃의 과정이 필요할 경우 리플로우라고 부릅니다.

 

 

3. 페인트 (Paint)

렌더링 과정에서 마지막 단계인 페인트이며, 한번 더 페인트가 필요할 경우 이것을 리페인트 이라고 부릅니다.

그런 후 레이아웃 단계에서 계산된 각 박스를 실제 화면의 픽셀로 변환 합니다.

페인팅에서 background, box-shadow, border-raidus, color 등등 다양한 요소들을 픽셀로 계산 후 화면에 그리는 작업을 합니다.

원활한 웹 사용을 위해서는 이 과정이 매우 빨라야겠지요!!

요즘은 모니터가 크고, 애플의 경우는 고해상도 이니 계산해야할 픽셀 수가 많다고 볼 수 있습니다.

 

 

4. 함성 (Compositing)

합성의 경우 다른 레이어에서 그려질 때 섹션을 겹쳐놓으면(모달 과 같은 것들) 올바른 순서로 화면에 그려지는 것을 말합니다.

페이지가 계속해서 자원을 로드하면, 브라우저는 큰 부담을 느끼게 됩니다.

왜 그럴까요? 🤔

즉, 계속해서 자원을 로드한다는건 리플로우, 리페인트가 계속해서 발생한다는 뜻이고 브라우저에 부하가 될 수 있다는 뜻 입니다.

아니 그러면 css가 변경될 때마다 리플로우, 리페인트가 계속 되는건가!??

예를 들면 background-color가 변경이 되었을 때, 위치는 변하지 않았으니 리플로우는 생략하고 리페인트만 동작하게 됩니다.

 

 

즉, 불필요한 부분을 생략을 한다는 것 이죠! 🫠

이러한 과정들을 거치게 되면 !!

드디어 렌더링 된 화면이 나오게 됩니다.

약간 가상돔 과 같은 성질을 가지고 있다고 볼 수 있겠네요

 


 

 

이렇게 브라우저가 HTML을 어떻게 받고 화면에 보여주는지를 알아보았습니다.

이것을 찾아보기 위해 조금은..! 힘들었지만 도움이 되었으면 좋겠습니다 😊

 

 

참고문헌

1. https://www.youtube.com/watch?v=z1Jj7Xg-TkU

2. https://developer.mozilla.org/ko/docs/Web/Performance/How_browsers_work

3. https://developer.mozilla.org/ko/docs/Web/Performance/Critical_rendering_path

4. https://ko.javascript.info/script-async-defer

'CS' 카테고리의 다른 글

진법 변환을 알아보자  (4) 2024.03.24
자바스크립트 동작 원리  (2) 2024.03.17