HTTP에서의 압축

압축은 웹 사이트의 성능을 높이는 중요한 방법입니다. 어떤 문서에 대해, 70%가 넘는 사이즈 축소는 필요로 하는 대역폭 용량을 낮춰줍니다. 수년간, 알고리즘은 점점 더 효율적으로 변해왔고, 클라이언트와 서버에 의해 새로운 것들이 지원되고 있습니다.

실제로, 웹 개발자들은 압축 메커니즘을 구현해야 할 필요가 없고, 브라우저와 서버가 그것들을 이미 구현하고 있어서, 개발자들은 서버가 잘 구성되어 있는지 확인만 하면 됩니다. 압축은 세 개의 서로 다른 계층에서 일어납니다.

  • 먼저 몇 개의 파일 형식이 최적화된 특유의 방법으로 압축됩니다,
  • 그런 뒤 HTTP 계층에서 일반적인 암호화가 일어납니다(리소스는 끝단 간에 압축되어 전송됩니다),
  • 그리고 마침내 압축이 HTTP 커넥션의 두 노드 사이의 커넥션 계층에서 정의될 수 있습니다.

파일 포맷 압축

각각의 데이터 타입은 그 안에서 공간을 낭비하는, 몇 가지 중복을 가지고 있습니다. 텍스트가 일반적으로 60% 정도의 중복을 가지고 있다면, 오디오와 비디오 같은 다른 미디어들에게 이 비율은 훨씬 더 높아질 수 있습니다. 텍스트와 다르게, 이런 다른 미디어 타입들은 저장하는데 많은 공간을 차지하고 이런 낭비된 공간을 되돌려놓으려는 요구는 매우 이른 시기에 나타났습니다. 엔지니어들은 특정 목적을 위해 설계된 파일 포맷이 사용하는 최적화 압축 알고리즘을 설계했습니다:

  • 무손실 압축은 압축-비압축 사이클이 복원된 데이터를 변경하지 않는 것을 말합니다. 원래의 데이터와 복원 데이터는 일치(byte 단위까지)합니다. 이미지에서는, gif 혹은 png가 무손실 압축을 사용합니다.
  • 손실 압축은 사용자가 인지하기 힘든 방법 내에서 원래의 데이터를 사이클이 변경하는 것을 말합니다. 웹에서의 비디오 포맷은 손실 압축이며, 이미지에 경우에는 jpeg이 그렇습니다.

어떤 포맷들은 webp처럼 무손실 혹은 손실로 이용 가능하며, 일반적으로 손실 알고리즘은 그 과정이 무손실 혹은 좀 더 나은 품질을 이끌도록 좀 더 나은 혹은 무손실의 압축을 가능하도록 구성될 수 있습니다. 사이트의 좀 더 나은 성능을 위해, 수용 가능한 수준의 품질을 지키면서도 가능한 많이 압축하는 것이 이상적입니다. 이미지의 경우, 도구가 만들어 낸 이미지는 웹을 위해 충분히 최적화되지 않을 수도 있습니다; 요구되는 품질를 유지하면서 가능한 많이 압축하는 도구를 사용하는 것을 추천합니다. 이것에 특화된 많은 도구들이 있습니다.

손실 압축 알고리즘은 무손실 압축 알고리즘보다 일반적으로 효율적입니다.

참고: 압축이 특정 종류의 파일에서 더 잘 동작하므로, 파일을 두번 압축하는 것은 보통 아무런 도움이 되질 않습니다. 사실, 오버헤드 비용(알고리즘은 보통 초기의 크기에 추가할 사전을 필요로 합니다)이 크기가 큰 파일을 낳는 압축에서의 추가적인 이득보다 크므로, 자주 생산성 측면의 문제에 맞닥뜨리게 됩니다. 압축된 포맷의 파일들에 다음 두 기술을 사용하지 마시기 바랍니다.

종단 간 압축

