avatar
Published on

HTTP1 vs HTTP2

Author
  • avatar
    Name
    yceffort

HTTP/1.1 vs HTTP/2

HTTP(Hypertext Transfer Protocol)는 1989년에 만들어진 월드 와이드 웹의 통신 표준이다. 1997년 HTTP/1.1이 릴리즈된 이래로 프로토콜이 거의 수정된 적이 없었다. 그러나 2015년에는 HTTP/2 버전이 나오면서 사용되기 시작했다. 이 버전에서는 모바일 플랫폼, 서버 집약적인 그래픽과 비디오를 다룰 때 레이턴시를 줄일 수 있는 여러가지 방법을 제공하였다. HTTP/2는 그 이후로 점점더 많은 인기를 얻어서 현재는 모든 웹사이트의 1/3 정도가 HTTP/2를 지원하는 것으로 알려져 있다.

이 글에서는, HTTP/1.1과 HTTP2의 차이점을 알아보고, HTTP/2가 보다 효율적인 웹 프로토콜을 만들기 위해 채택한 기술적 변화를 살펴보자.

배경

HTTP/2가 HTTP/1.1에서 변경된 내용을 살펴보려면, 각 버전 별로 과거 어떻게 개발되었는지를 살펴볼 필요가 있다.

HTTP/1.1

1989년 Timothy Berners-Lee가 월드 와이드 웹의 통신 표준으로 개발한 HTTP는 클라이언트 컴퓨터와 로컬 또는 원격 웹 서버간에 정보를 교환하는 최상위 애플리케이션 프로토콜이다. 이 프로세스에서는 클라이언트는 GET POST와 같은 메소드를 호출하여 텍스트 기반 요청을 보낸다. 이에 대한 응답으로 서버는 HTML 페이지나 리소스를 클라이언트를 보낸다.

예를 들어, www.example.com 도메인 웹사이트로 방문한다고 가정해보자. 이 URL로 이동하면, 웹 브라우저가 텍스트 기반 메시지 형식으로 HTTP 요청을 날린다.

GET /index.html HTTP/1.1
Host: www.example.com

이 요청은 GET 메소드를 사용하였으며, Host:뒤에 나열된 서버에 데이터를 요청한다. 이 요청에 대한 응답으로, example.com 서버는 이미지, 스타일시트, 기타 HTML 의 리소스 등과 함께 HTML 페이지를 리턴한다. 한가지 알아둬야 할 것은, 첫 번째 데이터 호출 시에 모든 리소스가 클라이언트로 반환되는 것은 아니다. 웹 브라우저가 화면의 HTML 페이지를 렌더링하는데 필요한 모든 데이터를 받을 때까지 요청과 응답이 서버와 클라이언트를 왔다갔다 한다.

이런 요청과 응답의 교환은 transfer layer(일반적으로 TCP)와 network layer (IP) 의 최상단에 위치한 인터넷 프로토콜 스택의 단일 애플리케이션 계층으로 생각할 수 있다.

https://assets.digitalocean.com/articles/cart_63893/Protocol_Stack.png

HTTP/2

HTTP/2는 압축, 멀리플렉싱, 우선순위 지정 등의 기술을 사용하여, 웹 페이지 로드 레이턴시를 줄이려는 목적으로 구글에서 개발한 SPDY 프로토콜로 시작된 기술이다. 그 이후로 2015년 5월 HTTP/2가 발표되었다. 처음 부터 많은 모던 브라우저들이 표준화 작업을 지원했다. 이러한 지원 덕분에, 많은 인터넷 사이트들이 2015년 이후로 이 프로토콜을 채택하기 시작했다.

