6. Browser는 어떻게 동작하는가?

2022. 5. 15. 20:03지식정리

브라우저의 주요 기능

  • 서버에 요청해서 받은 웹 자원을 브라우저 창으로 보여주는 것
  • 웹자원 : HTML 문서(보통), PDF, 이미지
  • URI(Uniform Resource Idenfier) : 자원의 위치

browser의 표준(웹 표준)

  • brower가 html 파일을 보여주는 방식은 html과 css 표준에 달려있다.
  • 해당 표준은 W3C 라는 컨소시엄에서 주도하여 유지된다
  • 브라우저들이 일부만 갖다 쓰고 확장해서 호환성 이슈 발생

공통 BUI(Browser User Interface)

  • URI 주소 창
  • 뒤로 가기, 앞으로 가기 버튼
  • 즐겨찾기 옵션
  • 새로고침, 중지 버튼(페이지 갱신, 로딩중 중지)
  • home button( 홈페이지로 가기 위한)

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

개요

  • web performance 관련한 주요 이슈
    • latency 관련
      • 요청된 정보를 빠르게 응답해야 한다
      • network latency : byte들을 컴퓨터로 쭉 보내는 과정에서 시간이 걸리는 것
      • page load를 빠르게 해야한다.
    • browser가 single thread 인 것
      • render time이 중요
      • main thread의 할 일을 최소화 시키는 것
    • web performance 상승시 : main thread가 요청받은 render를 마치고 사용자 상호작용을 받을 수 있는 상태로 바로 전환됨

Navigation(탐색)

  • 사용자가 URL을 주소창에 입력
  • link를 클릭
  • form을 제출
  • 그외 다른 동작들
  • 해당 부분에서의 delay 요소
    • latency, 대역폭(bandwidth)

DNS Lookup

  • domain name 주소를 탐색 시 IP address로 변환 하여 해당 server의 HTML 페이지를 응답. 한번도 방문한 적이 없다면 DNS lookup을 수행함
  • browser에서 name server에 DNS lookup 요청 후 IP가 얼마간 저장됨
  • 연속된 요청시 name server 말고 cache에서 IP주소를 가져옴
  • 새로운 hostname에 대한 요청마다 DNS lookup이 수행 되어야 함.
  • 해당 부분에서의 delay 요소(특히 mobile network)
    • DNS look up 시 mobile browser -> cell tower -> 전화 회사 -> Authorative DNS server 전달
    • 전화, cell tower, name server의 거리가 심각한 latency 발생

TCP Handshake

  • IP 주소 획득 후 server와의 TCP three way handshake 연결을 준비한다.
  • 브라우저와 웹 서버는 데이터를 주고 받기전 네트워크 TCP socket 연결 로 파라미터를 주고 받는다. 가끔 HTTPS를 통해 하기도 한다.
  • SYN , SYN-ACK, ACK

TLS Negotiation(TLS 협상)

  • HTTPS 연결을 위해 다른 handshake 가 필요
  • 송수신을 암호화하는 키, 서버 검증, 보안 연결 수립 등을 위해 송수신 왕복이 3번 더 반복된다. browser가 요청 보낼 준비가 된다.
    1. sample.com (domain name)
    2. < 123.123.123.123 (IP Address)
    3. SYN (3 way handshake)
    4. < SYN-ACK
    5. ACK
    6. ClientHello (TLS negotiation or SSL handshake)
    7. < serverHello & certificate
    8. clientKey
    9. < finished
    10. finished
  • 해당 부분의 latency 요소
    • 연결 암호화(secure connection)시 page load에 시간이 더해진다(복호화 하느라)

response(응답)

  • 웹 서버와 연결되면 브라우저는 HTTP GET request를 사용자를 대신해서 보낸다.
  • request를 받으면 관련 있는 response header와 HTML contents로 응답한다
  • initial request에 대한 응답은 first byte of data를 포함한다.
  • TTFB 란 click 하고 request를 보내고 나서 HTML의 첫번째 packet을 받기 까지 시간이다(Time To First Byte)

TCP slow start / 14KB 규칙

  • TCP slow start 때문에 첫번째 응답 packet은 14KB 일 것 이다.
  • TCP slow start
    • 네트워크 연결 속도의 균형을 맞추는 알고리즘.
    • 네트워크가 최대 대역폭에 이르기 까지 보내는 데이터의 양을 점점 증가시킨다.
    • 임계점에 다다를 때까지 보내는 packet data를 2배로 늘린다(28,56,112...)
  • TCP slow start가 웹 성능 최적화시 14KB reponse에 집중하는 이유이다