압축에 있어, 종단간 압축은 웹 사이트의 가장 큰 성능 이득이 발생하는 곳입니다. 종단간 압축은 서버에 의해 처리되고 클라이언트에 도달할 때까지 결코 변하지 않을 메시지 바디의 압축을 나타냅니다. 중간 노드가 무엇이든지, 바디는 건들이지 않고 그대로 둡니다.

모든 모던 브라우저와 서버들은 종단간 압축을 지원하며 협상하는 유일한 것은 사용할 압축 알고리즘입니다. 이런 압축 알고리즘들은 텍스트에 최적화되어 있습니다. 1990년대에, 압축 기술은 급격한 속도로 진보되고 있었으며 많은 수의 성공적인 알고리즘들이 선택 가능한 후보군에 추가되었습니다. 오늘날에는, 오직 두 개의 알고리즘만이 적절한 후보군입니다: 가장 일반적인 gzip, 그리고 새로운 도전자인 br이 그것이죠.

사용할 알고리즘을 선택하기 위해, 브라우저와 서버는 사전 컨텐츠 협상을 사용합니다. 브라우저는 브라우저가 지원하는 알고리즘 그리고 그것의 우선순위와 함께 Accept-Encoding 헤더를 전송하며, 서버는 그 헤더를 뽑아내서 응답의 바디를 압축하는데 사용하고 서버가 선택한 알고리즘을 Content-Encoding 헤더를 사용해 브라우저에게 알려줍니다. 컨텐츠 협상이 그것의 인코딩에 근거한 표현을 선택하는데 사용되므로써, 적어도 Content-Encoding을 포함하는 하나의 Vary 헤더가 반드시 응답 내 해당 헤더에 붙어 전송되어야 합니다; 그러한 방법으로, 캐시는 리소스의 다른 표현을 캐시하는게 가능해질 겁니다.

압축이 명확한 성능 향상을 가져다주므로, 모든 파일에 대해 활성화하는 것을 추천하지만, 이미지, 오디오나 비디오와 같은 파일들은 이미 압축되어 있을 겁니다.

Apache는 압축을 지원하며 mod_deflate를 사용합니다; nginx의 경우 ngx_http_gzip_module 모듈이 있고 IIS는 <httpCompression> 엘리먼트를 지원합니다.

Hop-by-hop 압축

종단간 압축과 비슷하긴 하지만, hop-by-hop 압축은 한 가지 필수적인 엘리먼트에 의해 차이가 납니다: 전송되게 될 구체적인 표현을 만들어내는, 서버 내에서 리소스에 대한 압축이 일어나지 않고, 클라이언트와 서버 사이의 경로 상에 있는 어떤 두 노드 사이에서 메서지의 바디에 압축이 일어납니다. 이따르는 중간 노드 간의 커넥션들은 다른 압축을 적용할수도 있습니다.

이를 위해, HTTP는 종단간 압축에서의 컨텐츠 협상과 유사한 메커니즘을 사용합니다: 요청을 전송하는 노드는 노드의 요청이 TE (en-US) 헤더를 사용하고 있다는 것을 알려주고 다른 노드들은 알맞는 방법을 선택하여 적용하고 Transfer-Encoding 헤더를 사용해 선택한 내용을 가리킵니다.

실제로, hop-by-hop 압축은 서버와 클라이언트에게는 보이지 않으며 드물게 사용되고 있습니다.TE (en-US) 헤더와 Transfer-Encoding 헤더는 리소스의 길이를 알지 못한 상태로 전송을 시작하도록, 청크에 의해 응답을 전송하는데 대부분 사용됩니다.

Hop 계층에서 Transfer-Encoding 헤더와 압축을 사용하는 것은, Apache, nginx 혹은 IIS와 같은 대부분의 서버들이 그것을 구성할 수 있는 쉬운 방법이 존재하지 않을 만큼 희귀합니다. 그런 구성들은 보통 프록시 계층에 적용됩니다.