기술적인 관점에서, HTTP/2와 HTTP/1.1을 구별하는 가장 중요한 기능 중 하나는 인터넷 프로토콜 스택에서 애플리케이션 계층의 일부로 간주되는 binary framing layer다. 모든 요청과 응답을 일반 텍스트 형식으로 관리하는 HTTP/1.1과는 다르게, HTTP/2는 모든 메시지를 이진 형식으로 캡슐화 하는 동시에 verb, 메서드, 헤더 등의 HTTP 문법을 유지한다. 애플리케이션 layer api는 여전히 전통적인 HTTP 형식으로 메시지를 만들지만, 그 하단의 레이어는 이러한 메시지를 이진수로 변환한다. 이렇게 하면 HTTP/2 이전에 작성된 웹 애플리케이션이 새 프로토콜과 상호작용 할 때 정상적으로 작동할 수 있다.

메시지를 이렇게 2진수로 변환하면, HTTP/2가 HTTP/1.1에서는 사용할 수 없는 데이터 전송에 대한 새로운 접근 방식을 시도할 수 있다.

Delivery Model

앞서 언급했던 것처럼 HTTP/1.1과 HTTP/2는 같은 문법을 공유한다. 두 프로토콜 모두 서버와 클라이언트 사이를 이동하는 요청은 GET POST 같은 익숙한 방법을 사용하여, 세더와 본문이 있는 전통적인 형식의 메시지로 목적지에 도달하도록 한다. 그러나 HTTP/1.1은 이것을 일반 텍스트로 전달하는 방면, HTTP/2는 이를 이진수로 코딩한다.

HTTP/1.1 - Pipelining and Head-of-Line Blocking

클라이언트가 HTTP GET 요청에서 받는 최초의 응답은 가끔씩 완전히 렌더링 할 수 있는 페이지 형태가 아닐 수 있다. 이 페이지에 추가로 필요한 리소스의 링크가 포함되어 있다. 클라이언트는 페이지를 다운로드를 한 이후에야 비로소 페이지의 전체 렌더링에 추가로 리소스가 필요한 것을 알게 된다. 이로 인해 클라이언트는 이러한 리소스를 추가로 요청해야 한다. HTTP/1.0에서는 클라이언트는 모든 새로운 요청을 위해 TCP 연결을 끊고 새로 연결을 만들어야 해서 시간과 리소스 측면에서 많은 비용이 들었다.

HTTP/1.1은 영구적 연결(persistent connection)과 파이프라인을 도입하여 이 문제를 해결한다. 영구적인 연결을 사용하면 TCP 연결을 닫으라고 직접 요청하지 않는 이상 계속해서 연결을 열어둔다. 이를 통해 클라이언트는 동일한 연결을 통해 여러 요청의 각각의 응답을 기다리지 않고 전송할 수 있다.따라서 1.1에서 크게 성능이 향상되었다.

하지만 안타깝게도 이 최적화 전략에는 피할 수 없는 병목현상이 존재한다. 동일한 대상으로 이동할 때 여러 데이터 패킷이 동시에 통과할 수 없기 때문에, 대기열 앞에 있는 요청이 이후의 모든 요청이 차단되어 버린다. 이는 HOL (Head of line) 블로킹으로 알려져 있으며, HTTP/1.1에서 연결 효율성을 최적화 하는데 있어 중요한 문재다. 별도의 병렬 TCP 연결을 추가하면 이러한 문제를 완화할 수는 있지만, 클라이언트와 서버간에 동시에 연결할 수 있는 TCP숫자는 제한이 있으며, 새로운 연결은 상당한 리소스를 필요로 한다.

HTTP/2 - 이진 프레임 레이어의 장점

HTTP/2의 이진 프레임 레이어는 요청과 응답을 인코딩 하고 이를 더 작은 패킷으로 잘라 데이터 전송의 유연성을 향상 시킨다.

HOL 블로킹의 영향을 줄이기 위해 여러개의 TCP 연결을 사용하는 HTTP/1.1과는 다르게, HTTP/2는 두 컴퓨터 사이에 단일 연결 개체를 설정한다. 이 연결에는 여러 데이터 스트림이 있다. 각 스트림은 요청/응답 형식의 여러메시지로 구성된다. 마지막으로 이러한 각 메시지는 프레임이라는 작은 단위로 분할 된다.

