HTTP utvecklades inte. påtvingad Förändras genom fysik, latens och missbruk.
Varje version finns eftersom den tidigare träffade en hård begränsning. Om du förstår dessa begränsningar, du förstår varför webben fungerar som det gör - och varför så många "bästa praxis" faktiskt fungerar runt för protokoll begränsningar vi har släpat runt i trettio år.
Jag har byggt webbapplikationer sedan 1997. Jag har felsökat HTTP/1.0 anslutningsstormar, sett webbläsare öppna sex anslutningar per värd som en "feature", förbannade på HTTP/2: s TCP head-of-line blockering på mobila nätverk, och slutligen sett HTTP/3 erkänna vad vi visste hela tiden: nätverket är problemet.
Det är historien om hur vi kom hit.
HTTP/1.0 utformades 1996 för en värld som inte längre existerar. För att förstå varför det fungerade måste du förstå vad "webben" betydde 1996:
I denna värld, var flaskhalsen bandbreddEn 50KB-sida tog 15 sekunder att ladda ner på uppringning. Vem brydde sig om ett extra 200ms handslag?
Vad HTTP/1.0 optimerat för:
GET /index.html HTTP/1.0
Host: example.com
HTTP/1.0 200 OK
Content-Type: text/html
<html>...
Elegant, perfekt för 1996 och helt oanvändbar för allt bortom dokumentsökning.
Sedan förändrades nätet.
År 1998 var sidor inte bara dokument. De hade stilmallar, JavaScript, flera bilder. En enda sida kan behöva 20-30 separata resurser.
Varje enskild begäran som krävs:
En sida med 20 resurser betydde 20 TCP handslag. På en 200 ms latency anslutning (fortfarande vanligt), det är 4 sekunder av bara handskakning Innan något innehåll överförs.
Det grundläggande antagandet av HTTP/1.0:
Tiden var billig.
1996 var det. Bandbredden var flaskhalsen. 1999 förbättrades bandbredden men Det var inte latency. - och plötsligt dessa turer betydelse.
HTTP/1.0 utformades för dokument. Webben hade blivit en applikationsplattform. Något måste ge.
HTTP/1.1 anlände 1997, precis som webben exploderade. Dotcom-boomen började. Varje företag behövde en webbplats. Webbsidor blev komplexa - tabeller för layout, JavaScript för interaktivitet, bilder överallt.
Trycket var tydligt: Uppkoppling-per-request var att döda prestanda. Men helt omdesigning HTTP var inte ett alternativ. För mycket infrastruktur redan berodde på det. Lösningen måste vara bakåtkompatibel.
Vad som förändrades:
Connection: keep-alive Som standard) - återanvända TCP-anslutningenCache-Control, ETag, villkorliga ansökningar)Det som inte förändrades:
GET /page.html HTTP/1.1
Host: example.com
Connection: keep-alive
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Cache-Control: max-age=3600
...
HTTP/1.1 löste faktiskt inte prestandaproblemet.
Pipelining var ett misslyckande. Specen tillät att skicka flera förfrågningar på en anslutning, men:
Så webbläsare fuskade. Istället för att fixa protokollet, arbetade de runt det:
static1.example.com, static2.example.com) för att multiplicera anslutningarInget av detta var protokollet som fungerade som planerat. Det var hela ekosystemet kompensera för HTTP/1.1 grundläggande begränsning.
HTTP/1.1 skalas genom fusk, inte genom att fixera modellen.
HTTP/1.1 fungerade - Bra nog. Inte för att det var bra, utan för att miljön kompenserade:
Vi hade tur att världen gömde den.
Dessa sex anslutningar per värd var inte gratis:
Webben blev snabbare i HTTP/1.1-eran, men inte på grund av HTTP/1.1. Det blev snabbare eftersom:
Vi byggde en applikationsplattform på ett protokoll, men vi kände det inte än.
År 2010 var webbprestanda en ständig kamp mot HTTP själv.
Erans "bästa metoder" berättar historien:
Var och en av dessa är en lösning för "HTTP/1.1 kan inte hantera många förfrågningar på ett effektivt sätt".
Jag byggde många av dessa små verktyg som sprite generatorer, CSS kompressorer, vi började använda respons compression etc ...
Webbläsare var inte snabbare eftersom HTTP förbättrades. De var snabbare eftersom de fungerade runt HTTP.
Sex anslutningar per värd är inte en funktion. Det är en hacka. Domän skärning är inte en bästa praxis. Det är ett erkännande av misslyckande.
Jag spenderade år att lära utvecklare att bunta tillgångar, sprite bilder, och inline kritiska resurser. Inget av det var "bra arkitektur." Det var Kontroll av protokollskador.
Myten "HTTP är enkel" kvarstod eftersom komplexiteten var gömd i:
HTTP/1.1 fungerade eftersom allt runt Det jobbade övertid för att kompensera.
Om du någonsin har sett ett diagram över HTTP som inte visar latens, förlust eller fellägen, så ljuger det för dig. Protokollet är enkelt. Verkligheten är inte det.
År 2010 hade webben förändrats igen. Två massiva skift förändrade allt:
1. Mobilen hände. Den iPhone lanserades 2007. Av 2012, var mobil webbtrafik exploderande. Plötsligt var användarna inte på trådbundet bredband - de var på 3G, sedan 4G, med variabel latens och frekventa paket förlust. Antagandena som gjorde HTTP/1.1 tolerable bröt ner.
2. Webbprogram ersatte webbsidor. Gmail. Google Maps. Facebook. Twitter. Dessa var inte dokument med länkar. De var program som behövde dussintals eller hundratals resurser, uppdateringar i realtid, och omedelbar respons. "sex anslutningar per värd" hacka visade sin ålder.
Google kände denna smärta akut. De hade massiv skala, prestandabesatta ingenjörer, och data för att bevisa HTTP/1.1 var flaskhalsen. 2009 startade de SPDY - ett experimentellt protokoll som skulle bli HTTP/2.
Vad som förändrades:
┌──────────────────────────────────────────┐
│ Single TCP Connection │
├──────────────────────────────────────────┤
│ Stream 1: GET /page.html │
│ Stream 3: GET /style.css │
│ Stream 5: GET /app.js │
│ Stream 7: GET /logo.png │
│ (all interleaved, no ordering required) │
└──────────────────────────────────────────┘
Detta är vad HTTP/1.1 pipeline borde ha varit. Strömmar är oberoende. Ett långsamt svar blockerar inte andra. Headers är komprimerade. Protokollet matchade slutligen hur vi faktiskt använder webben.
HTTP/2 var perfekt för bredbandsnätet. Och 2015, när det standardiserade, bredband var allmänt förekommande i den utvecklade världen.
Vad som förbättrades:
För användare på trådbundna anslutningar med låg paketförlust, HTTP/2 var en verklig förbättring. Riktmärken såg bra ut. Mätvärdena förbättrades. Google förklarade seger.
Men världen hade redan gått vidare. Mobilen var nu majoriteten av webbtrafiken.
Och mobila nätverk har en grundläggande egenskap som bredband inte: paketförlusten är konstant.
TCP-garantier leverans i ordning. Om paket 47 försvinner, paket 48-100 vänta tills 47 återförs - även om de tillhör helt oberoende HTTP/2 strömmar.
┌──────────────────────────────────────────┐
│ TCP Receive Buffer │
├──────────────────────────────────────────┤
│ [pkt 45][pkt 46][ ? ][pkt 48][pkt 49] │
│ ↑ │
│ Waiting for packet 47 │
│ │
│ Stream 1 data: BLOCKED │
│ Stream 3 data: BLOCKED │
│ Stream 5 data: BLOCKED (has pkt 48-49) │
│ Stream 7 data: BLOCKED │
└──────────────────────────────────────────┘
HTTP/2 löste head-of-line-blockering vid applikationslagret. Sedan återinförde TCP det vid transportlagret.
Ett borttappat paket stannar alla strömmar. På en ren trådbunden anslutning, paketförlust är sällsynt. På mobila nätverk, förlorade WiFi, eller överbelastade länkar? Packet förlust är konstant. Och eftersom HTTP/2 använder en enstaka anslutning (genom design), ett förlorat paket nu block allt Istället för bara en av sex kontakter.
HTTP/2 prestanda:
Ironin: HTTP/2 var utformad för mobil, men TCP: s garantier gjorde det värre på mobilen än det protokoll den ersatte.
De första HTTP/2-utplaceringarna visade på verkliga förbättringar:
Men svans latency berättade en annan historia. medianvärde P99 blev sämre.
Jag såg detta på egen hand: en klient aktiverade HTTP/2 över deras CDN och tittade på mobil P99 latency ökning Av 40% . De instrumentpaneler visade förbättring på skrivbordet . Support biljetter kom från mobila användare . Vi tillbringade en vecka med att räkna ut att HTTP/2 " förbättring " var att göra saker värre för majoriteten av deras trafik .
När HTTP/2 fungerar, fungerar det vackert. När ett paket sjunker på en mobil anslutning i värsta ögonblick, allt fryser. Och användare märker fryser mer än de märker snabba medianer.
Det grundläggande problemet:
HTTP/2 antog att TCP var tillräckligt bra.
För bredband var det, för mobilt var det inte det. Och när HTTP/2 hade standardiserats, hade mobilen redan vunnit. Vi hade drivit så långt som TCP kunde ta oss.
År 2015 var bevisen tydliga: TCP var problemet.
Google hade kört QUIC experimentellt sedan 2012. De hade data. På mobila nätverk, förlorade WiFi och hög-latens anslutningar, HTTP/2 över TCP misslyckades på sätt som inte kunde fixas utan att ändra transportskiktet.
Men du kan inte bara "fixa TCP." Det implementeras i operativsystemets kärnor. Det är bakat i varje router, brandvägg och mellanbox på internet. Att ändra TCP innebär att vänta årtionden på att hela internetinfrastrukturen ska uppgraderas.
Så Google gjorde något djärvt: De byggde ett nytt transportprotokoll ovanpå UDP..
UDP är "dumb" av design - det bara skickar paket utan garantier. Men det är precis vad du behöver om du vill genomföra din egen tillförlitlighet semantik. QUIC reimplementerar TCP: s garantier (tillförlitlig, beställd leverans) men gör det per bäck istället för per anslutning.
HTTP/3 (2022) är HTTP över QUIC. Det är medgivandet som vi behövde för att gå under HTTP för att fixa HTTP.
Vad som förändrades:
┌──────────────────────────────────────────┐
│ QUIC Connection │
├──────────────────────────────────────────┤
│ Stream 1: [pkt][pkt][pkt] ← flowing │
│ Stream 3: [pkt][ ? ][pkt] ← waiting │
│ Stream 5: [pkt][pkt][pkt] ← flowing │
│ Stream 7: [pkt][pkt] ← flowing │
│ │
│ Lost packet only affects Stream 3 │
└──────────────────────────────────────────┘
Det som förblev detsamma:
HTTP/3 ändrade inte HTTP, det förändrade hur HTTP överlever verkligheten.
QUIC genomför TCP:s tillförlitlighetsgarantier per bäck, inte per anslutning . Detta är den viktigaste insikten .
TCP:s löfte: "Varje byte kommer i ordning." QUIC:s löfte: "Varje byte i denna ström kommer i ordning."
Det är därför HTTP/3 inte kollapsar på förlorade nätverk.
Andra QUIC funktioner som fixar långvariga problem:
Anslutningsmigrering:
Phone on WiFi → walks out of range → switches to cellular
TCP: Connection dies. Restart everything.
QUIC: Connection ID maintained. Streams continue.
Detta är viktigt eftersom mobila användare konstant Byta nätverk. Gå ut ur ditt hus, förlora WiFi, byta till mobil. Med TCP, varje anslutning dör. Med QUIC, anslutningen fortsätter.
0-RTT återupptagande:
First connection: Full handshake (1-RTT)
Returning user: Send data immediately (0-RTT)
Kryptering överallt:
TCP + TLS: Handshake, then encrypted tunnel
QUIC: Encryption is the handshake (TLS 1.3 integrated)
HTTP/3 är designad för den värld vi faktiskt lever i:
Protokollet matchar slutligen nätverksverkligheten. Trettio år efter HTTP/1.0 antog tillförlitliga trådbundna anslutningar, medger HTTP/3 att tillförlitlighet är undantaget, inte regeln.
HTTP/3 är inte gratis:
Men för mobil-första applikationer, opålitliga nätverk, och latency-känsliga tjänster, HTTP/3 är den första versionen som matchar hur nätverk faktiskt beter sig.
Varje HTTP-version ändras eftersom miljön förändrades snabbare än protokollet.
Omvandling av miljö på grund av att den gick sönder på grund av att den gick sönder |---------|-----|-------------|------------|--------------| på HTTP/1.0 på 1996 på Dialup, dokument på Bandwidth är flaskhalsen sidor blev appar, latency betydelsed .. HTTP/1.1 ..1999-2015 .. .. Bredband, webbappar ..låg latency döljer ineffektivitet .. Mobile anlände med paketförlust .. på HTTP/2 på 2015-2022 på bredbandstoppen, mobilt stigande TCP är pålitlig nog på mobilen blev dominerande, TCP misslyckades på HTTP/3 2022+ på mobilen först, globalt och inget är pålitligt, fortfarande utplacerande...
Mönstret är tydligt:
Varje abstraktion som verkade tillräcklig fick vika tillbaka när miljön krävde det.
Övriga iakttagelser:
Det här är den obekväma delen, trots trettio års protokollutveckling.
Begäran misslyckas fortfarande. Nätverkspartition. Servers kraschar. Tidsgränser inträffar. Din kod behöver fortfarande försökslogik.
Nätverken ljuger fortfarande. 200 OK betyder inte att svaret är korrekt. Anslutning stängd betyder inte att begäran inte lyckades. Tidsgränser betyder inte att servern inte behandlade din begäran.
Kackerlackor tjänar fortfarande gamla data.
Cache-Control är en begäran, inte ett kommando. Proxies gör vad de vill. CDN-invalidering är i bästa fall.
Kunderna försöker fortfarande dåligt. Användaren klickar på knappen, ingenting händer, klickar igen. Nu har du två önskemål. Idempotency frågor.
Utvecklare missförstår fortfarande idepotens. PUT borde vara idempotent.
// This is still your problem, regardless of HTTP version
public async Task<Result> CreateOrderAsync(Order order)
{
// What happens if this times out?
// Did the server receive it?
// Did it process it?
// Will the client retry?
// Will you create duplicate orders?
// HTTP/3 doesn't save you here.
// Idempotency keys do.
}
Om du inte förstår dessa, HTTP/3 kommer inte att rädda dig.
Efter att ha byggt webbprogram över alla dessa protokoll versioner, här är vad som fastnade:
1. Protokollet är inte din pålitlighet lager.
HTTP ger dig begäran / svar semantik. Det garanterar inte leverans, korrekthet, eller exakt en gång bearbetning. Det är ditt jobb.
2. Latency är fienden, inte bandbredden.
De flesta prestandaproblem är runda-trip bundna, inte genomströmning bundna. Reducera förfrågningar gäller mer än komprimera nyttolaster.
3. Varje "bästa praxis" har ett utgångsdatum.
Domänskärvning var nödvändig för HTTP/1.1. Det är skadligt för HTTP/2. Att markera CSS var smart. Nu har vi serverpush (som också misslyckades) och tidiga tips. Taktiken ändras. Målet (reducera latency) förblir detsamma.
4. Mäta på verkliga nätverk.
Riktmärken på localhost bevisar ingenting. Dina användare är på mobila nätverk, hotell WiFi och mättade kafé anslutningar. Testa där.
5. De tråkiga delarna betyder mest.
Tidsgränser. Retries. Kretsbrytare. Idempotency. Anslutning pooling. Dessa oglamorösa detaljer avgör om ditt system fungerar under belastning.
HTTP blev inte snabbare för att det blev smartare. nätverket var problemet.
Varje version var rätt för sin tid:
Misstaget var att tro att någon av dem var permanenta lösningar. De var alla svar på specifika miljöpåfrestningar. När miljön förändrades, skulle protokollet följa.
HTTP-versioner är inte uppgraderingar i konsumentbetydelse. De är kompromisser optimerade för olika feldistributioner.
Och ändå, efter allt detta, de grundläggande förblir:
Problemen försvann inte, de bara rörde sig.
Bygg system som överlever misslyckanden. Testa på riktiga nätverk. Förstå att varje HTTP-version är en kompromiss formad av sin era, inte en uppgradering som föråldrade det som kom tidigare.
Det är trettio år av HTTP. Det är webben vi byggde. Och i ytterligare ett decennium, HTTP/3 antaganden kommer förmodligen att se lika daterad ut som HTTP/1.0 gör nu.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.