HTTP2로 성능향상 (1.1 -> 2)

Joowon Jang·2025년 10월 27일
post-thumbnail

학교 수업 때도 배우고, 면접 준비를 하면서도 공부했었던 CS 지식을 실무에 적용하면서 사용자 경험 측면에서도 서버의 부담에 있어서도 유의미한 개선이 있었던 뜻깊은 경험이라 생각해 정리해봅니다.

프로젝트에서 http1.1 사용 발견

회사에서 개발 중인 서비스의 신규 기능 개발로 바빴었는데, 마무리되어 가는 단계라 여유가 생겨 오류 수정이나 개선할 부분이 없는지 찾아보고 있었다.
그렇게 아무 생각없이 Lighthouse를 통해 페이지의 렌더링 성능을 측정했더니...

Lighthouse를 사용해 오면서 처음보는 경고가 보였다.
http버전이 오래되었다고?
그래서 찾아보니 개발자 도구의 Network 탭에서 'Protocol'이라는 항목을 볼 수가 있었다.

그런데, http1.1이라고? 내가 잘못 본 건가?
일단, 공부를 해보자!
금요일에 발견했기 때문에, 퇴근하고 주말동안 오랜만에 CS 책을 펴서 네트워크 전반에 대해 공부를 했다.

http 버전에 따른 차이
https://velog.io/@juwon98/http#http-%EB%B2%84%EC%A0%84%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%B0%A8%EC%9D%B4

표로 정리한 HTTP/1과 HTTP/2의 차이

연결방식 - 멀티플렉싱(Multiplexing)

특징HTTP/1.1HTTP/2
설명하나의 TCP 연결에서 한 번에 하나의 요청/응답만 처리할 수 있어, 이전 요청의 응답이 늦어지면 다음 요청도 지연되는 Head-of-Line (HOL) Blocking 문제가 발생. 이를 회피하기 위해 여러 개의 연결을 만들지만, 더 많은 리소스를 소모함.하나의 TCP 연결 내에서 여러 개의 요청과 응답을 동시에 주고받을 수 있음(Multiplexing). 요청과 응답은 프레임(Frame)이라는 작은 단위로 쪼개져 독립적인 스트림(Stream)으로 전송되므로, HOL Blocking 문제가 해결되고 연결 효율이 좋아짐.

리소스 전송 - 서버 푸시(Server Push)

특징HTTP/1.1HTTP/2
설명클라이언트가 HTML 파일을 받은 후, 그 안에 포함된 CSS, JavaScript, 이미지 등의 필요한 리소스를 다시 요청.클라이언트가 HTML 파일을 요청했을 때, 서버가 해당 HTML에 필요할 것이라고 예상되는 리소스 (CSS, JS 등)를 클라이언트의 별도 요청 없이 미리 함께 전송해 줄 수 있음. 클라이언트의 추가 요청 대기 시간을 줄여 로딩 속도를 향상.

헤더 처리 - 헤더 압축 (Header Compression)

특징HTTP/1.1HTTP/2
설명요청마다 쿠키와 같은 메타 정보가 포함된 헤더를 압축 없이 전체 전송. 웹페이지에 많은 리소스가 필요해 요청이 많아질수록 중복된 헤더 정보가 불필요하게 대역폭을 소모하는 비효율이 발생.HPACK 압축 방식을 사용하여 헤더를 압축하고, 중복되는 헤더 필드는 정적/동적 헤더 테이블을 활용해 인덱스만 전송하여 실제 전송되는 헤더 크기를 대폭 줄임.

데이터 형식 - 바이너리 프레이밍 (Binary Framing)

특징HTTP/1.1HTTP/2
설명사람이 읽을 수 있는 텍스트 기반(Plain-Text)이어서 파싱이 복잡하고 오류 발생 가능성이 있음.바이너리(Binary) 형식으로 인코딩하여 전송하여 파싱 속도를 빠르게 하고, 효율성을 높이며, 오류 발생 가능성을 줄임.