https://assets.digitalocean.com/articles/cart_63893/Streams_Frames.png

가장 세분화된 레벨에서, 통신 채널은 각각 특정 스트림에 태그가 지정된 이진 인코딩 프레임 다발로 구성된다. 이렇게 만들어진 태그를 사용하면, 전송의 반대쪽 끝에서 다시 재조립할 수 있다. 인터리빙된 요청과 응답은, 멀티플렉싱이라는 프로세스 뒤에서 메시지를 차단하지 않고 병렬로 실행이 가능해진다. 멀티플렉싱은 다른 메시지가 완료될 때 까지 기다릴 필요가 없도록 하여, HTTP의 HOL 문제를 해결한다. 이는 서버 와 클라이언트가 동시에 요청과 응답을 보낼 수 있다는 것을 의미하므로, 제어 능력을 높이고 연결을 보다 효율적으로 관리할 수 있다.

통신에서 다중화(Multiplexing 혹은 MUXing)라는 용어는 두개 이상의 저수준의 채널들을 하나의 고수준의 채널로 통합하는 과정을 말하며, 역다중화(inverse multipleing, demultiplexing, demuxing) 과정을 통해 원래의 채널 정보들을 추출할 수 있다. 각각의 채널들은 미리 정의된 부호화 틀(coding scheme)을 통해 구분할 수 있다.

https://ko.wikipedia.org/wiki/%EB%8B%A4%EC%A4%91%ED%99%94_(%ED%86%B5%EC%8B%A0)

멀티플렉싱은 클라이언트가 여러 스트림을 병렬적으로 구성할 수 있게 해주기 때문에, 이들 스트림은 단일 TCP 연결만 사용하면 된다. 출처당 하나의 영구적인 접속은 네트워크 전체의 메모리와 처리 공간을 줄임으로써 HTTP/1.1에서 성능향상을 가져올 수 있게 된다. 네트워크 및 대역폭 활용도가 향상되어 전체 운영 비용이 절감된다.

클라이언트와 서버가 여러 요청과 응답에 대해 동일한 보안 세션을 재사용할 수 있으므로, 단일 TCP연결을 바탕으로 HTTPS 프로토콜의 성능도 향상된다. HTTPS에서는 TLS 또는 SSL 핸드셰이크 중에는 양 측이 모두 세션내내 단일 키를 사용하는 것에 동의 한다. 연결이 끊어지면 새로운 세션이 시작되므로, 추가 통신을 위해 새로운 키가 필요하다. 따라서 단일 연결을 유지하면, HTTPS 를 위해 필요한 리소스를 크게 줄일 수 있다. HTTP/2 규격에서 TLS 계층을 사용하도록 의무화 하지 않지만, 대부분의 브라우저는 HTTPS를 사용하는 HTTPS/2 만 지원한다.

이진 프렐임 레이어에 내재된 멀티플렉싱이 HTTP/1.1의 특정 문제를 해결하지만, 동일한 리소스를 기다리는 다중 스트림은 여전히 문제를 일으킬 수 있다.

HTTP/2 - 스트리밍 우선순위

Stream prioritization 동일한 리소스를 두고 경쟁이 일어나는 요청 사이의 문제를 해결할 뿐만 아니라, 개발자가 애플리케이션 성능을 더 잘 최적화 하기 위해 요청의 상대적 가중치를 정의할 수 있도록 도와준다.

아시다시피, 이진 프레임 레이어는 메시지를 병렬 데이터 스트림으로 구성한다. 클라이언트가 서버에 동시 요청을 보낼때, 각 스트림에 1 부터 256 사이의 가중치를 할당하여 요충 중인 응답의 우선순위를 지정할 수 있다. 숫자가 클 수록 우선순위 앞쪽에 있다. 이외에도 클라이언트는 각 스트림의 종속성을 ID로 지정하여 명시한다. 상위 ID가 없다면 루트 스트림에 종속된 것으로 간주된다. 아래 그림을 살펴보자.

