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

들어가기전에

브라우저의 작동 방식

  • 유명한 브라우저 동작 방식 글이 있다.

  • 원본 글을 보니 2011년에 쓴 글이라 콘텐츠의 상당 부분은 정확하지 않는다고 적혀있음

  • 브라우저 동작 방식은 나름 low 하다고 생각해서 자료 볼 때 작성 된 날짜를 고려해야겠다는 생각을 못 했는데 반성.

  • 공식 문서가 읽기 불편해도 중요하게 이야기 하는 이유가 있다. 신뢰성 ↑↑

우리는 왜 브라우저 동작 방식을 알아야할까?

  • 사용자는 로드가 빠르고 상호작용이 원활한 콘텐츠로 이루어진 웹 경험을 원합니다.
  • 웹 브라우저 동작 방식을 이해하면 실제 성능체감되는 성능을 향상시키는 방법을 이해하는데 도움이 됩니다.

웹 성능에 있어서 두 가지 주요한 문제는 지연시간 과 브라우저가 대부분 싱글 스레드 로 동작한다는 점

→ 빠른 로딩을 하는데 있어서 지연시간은 이겨내야할 중요한 문제

→ 메인 쓰레드가 요청된 모든 작업을 수행하면서 유저와 상호 작용에 반응을 보장하기 위해서는 렌더링 시간이 중요

❓

MDN 문서에 브라우저가 싱글 스레드라고 적혀있는게 의문

수업 시간에서 브라우저는 탭마다 각각 프로세스라고 했고, 
이벤트 루프도 별도의 스레드에서 실행 되는걸로 알고 있는데, 왜 싱글 스레드라고 했을까? 

MDN에서는 메인 스레드를 기준으로 말했기 때문이다.
크롬(Blink 엔진), Firefox (Gecko엔진), Safari(WebKit엔진) 모두 메인 스레드는 싱글이다.
메인스레드는 자바스크립트 실행과 DOM 조작을 담당한다. 
( 자바스크립트는 기본 설계 원칙이 싱글 스레드로 동작 ) 

1. 탐색 ( Navigation )

  • 웹 페이지를 로딩하는 첫 단계
  • 우리가 주소창에 URL 입력, 링크 클릭, 폼 제출하는 등의 요청 보낼 때마다 발생
  • 웹 최적화의 목표 중 하나는 탐색이 완료될 때까지의 시간을 최소화 하는 것 !

1-1. DNS 조회

  • 브라우저가 DNS 조회 요청
  • 호스트 네임 → ip 주소로 응답
  • ip는 일정 기간 동안 캐시 된다고 합니다.
  • 모바일은 DNS 가기 전에 셀타워를 거친다 !

셀타워는 이동통신사가 설치한 네트워크 인프라의 일부임

셀타워를 거치기 때문에 모바일은 탐색 완료 되는 시간이 더 오래 걸릴 수 있다.

1-2. TCP 핸드셰이크

  • IP를 알고난 후에는, 브라우저는 서버와 연결을 합니다.
  • 뭐를 통해? TCP 3-way handshake를 통해
    • TCP 3-way handshake
      • 수업 시간에 배웠던 내용
      • SYN(SYNchronize) 클→서: 내 시작번호는 ~ 야
      • SYN-ACK(SYNchronize-ACKnowledgement) : 서→클: 내 시작 번호는~, 너 다음 번호는 ~기대할게
      • ACK(ACKnowledge) : 클→서 : 알겠어, 너 다음 번호는 ~ 기대할게
      • 기대하는 시퀀스 번호가 아니면 연결이 취소

1-3. TLS 협상 ( TLS Negotiation )

  • HTTPS를 이용한 연결을 위해서는 또 다른 핸드셰이크가 필요함
  • 암호화에 쓰일 함호를 결정하고, 서버를 확인하고, 실제 데이터 전송 전에 안전한 연결이 이루어지도록 한다.
  • TCP 핸드셰이크로 끝난게 아니라 실제 요청 전에 클-서 3번 더 왕복해야함

DNS : 2번

TCP-3way-handshake : 3번

TLS Negotiation : 3번

총 8번의 왕복이 있고 난 후에, 브라우저는 요청을 할 수 있다.

2. 응답 ( Response )

  • 웹서버로 한 번 연결이 성립되고 나면, 브라우저는 유저 대신 초기 HTTP GET request 보내서 HTML 파일 요청함
  • 서버는 관련 응답 헤더와 함께 HTML 내용을 응답함
  • 브라우저가 초기 요청에 대한 응답에 대한 TTFB ( Time to First Byte ) 시간을 측정도 한다고 함

그 외, 네트워크 트래픽을 관리하는 매커니즘

혼잡 제어

- 데이터가 안정적으로 전송 되기 위해 전송 속도 조절도 하고 모니터링도 하는 것을 말합니다.

### TCP 슬로우 스타트

- 처음 스타트를 느리게 하다가 빨라지면 증가 시키는 것을 말합니다.

```jsx
처음: 1개 패킷
↓
성공하면: 2개 패킷
↓
성공하면: 4개 패킷
↓
성공하면: 8개 패킷
(지수적 증가)
```

3. 구문 분석 ( Parsing )

  • 브라우저가 첫 번째 데이터 청크 (데이터를 작은 조각으로 나눈 것)을 받으면 구문 분석을 시작합니다.
  • 구문 분석은 브라우저가 네트워크를 통해 받은 데이터를 DOM, SSCOM으로 바꾸는 단계를 말합니다.

3-1. DOM 트리 구축

