FEInterview Prep

network

HTTP와 네트워크: HTTP/1.1 → HTTP/2 → HTTP/3, WebSocket, CDN, DNS

네트워크 지식은 프론트엔드 성능 최적화의 기반입니다. HTTP/2의 멀티플렉싱을 이해해야 번들링 전략을 결정할 수 있고, WebSocket과 SSE의 차이를 알아야 실시간 기능을 적절하게 구현할 수 있습니다. "URL 입력부터 화면 표시까지 무슨 일이 일어나는가"는 면접 클래식 질문입니다.

시작 전
이해도
매우 낮음

학습 개요

탄생 배경

해결하려 했던 문제

HTTP/1.1은 요청마다 연결을 맺거나 (Connection: keep-alive로 재사용해도) 응답을 순서대로 기다려야 했습니다. 웹 페이지가 수십 개의 리소스(JS, CSS, 이미지)를 로드하게 되면서 HOL(Head-of-Line) Blocking이 심각한 성능 문제가 되었습니다. HTTP/2는 이를 해결하고, HTTP/3은 TCP의 근본적인 한계를 해결하기 위해 등장했습니다.

역사적 맥락

1991년 HTTP/0.9 → 1996년 HTTP/1.0 → 1997년 HTTP/1.1 (keep-alive) → 2009년 Google SPDY 프로토콜(HTTP/2의 전신) → 2015년 HTTP/2 표준화 → 2018년 HTTP/3(QUIC) 초안 → 2022년 HTTP/3 RFC 9114 표준화 → 2023년 대부분의 주요 브라우저와 CDN이 HTTP/3 지원

이전에는 어떻게 했나

실시간 통신을 위한 Long Polling, Short Polling이 WebSocket 이전에 사용되었습니다. 서버 푸시를 위해 Comet 기법(숨겨진 iframe + keep-alive) 같은 해킹 방법도 있었습니다.

멘탈 모델

동작 원리