혼잡제어

  • 연결은 HW 성능과 네트워크 상황에 따라 달려있다.
  • 너무 많은 packet을 너무 빨리 보내면 drop이 발생한다.
  • ACK 이 없으면 missing ACK라 한다.
  • 혼잡제어 알고리즘은 패킷의 흐름과 ACK을 이용해 전송률을 결정한다.

Parsing(구문 분석)

  • 브라우저가 첫번째 정보를 받으면 받은 정보를 parsing한다.
  • Parsing은 네트워크를 통해 받은 데이터를 DOM과 CSSOM로 변환한다.
    • 해당 객체 모델은 renderer가 화면에 페이지를 그리는데 사용된다
  • DOM : 브라우저를 위한 마크업의 내부 표현. API, javascript를 통해 제어가능하다.
  • 14KB보다 큰 요청 페이지의 HTML이라해도 브라우저는 parsing하고 데이터 기반의 render를 시도한다.
  • 첫 14KB 안에 page rendering 시작을 위해 브라우저가 요구하는 모든 것들, 적어도 첫 rendering을 위한 page template 정도는 포함되어야 한다. web 성능 최적화에 중요한 요소이다.
  • 하지만 HTML,CSS, JavaScript는 page rendering 이전 parsing이 되어있어야 한다.

Building the DOM tree
5 단계로 구성 ( critical rendering path )

  1. HTML 마크업을 DOM tree로 변환
    html parsing은 토큰화와 트리구성을 포함한다. html token은 시작/종료 태그를 포함하고, attribute name/values를 가지고 있다. 문서가 잘 구성되어있으면 parsing도 바로 빠르게 된다. parser는 토큰화된 입력을 parse 해서 문서로 만들고, document tree로 형성한다.

DOM Tree 는 문서의 content를 설명한다. <html> 요소는 첫번째 태그이며 document tree의 root node 이다. tree는 다른 태그들간의 관계와 계층을 반영한다. 태그 속 다른 태그는 child node이다. DOM node 수가 많아질 수록 DOM tree 생성도 오래 걸린다.

domtree

parser가 non-blocking resource (이미지 같은)를 발견하면 브라우저는 해당 자원을 요청하고 parsing을 계속한다. parser는 css파일을 만나도 게속 진행할 수 있지만, <script> 태그 (async,defer 없는 것들) 는 rendering을 막고 html parsing을 일시정지 시킨다. browser preload scanner가 이과정을 빠르게 만들지만, 과도한 스크립트는 여전히 심각한 병목현상을 발생 시킬 수 있다.

Preload scanner
브라우저가 DOM tree를 만들 때 해당 프로세스는 main thread를 차지한다. 이런 경우 preload scanner 에서는 쓸 수 있는 content를 parse 하고, 우선순위가 높은 CSS, JavaScript, web fonts 자원을 요청할 것이다. preload scanner 덕분에 parser가 외부자원에 대한 참조를 요청하기 위해 기다릴 필요가 없다. 자원을 background에서 가져오기에 main HTML parser가 요청된 자원에 도달하면 이미 flight 상태가 되거나 다운로드 되어있거나 하게 된다. preload scanner 최적화는 막히는 것을 감소시킨다.
JavaScript parsing 과 실행 순서가 중요하다면

<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>

같이 asyncdefer 속성을 넣어준다.

CSS 불러오는 것을 기다리는 것은 HTML parsing은 막질 않지만 Javascript를 막는다. javascript가 요소에 영향을 미치는 css property들을 요청하는데 종종 쓰이기 때문이다.

CSSOM 구성하기
2. critical redering path 2번째 단계는 CSS 처리 및 CSSOM tree 구성하기다. CSS 객체 모델은 DOM과 유사하다. 둘다 tree형태이고, 자료구조와는 독립적이다. browser가 CSS 규칙을 이해할 수 있는 style map으로 만든다. 브라우저는 각각의 css rule set을 통과하고, CSS 선택자를 기반으로 tree를 만든다.

브라우저는 받은 CSS 규칙을 작업할 수 있는 무언가로 만들 필요가 있고, html -> object 과정 처럼 CSS에 대한 object변환 과정을 반복한다.

