Front-end vývojáři, dejte si pozor na HTTP2! Mohli byste webům škodit.

HTTP2 změní způsob, jakým vytváříme webové aplikace. Nejčastější a nejlepší optimalizační praktiky z HTTP1 jsou při použití nového protokolu kontraproduktivní a škodlivé. Pokud je budete používat, můžete stránky výrazně zpomalovat.
HTTP1.X je pro většinou stávajících stránek pomalé a neefektivní. Jde o starý protokol, který byl navržen dlouhou dobu před tím, než se vůbec tušilo, jaké podoby web dosáhne. Přestože stávající protokol koná svou práci, není příliš efektivní, neboť po něm požadujeme mnohem komplexnější služby, než pro jaké byl původně navrhnut.
Aby se HTTP1 stránka načetla v rozumném čase, musíme si mnohdy pomáhat sérií hacků, abychom vymáčkli ze starého protokolu maximum:
Nejčastější optimalizační techniky
Sprites
Anglicky sprites, českoanglicky často „sprity“ či „sprajty“, je technika skládání několika různých, obvykle menších, obrázků či ikon do jednoho velkého souboru. Soubor je pak následně napozicován v CSS tak, aby se zobrazila pouze výseč, jen malá část tohoto obrazu, kde je původní obrázek umístěn.