[HTTP/1.1의 한계] HOL Blocking: 한 연결에서 요청이 순서대로 처리되어야 함. 앞 요청의 응답을 받기 전에 다음 요청을 보낼 수 없음. 해결 시도: 도메인 샤딩 (여러 서브도메인으로 병렬 연결 수 늘리기), 번들링으로 요청 수 줄이기. 헤더 중복: 같은 헤더(User-Agent, Cookie 등)를 매 요청마다 반복 전송 (압축 없음). [HTTP/2 핵심 기능] 1. 멀티플렉싱 (Multiplexing): 하나의 TCP 연결에서 여러 요청/응답을 동시에, 순서 없이 처리. 각 요청은 Stream ID로 식별되어 뒤섞여도 클라이언트가 조립 가능. → 도메인 샤딩 불필요, 연결 수 최소화, HOL Blocking 해소 (TCP 레벨은 여전히 존재) 2. 헤더 압축 (HPACK): 이전에 전송한 헤더와 달라진 부분만 전송. 자주 사용하는 헤더는 정적 테이블 참조로 1바이트로 표현. 3. 서버 푸시 (Server Push): 클라이언트 요청 전에 서버가 필요한 리소스를 미리 전송. HTML 요청 시 CSS, JS를 미리 푸시. (현재는 Link: preload 헤더로 대체 중) 4. 스트림 우선순위: 중요한 리소스(CSS, JS)를 이미지보다 높은 우선순위로 처리. [HTTP/3와 QUIC] HTTP/2도 TCP 레벨 HOL Blocking은 해결 못함: 하나의 TCP 패킷이 손실되면 전체 연결이 대기 (TCP는 순서 보장 프로토콜). HTTP/3 = QUIC (UDP 기반) 위에서 동작: - UDP로 패킷 손실 시 해당 스트림만 재전송, 나머지는 계속 진행. - TLS 1.3이 QUIC에 통합되어 핸드셰이크가 1-RTT (또는 0-RTT 재연결). - Connection Migration: IP가 바뀌어도 (WiFi → LTE) 연결 유지. [HTTPS와 TLS 핸드셰이크] TLS 1.3 핸드셰이크 (1-RTT): 1. Client → Server: ClientHello (지원 암호화 방식, 랜덤값, 키 교환 파라미터) 2. Server → Client: ServerHello (선택된 암호화 방식, 인증서, 키 교환 완료) 3. 이후부터 암호화 통신 시작 인증서 검증: 브라우저 → 인증기관(CA)의 공개키로 서버 인증서의 서명 검증. [WebSocket vs HTTP Polling vs SSE] HTTP Polling (Short Polling): 클라이언트가 주기적으로 서버에 요청. 서버가 새 데이터 없으면 빈 응답. 단점: 불필요한 요청 과다, 실시간성 낮음. HTTP Long Polling: 서버가 응답을 보류하다가 새 데이터 있을 때 응답. 클라이언트는 즉시 재요청. 단점: 연결 유지 비용, 복잡한 서버 구현. WebSocket: 초기 HTTP 업그레이드 핸드셰이크 후 양방향 지속 연결. 헤더 오버헤드 없이 메시지 프레임 단위로 양방향 통신. 적합: 채팅, 실시간 게임, 협업 도구, 알림. SSE (Server-Sent Events): HTTP/1.1 위에서 서버 → 클라이언트 단방향 스트림. Content-Type: text/event-stream, 브라우저 내장 EventSource API. 자동 재연결 내장, HTTP/2와 함께 사용 시 다중 스트림 가능. 적합: 실시간 피드, 주가, 알림 (클라이언트 → 서버는 별도 HTTP 요청). [DNS 조회 과정 (URL 입력 후 벌어지는 일)] 1. URL 파싱: 프로토콜, 도메인, 경로 분리 2. DNS 조회: a. 브라우저 DNS 캐시 확인 b. OS DNS 캐시 확인 (/etc/hosts 포함) c. Router DNS 캐시 확인 d. ISP DNS Resolver에 질의 e. Root DNS Server → TLD(.com) DNS Server → Authoritative DNS Server f. IP 주소 반환 3. TCP 연결 (3-way handshake) + TLS 핸드셰이크 4. HTTP 요청 전송 5. 서버 응답 수신 6. 브라우저 렌더링 [CDN 동작 원리] CDN(Content Delivery Network): 전 세계 여러 서버(POP, Point of Presence)에 콘텐츠를 캐시. 사용자는 지리적으로 가장 가까운 서버에서 콘텐츠를 받음 → 레이턴시 감소. DNS를 통해 사용자 위치에 따라 가장 가까운 CDN 서버 IP를 반환. Cache-Control 헤더로 CDN 캐시 기간 설정. Edge Computing: CDN 서버에서 직접 로직 실행 (Cloudflare Workers, Vercel Edge Functions).

핵심 구성 요소

Multiplexing

HTTP/2의 핵심: 단일 연결에서 병렬 요청/응답 처리

QUIC

HTTP/3의 기반: UDP 위에 신뢰성, 암호화, 멀티플렉싱을 구현한 프로토콜

TLS Handshake

HTTPS 연결 수립 시 암호화 키를 안전하게 교환하는 과정

WebSocket

단일 TCP 연결의 양방향 전이중(Full-Duplex) 통신 채널

SSE

HTTP 기반 서버→클라이언트 단방향 이벤트 스트림

CDN

지리적으로 분산된 캐시 서버 네트워크. 레이턴시 감소와 오리진 서버 부하 감소

흐름 설명


[WebSocket 연결 수립]
1. 클라이언트 → 서버: HTTP Upgrade 요청
   GET /chat HTTP/1.1
   Upgrade: websocket
   Connection: Upgrade
   Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

2. 서버 → 클라이언트: 101 Switching Protocols
   HTTP/1.1 101 Switching Protocols
   Upgrade: websocket
   Connection: Upgrade

3. 이후: HTTP 프로토콜이 아닌 WebSocket 프레임으로 통신
   → 헤더 없이 작은 프레임으로 양방향 실시간 통신

[SSE 연결]
1. 클라이언트: EventSource('https://api.example.com/events')
2. 브라우저 → 서버: GET /events HTTP/1.1 (Accept: text/event-stream)
3. 서버: HTTP 연결 유지, 데이터 있을 때마다 전송
   data: {"type":"notification","message":"새 메시지"}

   event: custom-event
   data: {"payload":"..."}