- HTML을 처리하여 DOM 트리를 만듬
- DOM 노드의 개수가 많아질수록, DOM 트리를 만드는데 오랜 시간이 걸립니다.
- CSS, 이미지와 같은 논 블로킹 자원을 발견하면 해당 자원을 요청하고 분석을 계속합니다.
- `async` 나 `defer` 같은 설정이 되지 않은 `script` 태그는 렌더링을 막고 HTML 분석을 중지시킵니다.
- 프리로드 스캐너가 이 작업을 가속화하지만, 과도한 스크립트는 여전히 주요한 병목 구간이 될 수 있습니다.

```jsx
1. HTML 바이트 → 문자 변환
       ↓
2. 토큰화 (Tokenization)
       ↓
3. 노드 생성
       ↓
4. DOM 트리 구축
```

프리로드 스캐너

  • HTML을 파싱하면서 미리 필요한 리소스를 찾아 다운로드를 시작하는 역할을 합니다.
  • 메인 스레드랑 별도의 스레드에서 동작
  • 메인 파싱 작업을 방해하지 않고 병렬로 처리할 수 있다.
일반 로드:
HTML 파싱  리소스 발견  리소스 요청  다운로드

프리로드:
HTML 파싱 ─→ 계속 진행
     
리소스 미리 발견
     
리소스 요청 시작

3-2 CSSOM 구축

  • CSS를 처리하고 CSSOM 트리를 만드는 것
  • DOM 과 비슷하게 트리 구조
1. CSS 바이트  문자 변환
       
2. 토큰화 (Tokenization)
       
3. 노드 생성
       
4. CSSOM 트리 구축

3-3. Javascript 컴파일

  • CSS 분석되고 CSSOM 생성되는 동안, 프리 스캐너 덕에 JS 파일 같은 다른 자원도 다운로드 됨
1. 코드 다운로드
       
2. 파싱 (구문 분석)
       
3. AST 생성 ( 추상 구문 트리 : 코드의 구조를 컴퓨터가 이해하기 쉽게 만든 데이터 구조라고 생각하면 )
       
4. 바이트코드 생성
       
5. 실행

3-4. 전체적으로 맥락 이해하기

  1. HTML 파싱 시작
  2. CSS/JS 파일 미리 발견(프리로드 스캐너)
  3. CSS 병렬 다운로드
  4. 비동기 JS 병렬 다운로드
  5. 각자 준비되는 대로 처리

4. 렌더 ( Render )

  • 화면의 일부분을 CPU 대신 GPU 가 그리면서 메인 스레드의 부담이 줄고 성능이 향상 된다고 합니다.
  • 렌더 단계에서는 스타일레이아웃페인트 순서로 진행
  • 이를 렌더링 파이프라인 이라고 합니다.

4-1. 스타일

- CSSOM과 DOM 트리는 구문 분석되는 과정에서 생성되고 렌더 트리로 합성 됩니다.
    - 점진적 렌더링 과정
        
        사용자가 더 빨리 콘텐츠를 볼 수 있는 장점이 있습니다.
        
    
    ```jsx
    DOM 파싱 시작  ─────────────────────────▶
         │ 
         ├─── 일부 DOM 생성 ──┐
         │                    │
    CSSOM 파싱 시작          렌더 트리 부분 생성
         │                    │
         ├─── 일부 CSSOM ────┘
         │        
         ▼
    계속 진행...
    ```
    
- 렌더 트리는 보이는 요소의 레이아웃을 계산 ( 루트부터 → 보이는 노드를 순회 )
    
    ```jsx
    display: none // 렌더트리에 포함되지 않는다. 
    visibility: hidden // 자리를 차지하기 때문에 렌더 트리에 포함
    ```
    
- 각각 보이는 노드는 그 노드에 적용된 CSSOM 규칙이 있는데, CSS 캐스케이드 방식에 따라 각 노드의 계산된 스타일이 무엇일지 결정합니다.

<aside>
❓

**CSS 캐스케이드**

하나의 요소에 여러 스타일 규칙이 있을 때, 어떤 스타일이 최종적으로 적용될지 결정하는 규칙

</aside>

4-2. 레이아웃

- 렌더 트리를 기반으로 각 노드의 도형 값을 계산하기 위해 레이아웃을 실행하는 것
- 즉, 모든 노드의 너비, 높이, 위치를 결정하는 프로세스입니다.

4-3. 페인트

- 각 노드를 화면에 페인팅 하는 것
- 브라우저는 레이아웃 단계에서 계산된 각 박스를 실제 화면의 픽셀로 변환합니다.

4-2 그 외 레이어와 합성

- 레이어와 합성은 성능 최적화를 위한 단계

```jsx
// 레이어란 ? 여러 층으로 나누어 처리, 레이어는 독립적으로 처리 가능하고 GPU를 활용해 효율적으로 처리 가능
웹 페이지
├── 레이어 1 (메인 콘텐츠)
├── 레이어 2 (fixed 헤더)
└── 레이어 3 (애니메이션 요소)

// 합성이란 ? 레이어를 순서대로 쌓아서 최종 화면에 생성
레이어 3 (최상단)
    ↓
레이어 2 (중간)
    ↓
레이어 1 (배경)
    = 최종 화면
```

5. 상호작용 - TTI

  • DNS 조회부터 페이지가 상호작용할 준비가 될 때까지 측정하는 단위
  • 좋은 사용자 경험을 위해 사용자 입력에 TTI가 50ms 안에 반응해야한다고 한다. (그래야 부드럽게 느껴진다함)
시작 ────────────────────────► TTI 달성
  
  ├── DNS 조회
  ├── 페이지 로드
  ├──  콘텐츠 표시
  └── JavaScript 실행 완료

참고 자료

웹페이지를 표시한다는 것: 브라우저는 어떻게 동작하는가 - 웹 성능 MDN

Categories:

Updated:

Leave a comment