+ 사실상 TLS(HTTPS) 사용 강제

  • HTTP/1.1: HTTP 통신(암호화 없음)과 HTTPS 통신(TLS 암호화 적용) 모두 지원함.
  • HTTP/2: 프로토콜 표준 자체는 TLS 사용을 의무화하지 않지만, Google Chrome, Firefox 등 주요 웹 브라우저들이 HTTP/2의 도입 시 보안 강화를 위해 TLS(HTTPS) 환경에서만 작동하도록 구현했다. 따라서 실제로 웹 서비스에서 HTTP/2를 사용하려면 HTTPS를 적용해야 함.

무조건 http3를 쓰면 되는거 아닌가?

아니다! 아래의 내용 참고
https://news.hada.io/topic?id=19816

HTTP/1.1 적용

Lighthouse 성능 측정 결과(77점)

LCP(Largest Contentful Paint)에 소요되는 시간이 굉장히 길고,
원인으로 ModernHTTP라는 항목이 있는 것을 확인할 수 있다.

(HTTP/2와 HTTP/3은 multiplexing처럼 HTTP/1.1보다 좋은 점을 많이 제공하고 있다는 내용)

퍼포먼스 77점

LCP 5.1초

Network 탭을 통해 확인한 “리소스를 받아오는 시간”

6개의 연결을 사용하고 각 연결마다 여러 번의 요청이 있음.

중간에 끊어지는 부분이 HOL Blocking으로 보임.

HOL Blocking

HTTP/2 적용

Lighthouse 성능 측정 결과(93점) (약 20% 성능 향상 / 페이지마다 편차 있음)

LCP에 소요되는 시간이 HTTP/1.1일 때는 5.1s였는데 HTTP/2에서는 1.7s로 1/3로 줄어든 것을 볼 수 있다.

퍼포먼스 93점

LCP 1.7초

Network 탭을 통해 확인한 “리소스를 받아오는 시간”

하나의 연결을 통해 여러 요청을 병렬로 진행.

세부 내용을 보면 css와 js 등을 받아오기 시작하는 시간도 HTTP/1.1보다 빠름(서버 푸시 때문으로 보임)

HTTP/2로 변경하고 발생한 문제 및 해결

단순히 nginx 설정에서 외부(브라우저)와의 연결을 http2로 설정하기만 했더니 몇 일 후에 서버가 멈춰버렸다. (테스트서버)

  • 기존에는 외부와의 연결이 http/1.1, 내부 연결은 http/1.0을 사용 중이었음
    • http/1.1한 번에 6~8개의 연결만 허용(연결 하나당 하나의 요청만 처리)
    • http/1.0은 기존의 연결을 재사용하지 않고 요청이 있을 때마다 새로운 연결을 수립
  • 변경 후에는 외부와의 연결이 http/2, 내부 연결은 http/1.0을 사용
    • http/2는 multiplexing을 사용하여 하나의 연결을 통해 수많은 요청을 동시에 처리

      → 외부와의 연결에서 한 번에 들어오는 수많은 요청으로 인해 내부에서 수많은 연결이 수립되고 해제되기를 반복하여 리소스가 고갈되는 문제가 발생한 것

      → 👍내부 연결을 http/1.1로 설정하여 최대 6~8개의 연결만을 수립하고 재사용하도록 하여 해결
      (HTTP/1.1을 사용한 이유: nginx가 내부 연결에 HTTP/2를 완벽하게 지원하지 않음. + 내부의 짧은 구간에서는 복잡한 HTTP/2의 프레임 처리를 하는 것보다, 단순한 HTTP/1.1 연결을 여러 개 유지(Keep-Alive)하는 것이 CPU 부하가 훨씬 적고 속도도 빠름.)

profile
깊이 공부하는 웹개발자

0개의 댓글