4. 연결 끊어지면 브라우저 자동 재연결
    

코드 예제


// WebSocket 클라이언트
class WebSocketClient {
  private ws: WebSocket;
  private reconnectTimer: number | null = null;

  connect(url: string) {
    this.ws = new WebSocket(url);

    this.ws.onopen = () => console.log('연결됨');
    this.ws.onmessage = (event) => this.handleMessage(JSON.parse(event.data));
    this.ws.onclose = () => this.reconnect(url);
    this.ws.onerror = (error) => console.error('WebSocket 에러:', error);
  }

  send(data: object) {
    if (this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(data));
    }
  }

  private reconnect(url: string) {
    this.reconnectTimer = window.setTimeout(() => this.connect(url), 3000);
  }
}

// SSE 클라이언트 (단방향 서버 이벤트)
function useServerSentEvents(url: string) {
  const [events, setEvents] = useState<Event[]>([]);

  useEffect(() => {
    const eventSource = new EventSource(url, {
      withCredentials: true, // 쿠키 포함
    });

    eventSource.onmessage = (event) => {
      setEvents(prev => [...prev, JSON.parse(event.data)]);
    };

    eventSource.addEventListener('notification', (event) => {
      // 특정 이벤트 타입 처리
    });

    eventSource.onerror = () => {
      // EventSource는 자동으로 재연결
    };

    return () => eventSource.close(); // 언마운트 시 연결 종료
  }, [url]);

  return events;
}

// HTTP/2에서 도메인 샤딩이 오히려 역효과인 이유
// HTTP/1.1: 브라우저 당 도메인별 6개 연결 → 도메인 샤딩으로 병렬 연결 증가
// HTTP/2: 단일 연결에서 멀티플렉싱 → 도메인 샤딩이 핸드셰이크 비용만 증가
// 따라서 HTTP/2 환경에서 도메인 샤딩은 오히려 성능 저하

// Cache-Control 헤더로 CDN 캐싱 전략
// 정적 자산: 긴 캐시 시간 + 파일명에 콘텐츠 해시
// bundle.a1b2c3d4.js
Cache-Control: public, max-age=31536000, immutable
// 변경 시 파일명이 달라지므로 캐시 무효화 자동

// HTML: 짧은 캐시
Cache-Control: public, max-age=0, must-revalidate
    

비교 분석

HTTP와

vs

WebSocket vs SSE

비교 관점
이 방식
WebSocket vs SSE
통신 방향
WebSocket: 양방향 (클라이언트 ↔ 서버)
SSE: 단방향 (서버 → 클라이언트만)
프로토콜
WebSocket: ws:// 또는 wss:// (HTTP 업그레이드)
SSE: HTTP 위에서 동작 (기존 인프라 그대로)
자동 재연결
WebSocket: 직접 구현 필요
SSE: 브라우저 내장 자동 재연결
HTTP/2 지원
WebSocket: HTTP/2와 함께 사용 어려움
SSE: HTTP/2 멀티플렉싱 활용 가능
적합 사례
WebSocket: 채팅, 실시간 게임, 협업 (클라이언트도 자주 전송)
SSE: 뉴스 피드, 주가, 알림 (서버에서 클라이언트로 푸시)

HTTP와

vs

HTTP/2 vs HTTP/1.1

비교 관점
이 방식
HTTP/2 vs HTTP/1.1
HOL Blocking
HTTP/2: 애플리케이션 레벨 해결 (스트림 독립)
HTTP/1.1: 요청 순서대로 처리, 앞 요청 블로킹
연결 수
HTTP/2: 단일 연결로 모두 처리
HTTP/1.1: 도메인당 최대 6개 병렬 연결
헤더
HTTP/2: HPACK으로 헤더 압축
HTTP/1.1: 매 요청마다 전체 헤더 텍스트로 전송
번들링 전략
HTTP/2: 작은 파일 다수가 더 효율적일 수 있음
HTTP/1.1: 요청 수 최소화를 위해 번들링 필수

트레이드오프

이상적인 사용 사례

면접 질문