https://assets.digitalocean.com/articles/cart_63893/Stream_Priority2.png

위 그림에서, 채널은 각 고유한 ID와 가중치를 가진 6개의 스트림이 포함되어 있다. 스트림1에는 부모 ID가 없으므로, 루트에 종속된 것으로 간주한다. 다른 그밖에 모든 스트림엔 부모 ID가 표시되어 있다. 각 스트림에 대한 리소스 할당은, 해당 스트림의 가중치와 필요한 종속성을 기반으로 한다. 예를 들어, 그림에서 동일한 가중치와 동일한 부모 스트림에 할당된 5, 6은 리소스 할당에 동일한 우선순위를 가진다.

https://assets.digitalocean.com/articles/cart_63893/Dependency_Tree.png

이 종속성 트리에서, 스트림1의 경우 루트에 의존하고, 루트에서 파생된 또다른 스트림이 없으므로 사용 가능한 모든 리소스가 다른 리소스보다 1에 먼저 할당된다. 스트림 2의 경우, 스트림1이 완료에 따라 달라 지므로 1이 완료될 때까지 2가 가지 않는다. 3, 4는 어떨까? 이는 모두 스트림2에 따라 달라진다. 2번 스트림은 3, 4보다 먼저 가용 리소스를 확보한다. 2의 작업이 완료되면, 3, 4는 리소스를 얻는데 가중치에 따라서 2:4로 분할되므로, 스트림 4에 대한 리소스 청크가 더 커진다. 3이 완료 되면, 5 와 6의 차례인데, 이 두개는 동일한 리소스를 얻게 된다. 스트림 4가 더 높은 리소스 청크를 수신하더라도, 4의 작업이 완료되기 전에 5, 6이 발생할 수 있다. 즉, 하위 레벨 스트림은 상위 레벨 스트림이 끝나는 순간에 즉시 시작할 수 있다.

애플리케이션 개발자는, 필요에 따라서 요청 가중치를 설정할 수 있다. 예를 들어, 웹 페이지에 미리보기 이미지를 먼저 제공한 뒤에, 고해상도 이미지를 로딩하는데 낮은 우선순위를 부여할 수 있다. HTTP/2는 이러한 가중치 할당 기능을 제공함으로써 개발자가 웹 페이지 렌더링을 더 잘 제어할 수 있도록 도와준다. 또한 프로토콜은 클라이언트가 사용자 인러택션에 대흥하여, 런타임 시에 종속성을 변경하고 가중치를 재 핼당 할 수 있도록 한다. 그러나 특정 스트림의 특정 리소스 액세스가 차단되는 경우에는, 서버 자체에서 우선순위를 변경할 수도 있다.

버퍼 오버플로우

두 시스템 간 TCP 연결에서, 클라이언트와 서버 모두 아직 처리되지 않은 수신요청을 보관하는데 사용할 수 있는 일정 크기의 버퍼 공간이 있다. 이러한 버퍼는 다운/업스트림 연결의 고르지 못한 속도나, 큰 요청에 대해서 유연하게 처리할 수 있다.

그러나 이러한 버퍼가 크지 않은 상황이 있을 수도 있다. 예를 들어, 서버가 제한된 버퍼 크기나 낮은 대역폭으로 인해 클라이언트 애플리케이션이 처리할 수 없는 속도로 많은 양의 데이터를 푸쉬하고 있을 수도 있다. 마찬가지로 클라이언트가 서버에 대용량 이미지나 비디오를 업로드 할 때 서버 버퍼가 오버 플로우 되어 패킷 손실이 일어날 수도 있다.

