HTTP/1.1: skąd wzięły się waterfall i bundling
- data
- kategoria
- Networking
- także w
- Frontend
- czytanie
- 1 min / 205 słów
Frontendowe praktyki takie jak:
bundle everything
sprite sheets
inline small assets
domain sharding
nie powstały przypadkiem.
Duża część była odpowiedzią na koszt wielu requestów w HTTP/1.1.
Jeden connection, sekwencyjne odpowiedzi
Uproszczony model:
connection A:
request 1 -> response 1
request 2 -> response 2
Jeżeli response 1 jest wolny, kolejny request na tym connection musi czekać.
HTTP/1.1 miał pipelining, ale problemy wdrożeniowe i head-of-line behavior sprawiły, że browsery w praktyce polegały głównie na kilku równoległych connections.
Model strony wyglądał więc mniej więcej:
conn 1 ─ CSS ───── image
conn 2 ─ JS ─ font
conn 3 ─ image ─ image
...
Liczba równoległych torów była ograniczona.
Request overhead miał znaczenie
Każdy request niósł textual headers:
GET /assets/icon.svg HTTP/1.1
Host: example.com
Cookie: ...
Accept: ...
Przy setkach małych zasobów overhead był zauważalny.
Stąd bundling:
100 JS files
|
v
bundle.js
Zyskiwaliśmy mniej requestów kosztem większego pliku i gorszej granularności cache.
Domain sharding
Jeśli browser ograniczał równoległe connections per host, można było rozbić zasoby:
static1.example.com
static2.example.com
i uzyskać więcej równoległych połączeń.
Ale płaciliśmy:
more DNS
more TCP
more TLS
Był to hack wynikający z ograniczeń warstwy transportowej.
Frontend architecture dopasowała się do protokołu
To ważny wniosek.
Optymalizacje build tooling nie są niezależne od sieci.
Jeśli transport premiuje:
few large files
bundler będzie próbował zmniejszać liczbę requestów.
Jeśli transport radzi sobie dobrze z wieloma równoległymi streamami, optimum może przesunąć się w stronę:
more granular resources
better caching
selective loading
Oczywiście koszt requestu nigdy nie spada do zera.
Ale jego charakter się zmienia.
Największa zmiana HTTP/2
HTTP/2 nie zmienił tego:
GET /app.js
Nie zmienił też:
200 OK
Cache-Control: ...
Zmienił sposób przenoszenia wielu requestów przez connection.
Zamiast:
several connections
each mostly sequential
dostaliśmy:
one connection
many concurrent streams
To jest multiplexing.
I to fundamentalnie zmieniło frontendowy network waterfall.