HTTP/1.1과 HTTP/2의 큰 차이는 전송 방식입니다. HTTP/1.1은 text 기반이고 한 connection에서 요청과 응답의 순서 제약 때문에 병렬성이 제한됩니다. 그래서 browser가 여러 TCP connection을 열어 병렬 요청을 처리하곤 했습니다. HTTP/2는 binary frame 단위로 데이터를 나누고, 하나의 connection 안에서 여러 stream을 multiplexing할 수 있습니다.
덕분에 여러 요청을 동시에 주고받기 쉬워지고 header compression 같은 최적화도 들어갔습니다. 다만 TCP 위에서 동작하기 때문에 packet loss가 생기면 TCP 수준의 head-of-line blocking은 여전히 있을 수 있습니다.
꼬리질문
조금 더 깊게 물어본다면
답변 뒤에 이어질 수 있는 질문들을 하나씩 열어볼 수 있어요.
multiplexing은 무엇인가요?
하나의 connection 안에서 여러 logical stream을 동시에 주고받는 방식입니다. 요청 하나가 끝날 때까지 다음 요청이 완전히 막히는 구조를 줄일 수 있습니다. HTTP/2 성능 개선의 핵심 중 하나입니다.
HTTP/2에서도 head-of-line blocking이 있나요?
HTTP layer에서는 많이 줄었지만, HTTP/2는 TCP 위에서 동작하므로 TCP packet loss가 있으면 같은 connection의 stream들이 영향을 받을 수 있습니다. 이 문제를 더 줄이려는 방향이 QUIC 기반 HTTP/3와 연결됩니다.
HTTP/1.1 pipelining과의 차이는?
HTTP/1.1 pipelining은 응답을 기다리지 않고 여러 요청을 순서대로 보내는 방식이지만, 응답은 여전히 요청 순서대로 받아야 합니다. 앞선 응답이 지연되면 뒤의 응답도 막힙니다. HTTP/2 multiplexing은 stream 단위로 독립 처리되어 순서 제약이 없습니다.
header compression은 왜 중요한가요?
HTTP 요청에는 cookie, user-agent 같은 반복 header가 많습니다. HTTP/2는 HPACK을 통해 header를 압축해 반복 전송 비용을 줄입니다. 작은 요청이 많은 웹 페이지에서 도움이 될 수 있습니다.
HTTP/2면 bundling이 필요 없나요?
완전히 필요 없어지는 것은 아닙니다. 요청 병렬성이 좋아졌지만 JavaScript parse/execute 비용, cache 전략, dependency 관리가 여전히 중요합니다. bundle을 무조건 크게 만드는 것도, 무조건 잘게 쪼개는 것도 정답은 아닙니다.
HTTP/2의 server push는 무엇인가요?
클라이언트가 요청하기 전에 서버가 필요할 것으로 예상되는 리소스를 미리 보내는 기능입니다. 예를 들어 HTML 요청 시 CSS나 JS를 함께 push할 수 있습니다. 다만 cache 상태를 고려하지 못해 불필요한 전송이 생기는 경우가 있어 실무에서는 신중하게 사용합니다.
HTTP/3(QUIC)는 무엇이 다른가요?
HTTP/3는 TCP 대신 UDP 기반의 QUIC 프로토콜 위에서 동작합니다. QUIC은 stream 단위 독립 전송을 지원해 packet loss가 발생해도 다른 stream이 영향을 받지 않습니다. 연결 수립 시간도 줄어 초기 지연이 작습니다. TCP 수준의 head-of-line blocking 문제를 근본적으로 해결한 방식입니다.
부가 설명
HTTP/1.1에서는 여러 이미지, CSS, JS를 받기 위해 connection 수 제한 안에서 병렬 요청을 보냅니다. HTTP/2에서는 같은 origin에 대해 하나의 connection을 재사용하면서 여러 stream을 동시에 보낼 수 있습니다.
이 차이 때문에 과거에는 domain sharding, sprite image 같은 최적화가 유리했지만, HTTP/2 환경에서는 오히려 효과가 줄거나 불리할 수 있습니다.
HTTP/2가 항상 모든 문제를 해결하는 것은 아닙니다. TLS 설정, server/proxy 지원, resource 우선순위, bundle 전략 등 실제 성능은 여러 요소에 영향을 받습니다.