일어한 버퍼 오버 플로우를 방지하려면, 흐름제어 메커니즘은, 송신자가 수신자를 데이터로 압도하는 것을 방지해야 한다.

HTTP/1.1

HTTP/1.1에서 흐름제어 메커니즘은, TCP 연결에 의존한다. 연결이 시작되면, 클라이언트와 서버 모두 시스템 기본설정을 사용하여 버퍼 크기를 세팅해둔다. 수신자의 버퍼크기가 데이터로 채워지면, 버퍼에 남아있는 사용공간을 알려준다. 이러한 수신 윈도우는 ACK 패킷이라고 불리우는 시그널로 전송된다. 이 크기가 0이 되면, 클라이언트가 내부 버퍼를 지운다음 다음 데이터 전송을 다시 시작할 수 있도록 요청 할 때까지 발신자는 더 이상 데이터를 보내지 않는다. 여기서 주목해야할 점은, TCP 연결을 기반으로 하는 수신을 사용하면, 연결의 어느 한쪽 끝에만 흐름제어를 구현할 수 있다는 것이다.

HTTP/1.1은 버퍼 오버플로우를 피하기 위해 transport layer에 의존하므로, 각각의 새로운 TCP 연결은 별도의 흐름 제어 메커니즘을 필요로 한다.

HTTP/2

HTTP/2에서는, 단일 TCP 연결 내에서 데이터 스트림을 멀티플렉싱한다. 따라서 TCP 연결 레벨의 수신으로는 개별 스트림의 전송을 규제하는 것이 어렵다. 그래서 HTTP/2는 클라이언트와 서버가 transport layer에 의존하는 대신, 자체적인 흐름제어를 구현하도록 허용함으로써 이문제를 해결한다. application layer은 사용가능한 버퍼 공간을 통신하여, 클라이언트와 서버사이에서 멀티플렉스 스트림 수준에서 수신 창을 설정할 수 있도록 해준다. WINDOW_UPDATE 프레임을 통해서, 초기 연결후 흐름 제어 컨트롤을 제어하거나 수정할 수 있다.

이 방법은, application layer 레벨에서 데이터 흐름을 제어하기 때문에, 흐름 제어 메커니즘은 수신 창을 조정하기 전에 신호가 최종 목적지에 도달하는 것을 기다릴 필요가 없다. 중간 노드는 흐름제어 설정 정보를 참고하여 자체 리소스 할당을 결정하고, 그에 따라 수정이 가능해진다. 이러한 방식으로 각 중간 서버는 고유한 커스텀 리소스 전략을 구현하여 연결의 효율성을 높일 수 있다.

이러한 흐름 제어 유연성은, 적절한 리소스 전략을 생성할 때 유리해질 수 있다. 예를 들어, 클라이언트는 첫번째 이미지를 먼저 표시하고, 더 중요한 리소스를 가져오는 동안 그 이미지를 미리 볼 수 있도록 할 수 있다. 클라이언트가 중요한 리소스를 가져오면, 브라우저는 이미지의 나머지 부분을 다시 가져 온다. 따라서 흐름 제어 구현을 클라이언트와 서버로 미루면 웹 애플리케이션의 성능을 향상 시킬 수 있다.

리소스 요청 예측

일반적인 웹 애플리케이션에서는, 클라이언트는 GET 요청을 보내서 HTML 페이지를 수신한다. (index.html) 이 index.html의 내용을 검사하는 동안, 클라이언트는 CSS 및 자바스크립트 파일과 같은 추가 리소스를 가여좌야 한다는 것을 발견한다. 클라이언트는 이러한 초기 GET 요청으로 부터 응답을 받은 후에만, 추가 리소스가 존재한다는 것을 알 수 있으므로, 이러한 리소스를 가져오고 페이지를 완성하기 위해 추가 요청을 해야한다. 따라서 추가적인 요청은 어쩔 수 없이 연결 로드 시간을 증가 시킨다.