CSSOM Tree는 user agent style sheet 에서 나온 style을 포함한다. browser가 가장 일반적인 규칙을 노드에 적용하고, 점점 더 세부적인 규칙을 적용하며 계산된 스타일을 재귀적으로 다듬는다. 다시말해, property value를 단계적으로 처리한다(cascade).

CSSOM 구성은 매우 빠르고, 개발자 도구에 고유 색을 보여주지 않는다. 대신 recalculate style(개발자 도구 속)은 css를 parse 하고 cssom tree 형성하는 총 시간을 보여준다. 웹 성능 최적화에서 가장 수월한 영역이다. CSSOM 만드는 것은 DNS lookup 한번 보다 일반적으로 빨리 걸린다.

다른 작업들

Javascript compilation (js 편찬)

CSS parse 되고 CSSOM이 만들어질 때, 다른 JS 같은 asset 들은 다운로드 중이다. JavaScript는 interpret, compile되고, parse된뒤에 execute(실행) 된다. script들은 추상 구문 tree(abstract syntax tree)로 parse된다. (V8같은) browser engines은 AST를 가져와서 interpreter에 전달하고, main thread에서 실행되는 bytecode를 생성한다. 이 과정이 javascript compilation이다.

접근성 Tree 만들기(Accessibility tree)

브라우저는 보조 장치가 컨텐츠를 parse/ interpret 할때 사용하는 접근성 트리를 만든다. AOM(Accessibility Object Model)은 DOM의 의미론적 버전이다. DOM이 업데이트 할때 AOM tree도 같이 업데이트 된다. 해당 AOM tree는 보조 기술 자체가 조작할 수 없다. AOM 만들어지기 전까지는 screen reader에 접근 불가능하다.

Render(표현)

  • rendering 은 style, layout, paint, 구성 등을 포함한다
  • CSSOM/DOM tree는 render tree로 엮인다. render tree는 화면에 그려지는 모든 가시적인 요소들의 layout을 계산한다.

Style

  1. critical rendering path 3번째 단계는 DOM / CSSOM을 엮어서 render tree로 만드는 것. 계산된 스타일 트리, render tree는 DOM tree의 root에서 생성을 시작해서 가시적인 모든 노드를 순회한다.

display: none 안보이는 tag나 script로 안보이는 것들은 render tree에 포함되지 않고 결과에도 보이지 않느나. visibility: hidden 적용된 것은 공간을 차지하므로 render tree에 포함된다. override 지시가 user agent에 없었기 때문에 script node는 포함되지 않는것이다.

각가시적인 node는 각각의 CSSOM 규칙이 적용되어 있다. render tree는 content와 계산된 스타일을 가지고 있다. 관련있는 스타일을 모든 DOM tree의 Node에 적용하고, CSS cascade에 따라 정한다.

Layout

  1. 4번째 critical rendering path 단계는 layout을 render tree에 적용 시켜서 각 노드의 기하,도형적 배열(배치방식)을 계산한다. Layout은 가로, 세로, render tree에서 node의 정해진 위치 + 사이즈와 각 페이지에서 각 객체의 위치 에 의해 처리된다. reflow는 페이지 부분/전체의 연속된 size/position 결정하는 과정이다.

render tree가 만들어지면 layout이 개시된다. render tree가 식별한 node들은 계산된 style과 함께 보여지는데, 차원이나 각 노드의 위치는 고려하지 않는다. 각 객체의 정확한 사이즈나 위치를 결정하기 위해 brwweser는 render tree의 root에서 시작해서 순회한다.

web page에서는 거의 모든것들이 직사각형이다. 다른 기기/PC 환경설정은 무한한 viewport 크기가 생긴다는 것을 의미한다. 이 단계에서는 viewport size를 고려하는 상황에서 browser는 모든 직사각형들의 차원이 화면에 어떻게 그려지는지 결정한다. viewport size 고려를 전제로, layout은 보통 body에서 시작되는 모든 것들의 차원들을 배치하고, 차원을 모르는 이미지 같은 element를 위해 placeholder space를 제공한다.

처음에 node의 size / position 이 결정되는 것을 Layout이라 부른다. 연속되는 노드 size / poistion 에 대한 재 측정을 reflow라 부른다. 초기 레이아웃이 image를 얻기 전 발생했을 때, image size를 알리지 않았기 때문에 image size를 알수 있을 때 reflow가 발생하게 된다.