Ukázka spritu (obrázek pochází z wikipedie)
Concatenating
Concatenating, česky zřetězení, je slučování více CSS či JS souborů do jednoho obrovského. Technika se obvykle řeší programově, přes různé task runnery (například známý Grunt). CSS concatenating kupříkladu umožňuje LESS, SASS či Stylus, což jsou nástroje, které rozšiřují CSS o různé dynamické prvky a kromě zmiňovaného zřetězení umí výsledný soubor i zminifikovat a řadu jiných fint. JS concetating ve své úplně nejjednodušší formě umí program Prepros, kde stačí na začátek libovolného js souboru definovat, které soubory se mají spojit a jak a pokud necháte program skrytý na pozadí, všechno udělá za vás.
Assets z domén bez cookies
Poskytování assetů z domén nezatížených cookies. Assets jsou dodatečné zdrojové soubory, kupříkladu sady písem, css soubory, neobsahové obrázky a podobně. Pro tento případ se obvykle používá specializovaných služeb, neboť se poskytování assetů hůře řeší na vlastním serveru (ale lze to). Jednou z takových služeb je systém zvaný Content Delivery Network (CDN), u nás například velmi populární český CDN77.
Sharding
Sharding, neboli vytváření více domén nebo sub-domén k hostování assetů, jako jsou obrázky. Rovněž se hůře řeší na vlastním serveru (serverech), je snažší použít pro to specializovanou službu.
Aktuální implementace
První dvě techniky jsou navrženy k tomu, aby se vyhýbaly několikanásobným HTTP requestům. V HTTP1 je požadavek (request) velmi drahá záležitost. Trvá příliš dlouho a každý požadavek může být doslova naládován cookies, které spolu s ním musí být pokaždé zasílány. Navíc žádný z nich není komprimován. Je proto rychlejší sloučit několik souborů dohromady a mít všechno přeneseno najednou, než poskytovat jednotlivé soubory odděleně.
Třetí technika se používá k tomu, aby zminimalizovala čas nutný k získání assetů – aby odstranila cookies, které je třeba neustále zasílat jako část požadavku, což ústí k tomu, že pokaždé je zároveň přenesena řada bordelu. Pokud jednotlivé soubory umístíte na různé domény, které nepoužívají cookies, tyto soubory pak nebudou nebudou cookies zatíženy a celý proces se výrazně zrychlí.
Poslední technika, sharding, existuje teprve krátce. Vznikla po implementaci HTTP/1.1 specifikací, které omezují počet http requestů pro jednu (sub)doménu na pouhé dva.
V dřívějších dobách se maximální počet spojení se serverem výrazně lišil. Některé prohlížeče podporovaly 8 až 15 requestů, což přinášelo zároveň řadu problémů.
Pro porovnání podpora trvalého spojení se serverem u starších prohlížečů:
- Firefox 2: 2
- Firefox 3: 6
- Opera 9.26: 4
- Safari 3.0.4: 4
- IE 7: 2
- IE 8: 6 (pro dial-up vytáčené připojení bylo číslo mnohem nižší)
Se snížením počtu requestů (lze říci, že průměr předtím byl kolem 4 najednou), se začala rozvíjet právě zmiňovaná technika sharding, která dokáže tento limit obejít tak, že se jednotlivé zdrojové soubory (assets) rozdistribují mezi různé domény, takže prohlížeč obvykle přistupuje v jednom čase k více souborům. Z toho důvodu se také často doporučuje u frameworků a jiných volně dostupných css či js souborů používat CDN server, pokud jej tvůrci nabízejí. Zjednodušeně řečeno, techniku sharding používáte, když například nejpoužívanější js framework jQuery nenutíte uživatele stahovat z vašeho serveru, ale ve svém zdrojového html souboru nalinkujete volně dostupný script z adresy http://code.jquery.com/jquery-latest.min.js
Budoucnost s HTTP2
HTTP2 je téměř zde, je založeno na síťovém protokolu SPDY a dělá všechno mnohem efektivnější. Což ale také znamená, že všechny optimalizační techniky z HTTP1 se stávají škodlivými. Udělají HTTP2 stránku pomalejší, nikoliv rychlejší, čili důrazně varuji, pokud vyvíjíte stránku, kde víte, že bude nový http protokol – nepoužívejte je!
HTTP2 řeší problém s více požadavky efektivněji, pomocí technik, které dělá automaticky:
- Umožňuje otevřenou komunikaci pro zpětné použití requestu, čili není třeba nového zasílání hlaviček a tudíž složitého navazování komunikace, kterou HTTP1 potřebuje pro každý nový soubor
- HTTP2 oproti HTTP1 rovněž používá kompresi nejen dat, ale i hlaviček, čili velikost každého požadavku je výrazně nižší a tudíž rychlejší
- HTTP2 umí multiplexovat – umí odesílat a přijímat více souborů v té samé chvíli zapomocí jednoho spojení
To znamená, že starší HTTP1 techniky optimalizace zmiňované v tomto článku nejen že nejsou třeba, ale zároveň vše zpomalují. Velmi často tak můžete načítat soubory, které nejsou v tuto chvíli pro danou stránku potřeba, což jsou problémy, které defaultně vytváří concatenation a sprity. Zároveň sharding v důsledku komunikaci s DNS servery (DNS lookups) vše zpomalí, a to nehledě na to, že taková věc v HTTP2 již vůbec není potřeba.
Zjednodušeně řečeno – budete-li vytvářet frontend pro stránku o které víte, že bude přenášena přes HTTP2 – ujistěte se, že nepoužíváte optimalizační techniky, které znáte z HTTP1, mohli byste stránky výrazně zpomalovat.
Kde hledat informace dále
- Volně dostupný ebook od Daniela Stenberga
- Specifikace tvůrců protokolu na Githubu
- Podpora v prohlížečích
- Rychlostní demo porovnávající HTTP2 s HTTP1.1
Vznik článku byl inspirován článkem od Matta Wilcoxe
Přijde mi, že by bylo lepší dát závěr na začátek článku.
Já si myslím, že by se tím ztratilo rozdělení do odstavců „co se dělá teď“ – „proč se to tak dělá“ – „jak se to bude dělat“, které má kontinuální návaznost. Ale psaní článků nerozumím.
Přijde mi pořád efektivní mít zvláštní doménu na servírování statického obsahu. I když jsou hlavičky komprimované, stále je zbytečné je přenášet tam a zpět, pokud nejsou vůbec potřeba. Navíc mám pocit, že v dnešní době, kdy převažují asymetrická připojení k internetu (kde download může být třeba 10* rychlejší než upload), se výrazněji ušetří přenosový čas každého požadavku.
Souhrn:
Ano, to rozhodně bude mít efekt. U HTTP/1.x do té doby, než narazí na omezený počet requestů (ale v tom případě už by se sharding s více (sub)doménami vyplatil). A u HTTP/2 tím, že nebude přenášet zmíněné komprimované hlavičky. Čili proč ne.
Concatenating považuji i za součást obfuskace. Podle vzoru: Krádeži nelze zabránit, ale každá další překážka může rozhodnout o tom, že už se to nevyplatí krást.
A k tomu závěru se došlo teoreticky, nebo na základě měření skutečného webu servírovaého přes oba protokoly? Ptám se, protože v článku jsou různé nepřesnosti.
Závisí na tom, kterou z optimalizačních metod posuzujete. Sharding/používání dodatečných (sub)domén je díky multiplexování a concurrency neefektivní. A slučování souborů (sprity/concenation) je zase zbytečné díky server push, který defacto dělá něco podobného. Nesporná výhoda je v tom, že nemusíte přenášet jeden velký soubor s tisíci nevyužitými css pravidly/js funkcemi/obrázky, ale pro každou stránku se stáhne jen to, co je aktuálně třeba. Protože nynější protokol není stavěný na to, aby ke stránce bylo přiloženo třeba 70 css souborů. A právě ty nevyužité části souborů v dnešním případě docela bolí na mobilních zařízeních, kde se zbytečně stahují javascriptové balíky, které mnohdy nejsou třeba. Určitě znáte desítky serverů, které použijí framework pro jednu jejich podstránku, ale includují jej na všech stránkách a uživatel jej tak mnohdy ani nepotřebuje, protože tu danou podstránku nikdy nenavštíví.
Co se týká benchmarku, jeden je k článku přiložen: https://http2.akamai.com/
Pokud jsou v článku nepřesnosti, sem s nimi. Vždycky je co vylepšit.
Co třeba změna obrázku na najetí myši? Nebude to problikávat? Není tohle třeba výjimka kdy spritesheet použít?
Momentálně to nemohu vyzkoušet a tudíž nechci fabulovat. Myslím si však, že z návrhu http2 se přenese push cache spojená s danou stránkou a tudíž se stáhne i hover obrázek, problikávat to pak nebude. Berte to ale spíš jako subjektivní názor, než jako fakt.
Tak to v HTTP/1.1 funguje stejně, spojení se standardně neuzavírá, v HTTP/1.0 jde toto chování vynutit pomocí hlavičky Keep-Alive
HTTP/1.1 samozřejmě kompresi podporuje, viz hlavička Content-Encoding (nepodporuje však komprimaci hlaviček)
HTTP2 je bezesporu mnohem lepší a efektivnější, ale nemá cenu šiřit o HTTP/1.0/1.1 bludy.
Upraveno. Děkuji! :)
Aneb jak si na webové stránky zatáhnout zranitelnost.
Je celkem sranda, že na rootu dnes vyšli články o bezpečnosti a zde se nabádá k používaná nebezpečných věcí.
Tohle vkládání javascriptu od kdejaké služby je strašlivá hloupost a neznalost. A navíc přes http. Je to jak, kdyby ste dali klíče od bytu náhodnému kolemjdoucímu a on Vám slíbyl, že po dobu dovoléne Vám zaleje kytky, ano nic se nemusí stát nebo taky po příjezdu zjistíte, že Vám krom zalívání kytek také vybílil.
Tady bych viděl prostor pro vylepšení prohlížečů. Kdyby kodér mohl místo konkrétního url odkazovat na knihovnu s názvem XYZ ve verzi vM.N s nějakým checksumem a fallback url a prohlížeč by to držel v samostatné cache sdílené mezi weby, mohlo by to zejména na mobilech dost přenosu dat ušetřit.
ano to by mohla být cesta, dokonce by možná stačil checksum pro identifikaci,
jen je otázkou co by na to řekli provozovatelé cdn, že jim někdo leze do zelí.
ale teď vážně, většina postupů, rad a triků jak zvíšit rychlost načítání vebů je vlastně marginální v porovnaná s nutností cucnout si jquery, jquery.ui nebo bootstrap ….. opravdu zazdílení obsahu těchto knihoven by by bohatě stačilo
Na to už tu máme W3C draft http://www.w3.org/TR/SRI/
Tohle jsem přesně hledal. Díky!
To je sice všechno hezké, ale co když chci ty HTTP2 vychytávky používat už teď? Existuje nějaká funkční serverová implementace, vhodná do produkce? Třeba „server push“ by se mi sakra hodil…
Přehled podpory na serverech jsem našel na https://en.m.wikipedia.org/wiki/HTTP/2#HTTP.2FHTTPS_servers všude tam zatím vidím experimental nebo beta.
Případně na stránce: https://github.com/http2/http2-spec/wiki/Implementations lze nalézt řadu implementací pro různé jazyky. Protože jde o experimentální implementace, je jejich vhodnost do produkce otázkou. Ale pokud se Vám podaří něco podobného bezproblémově rozjet, můžete říci, že máte jeden z prvních (českých) serverů na tomto protokolu. Já osobně o žádném neslyšel (což ale pranic neznamená).