그러나 이 문제는 해결책이 있다. 서버는 클라이언트가 추가 파일을 필요로 한다는 것을 미리 알 수 있기 때문에, 서버가 이러한 요청을 받기전에 리소스를 클라이언트로 전송하여 시간을 절약할 수 있다.

HTTP/1.1 - 리소스 인라이닝

이 기술은, 서버가 초기 GET에 응답하여 보내는 HTML 문서에 직접 필요한 리소스를 포함해서 보내줄 수 있다. 클라이언트가 페이지를 렌더링하기 위해 CSS 파일이 필요한 경우, 해당 요청이 오기전에 필요한 리소스를 제공하여 클라이언트가 보내야하는 요청수를 줄인다.

그러나 이러한 리소스 인라이닝에는 몇가지 문제가 있다. HTML 문서에 이렇게 리소스를 포함 시키는 것은, 텍스트 형식이 아닌 큰 파일이 있을 경우 HTML 문서의 크기를 증가시켜, 결국에는 연결 속도가 감소되어 이 기술로 얻는 이점이 상쇄되어 버린다. 그리고 인라인 리소스는 HTML 문서와 분리되지 않았으므로 클라이언트가 이미 가지고 있는 리소스를 거부하거나, 캐시를 쓸 수 있는 매커니즘이 없다. 즉, 가장 큰 단점은 리소스와 문서를 분리할 수 없다는 것이다.

HTTP/2 - 서버 푸쉬

HTTP/2는, 클라이언트의 초기 GET요청에 대해 여러개의 동시 응답을 허용하므로, 서버는 요청한 HTML 페이지와 함께 클라이언트에 리로스를 전송하여, 클라이언트가 요청하기 전에 리소스를 제공할 수 있다. 이를 서버 푸쉬라고 한다. 이러한 방식으로 HTTP/2 연결은 푸시된 리소스와 문서간의 분리를 유지하면서, 리소스 인라인이라는 목표를 동시에 달성할 수 있다. 이는 클라이언트가 메인 HTML 문서외에 다른 리소스를 거절할 수 있다는 것을 의미한다.

HTTP/2에서 이 프로세스는 PUSH_PROMISE라는 프레임을 전송하여 클라이언트에게 리소스가 푸시될 것임을 알리면서 시작된다. 이 프레임에는 메시지의 헤더만 존재하고, 클라이언트에서 서버가 푸시할 리소스가 포함되어 있다. 이미 캐시된 리소스가 존재하는 경우 클라이언트는 RST_STREAM 프레임을 응답으로 전송하여, 푸시를 거부할 수 있다.또한 PUSH_PROMISE 프레임은 서버가 어떤 리소스를 푸시할 것인지 알기 때문에, 서버에 중복 요청을 보내지 않도록 도와준다.

여기에서 중요한 것은 클라이언트 제어다. 클라이언트가 서버 푸시 우선 순위를 조정하거나, 서버 푸시를 비활성화해야하는 경우, 언제든지 SETTINGS 프레임을 보내 이 HTTP/2 기능을 수정할 수 있다.

이 기능이 많은 잠재력을 가지고 있는 것 같지만, 서버 푸시가 꼭 정답은 아니다. 예를 들어 일부 웹 브라우저는, 클라이언트에 미지 캐시된 리소스가 있더라도 푸시된 요청을 항상 취소할 수는 없다. 클라이언트가 서버에 중복된 리소스를 보낼 수 있도록 허용한 경우, 서버에 푸쉬를 해버리면 연결이 불필요하게 낭비될 수 있다. 따라서 서버 푸쉬는 개발자의 재량에 달려있다.

압축

웹 애플리케이션을 최적화하는 일반적인 방법은, 압축 알고리즘을 사용하여 클라이언트와 서버간의 HTTP 메시지 크기를 줄이는 것이다. HTTP/1.1과 HTTP/2에서 모두 이 전략을 사용하고는 있지만, 전자의 경우 전체 메시지를 압축하는 것을 금지하는 것을 구현하는데 문제가 있다.