Paint

  1. critical rendering path의 마지막 단계는 개별적인 노드를 화면에 그리는 것이다. 노드 그리기가 처음 나타났을 때 그것을 first meaningful paint라 부른다. painting(rasterization phase) 과정에서 브라우저는 레이아웃에서 계산된 박스를 화면의 실제 픽셀로 변환한다. painting은 모든 element의 시각적인 부분을 화면에 그리는 것과 관련되어있다. 텍스트, 색, 테두리, 그림자 등등, 버튼이나 이미지 처럼 대체된 element 또한 포함한다. browser는 이 과정을 엄청 빠르게 수행해야 한다.

부드러운 scrolling 과 애니메이션을 보장하기 위해 모든 main thread를 차지하는 style 계산, reflow, paint를 아우르는 과정들은 16.67ms(millisecond) 안에 처리되어야 한다. 2048 x 1536 크기의 iPad는 3145000 이상의 pixel을 화면에 매우 빨리 그려야 한다. repainting이 initial paint보다 더 빠르게 수행하는 걸 보장하기위해 화면에 그리는 것은 일반적으로 여러 layer로 쪼개진다. 이것이 발생하면 조합(compositing)하는 과정이 필수이다.

painting은 layout tree의 element를 layer로 분리할 수도 있다. content를 GPU위의 layer로 승격시키는 것은 paint/repaint 성능을 향상시킨다. <video>,<canvas>,opacity, transform, will-change 같은 특정한 element들과 CSS property들이 있다. 자식이 스스로의 layer를 갖출 필요가 없는 한, node들은 자식노드를 포함해서 각자의 layer로 paint된다.

Layer들은 성능을 향상시키지만 memory 관리 문제에 있어서 많은 비용이 들기 때문에, 웹 성능 최적화 전략 과정에서 남용하면 안된다.

Compositing(조합)
문서의 영역들이 다른 레이어에 그려져서 서로 겹치면, content를 화면에 정확하고 올바른 순서대로 그리기 위해 조합(compositing)이 필수적이다.

page가 asset들을 계속 불러올 때 reflow가 발생할 수 있다. reflow는 repaint, recomposite를 촉발할 수 있다. image size를 확정했었을 때는 reflow 하지않는 것이 필수적이고, 오직 repaint 가 필요한 layer들만, composite 도 필요한 경우에만 수행된다. 그러나 image size는 포함하지 않았기 때문에, server에서 image를 획득할 때는 rendering proecess가 layout 단계에서 다시 시작된다.

Interactivity(상호작용성)

main thread가 page painting을 완료한다고 다 끝나지 않은 경우가 있다. Javascript를 포함해서 load 할 때는 확실히 load가 뒤로 늦춰지고 오직 onload event 발생시 실행 되며, main thread는 바빠지고 , scrolling, touch 같은 다른 상호작용을 할 수 없다.

Time To Interactive(TTI)는 첫번째 request가 DNS lookup,SSL connection을 거쳐 page가 상호작용하는데 얼마나 걸리는지의 측정기준이다. 이때 상호작용은 First Contentful Paint이후 부터 page가 사용자 상호작용에 50ms 이내에 바로 응답한다. 만약 main thread가 Javascript를 parsing,compile,execute하느라 점유되어있다면, 50ms 안에 사용자 상호작용에 응답하는 것은 가능하지 않다.

예시로 image가 빨리 load 되었지만 다른 Javascript file이 2MB이고 사용자의 network connection이 느린 경우를 들 수 있다. 이 경우 사용자는 page가 엄청 빨리 뜨는 것을 보겠지만, script가 download,parse, execute 되기까지 버벅거리는 것을 제외하면 스크롤도 할 수 없다.이건 안좋은 사용자 경험이다. WebPageText에서 실제로 보여주는 것처럼 main thread가 점유되는 것을 피하라.

WebPageText


이 경우 DOM content load process는 1.5초가 걸리고 그동안 main thread는 전부 점유되어 screen tap이나 click event에 반응하지 않는다.

'지식정리' 카테고리의 다른 글

Division by Zero(0으로 나누기)  (2) 2023.01.17
7. CSS  (0) 2022.05.20
5. Domain name이란?  (0) 2022.05.13
4. Web Hosting이란?  (0) 2022.05.12
3. DNS란?  (0) 2022.05.12