이 글은 웹 개발자
Nathaniel
님이 자신의 블로그endtimes.dev
에 작성한 다음의 글을 한국어로 옮긴 것입니다 : Why your website should be under 14kb in size
작은 웹 사이트일수록 더 빠르게 로드됩니다. 이는 놀라운 일이 아닙니다.
놀라운 것은, 14kB
인 페이지가 15kB
인 페이지보다 612ms
나 더 빠르게 로드될 수 있다는 점입니다.
이는 TCP slow start
알고리즘 때문입니다. 이 글에서는 이것이 무엇인지, 어떻게 동작하는지, 그리고 왜 관심을 가져야 하는지를 다룹니다. 다만 그러기에 앞서, 몇 가지 기본적인 내용을 빠르게 살펴보겠습니다.
Transmission Control Protocol(TCP)
란 Internet Protocol(IP)
을 통해 데이터 패킷을 신뢰성 있게 전송하는 방법을 말합니다. 이를 TCP/IP
라고도 합니다.
브라우저가 웹 사이트(또는 이미지, 스타일시트)를 요청할 때, HTTP
프로토콜을 사용합니다. HTTP
는 TCP
상에서 구축되며, 단일 HTTP
요청은 보통 많은 TCP 패킷으로 구성됩니다.
한편, IP
는 인터넷의 어떤 한 위치에서 다른 위치로 데이터 패킷을 전송하는 시스템일 뿐입니다. IP
는 패킷이 목적지에 성공적으로 도착했는지 확인할 방법이 없습니다.
웹 사이트에서는 모든 데이터가 도착했다는 사실을 아는 것이 중요합니다. 그렇지 않으면 웹 페이지의 일부(chunk)가 누락될 수 있습니다. 다만 실시간 비디오 스트리밍과 같이, 이것이 그다지 중요하지 않은 경우도 존재합니다.
TCP
는 브라우저와 웹사이트의 서버가 성공적으로 도착한 패킷을 서로 알 수 있도록 하는 IP
의 확장된 개념입니다.
서버는 패킷의 일부를 송신한 다음, 패킷을 수신했다는 브라우저의 응답(이를 '확인 응답' - Acknowledgement, ACK 라고 합니다)을 기다립니다. 그런 다음 이전보다 더 많은 패킷을 송신하거나, ACK
를 받지 못했다면 패킷을 다시 송신합니다.
TCP slow start
는 서버에서 한 번에 얼마나 많은 패킷을 송신할 수 있는지 확인하는 데 사용되는 알고리즘입니다.
브라우저가 처음으로 서버에 연결할 때에는, 상호 간의 대역폭(bandwidth)을 확인할 방법이 없습니다.
대역폭은 단위 시간 당 네트워크를 통해 전송할 수 있는 데이터의 양을 말합니다. 일반적으로 초당 비트 수(bits per seconds, bps)로 측정됩니다. 보통 배관에 비유되기도 하는데, 초당 파이프에서 나오는 물의 양이라고 생각하면 됩니다.
서버는 해당 연결에서 얼마나 많은 데이터를 처리할 수 있을지 알 수 없기 때문에, 일반적으로 10개의 패킷만을 송신하여 작은 규모로 안전하게 프로세스를 시작하게 됩니다.
패킷이 사이트 방문자에게 성공적으로 도달하면, 방문자의 컴퓨터는 패킷을 수신했다는 응답(ACK)을 다시 보냅니다.
그런 다음 서버는 더 많은 데이터를 보내는데, 이때는 패킷의 양을 이전보다 두 배로 늘립니다.
이러한 프로세스는 패킷이 손실되고 서버가 더 이상 ACK 응답을 받지 않을 때까지 반복됩니다. (이 시점에서 서버는 패킷을 계속 송신하지만, 속도는 더 느립니다)
이것이 TCP slow start
의 요지입니다. 실제 알고리즘은 더 다양한 형태이지만, 본질적으로 동작하는 방식은 이렇습니다.
대부분의 웹 서버에서, TCP slow start
알고리즘은 10개의 TCP 패킷을 송신하는 것으로 시작합니다.
이때 TCP 패킷의 최대 크기는 1500bytes 입니다.
이 값은 TCP 스펙에서 결정된 것이 아니며, 이더넷 프레임(Ethernet frame)에서 비롯된 것입니다.
각 TCP 패킷은 헤더에서 40bytes 만큼을 사용합니다. (IP에서 16bytes, TCP에서 24bytes)
그러면 이제 TCP 패킷 당 1,460bytes가 남습니다. 10개의 패킷을 보내므로, 10 * 1460 = 14600 bytes
, 대략 14kB가 됩니다.
따라서 웹사이트 또는 웹사이트의 중요한 부분의 데이터 사이즈를 14kB에 맞출 수 있다면, 방문자와 웹사이트의 서버 사이를 한 번 왕복(Round Trip)하는 데에 걸리는 시간을 절약할 수 있을 것입니다.
사용자들은 굉장히 조급해합니다. 한 번의 왕복 시간은 경우에 따라 매우 길어질 수도 있는데, 이는 지연 시간(latency)이 얼마나 되느냐에 달려 있습니다.
지연 시간이란 데이터 패킷이 소스에서 대상(목적지)로 이동하는 데에 소요된 시간을 말합니다. 대역폭이 초당 파이프를 통과할 수 있는 물의 양이라면, 지연 시간은 한 방울의 물이 파이프에 들어갔다가 다른 쪽으로 나오는 데 소요된 시간입니다.
다음은 지연 시간이 얼마나 나쁜 것인지를 보여주는 재미있는 예입니다 :
위성 인터넷은 지구 주위를 도는 인공위성에 의해 제공됩니다. 인구가 매우 적은 지역, 석유 굴착 장치(oil rigs), 유람선 및 항공사 기내 WiFi 등에서 사용됩니다.
지연 시간의 나쁜 예를 설명하기 위해, 석유 굴착 장치에서 실제 주사위가 아니라 14kB 미만의 missingdice.com 사이트를 통해서 Dungeons & Dragons* 게임을 플레이해야 한다고 가정해 보겠습니다.
*역주) 여러 사람들이 테이블에 모여 앉아 주사위를 사용해 각자 역할을 연기하며 즐기는 게임(TRPG)입니다.
스마트폰으로 웹 페이지 요청을 위성 안테나로 보내기 위해, WiFi 라우터로 데이터를 전송하는 데에 먼저 1ms
가 소요됩니다.
그런 다음 위성 안테나는 해당 데이터를 지구 궤도에 위치한 위성으로 보내야 합니다.
일반적으로 이는 지구 표면에서 35,786km
떨어진 정지 궤도에 위치하는 위성을 통하게 됩니다. 빛의 속력은 299,792,458m/s
이므로 지구에서 위성으로 데이터를 보내는 데 120ms
가 소요됩니다. 그러면 위성은 메시지를 지상국(기지국)으로 다시 보내고, 이때 다시 120ms
만큼 소요됩니다.
이제 지상국에서는 웹사이트의 서버로 요청을 전송해야 합니다(이때 광케이블에서 광속은 200,000,000m/s 까지 느려질 수 있습니다). 지상국과 서버의 거리가 뉴욕과 런던 사이의 거리(5,569km)라면 28ms
정도가, 뉴욕과 시드니 사이의 거리(15,993km)라면 80ms
가 소요될 것입니다. 여기서는 계산의 편의를 위해 60ms
로 하겠습니다.
서버에서 수신된 요청을 처리하고, 결과를 다시 전송하는 데에는 10ms
정도가 소요될 것입니다.
지상국으로, 우주로, 위성 안테나로, 그 다음 WiFi 라우터로, 그리고 다시 스마트폰으로 돌아갑니다.
스마트폰 -> WiFi 라우터 -> 위성 안테나 -> 위성 -> 지상국 -> 서버 -> 지상국 -> 위성 -> 위성 안테나 -> WiFi 라우터 -> 스마트폰
합산해보면 10 + ( 1 + 120 + 120 + 60 ) * 2 = 612ms
가 됩니다.
이는 매 왕복마다 추가로 소요되는 시간입니다. 기다리는 시간이 그다지 길지는 않을 수도 있겠지만, 웹사이트에서는 첫 번째 리소스를 가져오기 위해 많은 왕복을 거쳐야 할 수 있습니다.
또한, HTTPS라면 첫 번째 왕복을 수행하기 전에 두 번의 추가 왕복이 필요하므로, 이 때는 1836ms
가 소요될 수 있습니다.
위성 인터넷은 의도적으로 나쁜 예를 든 것으로 보일 수 있습니다. 하지만 지상에서도 아래와 같은 이유들로 지연 시간이 나빠질 수 있습니다 :
또한 연결이 불안정한 경우에는 패킷이 손실될 수도 있으며, 이 때에는 패킷을 다시 가져오기 위해 왕복이 다시 발생합니다.
물론 웹사이트를 가능한 가볍게 만들어야 합니다. 각 페이지를 14kB 미만으로 맞추는 것이 좋은 목표입니다.
이때 14kB는 압축을 포함하므로, 압축되지 않은 실제 데이터 기준으로는 50kB 정도라고 할 수 있겠습니다.
자동 재생 동영상, 팝업, 쿠키, 쿠키 수락 배너, 소셜 네트워크 버튼, 추적 스크립트, 자바스크립트 및 CSS 프레임워크, 그리고 기타 불필요한 정크 등을 줄인다면 이러한 목표에 도달할 수 있을 것입니다.
중요한 CSS나 JS, 앱 사용 방법을 설명하는 텍스트의 처음 몇 단락 등과 같이, 렌더링시 유용한 데이터를 가급적 처음 전송되는 14kB 내에 포함되도록 할 수도 있습니다.
참고 : 14kB 규칙에는 압축되지 않은 HTTP 헤더도 포함되어 있습니다(첫 번째 응답에서 HTTP/2를 사용하는 경우에도). 이는 이미지도 마찬가지이므로, 스크롤 없이 먼저 볼 수 있는 부분만 로드하면서 크기를 작게 유지하거나, placeholder를 사용하여 사용자가 기다려야 한다는 사실을 인지할 수 있도록 할 수 있습니다.
14kB 규칙은 컴퓨팅의 기본적인 규칙이라기보다는 일종의 경험적인 법칙에 더 가깝습니다 :
TCP slow start
의 초기 window size(단위 시간 내에 송신하는 패킷의 수)를 조정하여 패킷 수를 10개에서 30개로 증가시켰습니다.HTTP/2와 14kB 규칙
HTTP/2를 사용하면 해당 규칙이 더 이상 유효하지 않다는 의견이 있습니다. 이와 관련된 모든 글들을 읽어보았으나, HTTP/2를 사용하는 서버가 TCP slow start
를 사용하지 않다는다는 증거를 발견하지 못했습니다.
HTTP/3 및 QUIC
HTTP/2와 유사하게, HTTP/3 및 QUIC에서 14kB 규칙을 없앨 것이라는 이야기가 있습니다. 그러나 이는 사실이 아닙니다. QUIC는 동일하게 14kB 규칙을 권장합니다.