HTTP/1.1

gzip 등의 기술은 CSS, 자바스크립트 파일의 크기를 줄이기 위해 HTTP 메시지로 전송되는 데이터를 압축하는데 오랫동안 사용되어져 왔다. 그러나 메시지의 헤더는 항상 일반 텍스트로 전송된다. 각 헤더는 상당히 작지만, 많은 요청이 이루어질 수록 이 압축되지 않은 헤더의 존재는 데이터의 부담이 가중되며, 특히 많은 다른 리소스간 요청이 필요한 복잡한 API를 사용하는 웹 애플리케이션에게 불이익이다. 또한 쿠키를 사용하게 되면, 헤더가 커지므로 어떻게든 압축을 하는 것이 필요할 수 있다.

HTTP/2

HTTP/2에서 반복적으로 등장하는 중요한 포인트 중 하나는, 이진 프레임 레이어를 사용하여 세부 정보에 대한 제어권을 높일 수 있다는 것이다. 헤더 압축도 마찬가지다. HTTP/2에서는 데이터에서 헤더를 분할하여 헤더 프레임과 데이터 프레임을 생성할 수 있다. 그런다음 HTTP/2 전용 압축 프로그렘 HPACK이 헤더를 압축할 수 있다. 이 알고리즘은 Huffman coding을 사용하여 헤더 메타데이터를 인코딩할 수 있으므로 크기를 크게 줄일 수 있다. 또한 HPACK은 이전에 전송된 메타데이터 필드를 추적하고, 클라이언트와 서버간에 공유된, 동적으로 변경된 인덱스에 따라서 해당 필드를 추가로 압축할 수 있다. 아래 예시를 살펴보자.

request 1

method:     GET
scheme:     https
host:       example.com
path:       /academy
accept:     /image/jpeg
user-agent: Mozilla/5.0 ...

request 2

method:     GET
scheme:     https
host:       example.com
path:       /academy/images
accept:     /image/jpeg
user-agent: Mozilla/5.0

이 요청들에서 method scheme host accept user-agent 등 많은 값들이 있지만, path의 값만 다르다. HPACK은 따라서 다른 값인 path만 아래와 같이 보낸다.

request 1

method:     GET
scheme:     https
host:       example.com
path:       /academy
accept:     /image/jpeg
user-agent: Mozilla/5.0 ...

request 2

path:       /academy/images

HPACK과 다른 압축 방법을 사용해서, HTTP/2는 클라이언트와 서버사이의 레이턴시를 감소시키는 기능을 제공할 수 있게 되었다.

결론

위에서 살펴보았듯이, HTTP/2는 여러 면에서 HTTP/1.1과 다르다. 일부 기능은 웹 애플리케이션 성능을 최적화 하는데 있어 사용할 수 있는 제어 수준을 높이고, 이진 프로토콜을 통해서 성능을 개선시켰다. 이제 두 프로토콜 간의 변화에 대해 이해했으므로, HTTP/2의 멀티플렉싱, 스트림 우선순위 지정, 흐름제어, 서버 푸시와 압축과 같은 요소가 웹 개발 환경에 어떤 영향을 미칠지 판단할 수 있다.

HTTP/1.1과 HTTP/2 사이의 성능 비교해보려면, 구글의 데모페이지를 참고해보면 좋다. 로컬 머신에서 테스트 시, 페이지 로드 시간은 테스트시 사용가능한 대역폭, 클라이언트 및 서버 리소스등과 같은 몇가지 요인에 따라 달리질 수 있다. 보다 포괄적인 테스트 결과는 여기에서 참고할 수 있다.

출처: https://www.digitalocean.com/community/tutorials/http-1-1-vs-http-2-what-s-the-difference