Komprimovat či nekomprimovat data pro HTTP

hknmtt

Komprimovat či nekomprimovat data pro HTTP
« kdy: 13. 01. 2023, 10:19:58 »
Narazil som pri vyvoji na dost hnusny bug. Respektive ani nie bug ale skor spravanie.
Mam http server kde pouzivam kompresny wrapper pre url handlery ktory automaticky komprimuje odpovede do gzip, brotli, deflate.. podla toho ktore z nich klient podporuje v accept-encoding headeri.

Doteraz to nebol problem, no robim teraz so subormi a "bug" bol ten ze mi rychlost stahovania dat isla len 1.9 mb/s a postupne padala na 300 kb/s. Takze 300Mb subor sa mi tahal na localhoste sialene dlho. Ked som wrapper odstavil tak sa subor stiahol instantne. Vsimol som si, ze mam nastavenu maximalnu kompresiu a preto ta rychlost bola pomala. Uspora miesta mala prioritu, co je pri beznych odpovediach v poriadku.

Pri beznych REST/JSON odpovediach ide o par kb takze tam problem nevznikal, ani z hladiska rychlosti, ale ked sa riesi velky subor tak nastane tento problem. A teda riesim, ze ci mam vobec riesit kompresiu pre subory, alebo nie? Inak povedane, rychlost vs datovy tok. Nejak nevidim moc dovod robit malu kompresiu a usetrit par percent na prevadzke takze mi pride ze tam asi kompresia ani nema vyznam byt potom.

Ako to riesit vy alebo podla akych pravidiel sa zariadujete?
« Poslední změna: 13. 01. 2023, 11:27:05 od Petr Krčmář »


Re:Balit, ci neablit?
« Odpověď #1 kdy: 13. 01. 2023, 10:35:20 »
A teda riesim, ze ci mam vobec riesit kompresiu pre subory, alebo nie? Inak povedane, rychlost vs datovy tok. Nejak nevidim moc dovod robit malu kompresiu a usetrit par percent na prevadzke takze mi pride ze tam asi kompresia ani nema vyznam byt potom.

Ako to riesit vy alebo podla akych pravidiel sa zariadujete?

Většina toho, co člověk z internetu stahuje je nějakým způsobem komprimovaná. Takže ano, to nemá. Jinak většina toho, co prohlížeč nezná má MIME typ application/octet-stream. Ten bych prostě z komprese vynechával automaticky. Tak to ostatně dělají i HTTP servery, že komprimují jen povolené typy.

A k tomu třeba můžete vynechávat všechno, co je větší než nějaká limitní velikost (třeba 1 MB), pokud tu informaci v hlavičce dostanete což většinou dostanete. A tam zase můžete přidat výimky pokud stahujete nějaká velká komprimovatelná data s jiným MIME typem. (Velké CSV soubory, typicky.) Na druhou stranu některé webové aplikace jsou neskutečně nafouknuté. Třeba taková Figma si stáhne cca 30 MB dat z čehož velkou část tvoří jen pár blobů a obrovské javascripty.

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #2 kdy: 13. 01. 2023, 17:28:54 »
Tady to vypadá jako nedostatek CPU, protože komprese probíhá on-line (v okamžiku vyřizování requestu). Hádám správně? Pokud ano, doporučuji komprimovat offline. To znamená, že dopředu vyberu statické resources, které chci komprimovat (typicky JavaScripty, txt logy, CSV dokumenty, apod), tyto 1x zkomprimuji pomocí zlib/brotli/gzip. Následně při vyřizování requestu se podívám jakou kompresi klient umí a podle toho vyberu (už zkomprimovaný) soubor na disku a pošlu ho.

Tonda

  • *****
  • 694
    • Zobrazit profil
    • E-mail
Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #3 kdy: 13. 01. 2023, 23:47:48 »
Určitě komprimovat, některý věci sou příšerně nafouknuté, ale otestovat si jak rychlé jsou jednotlivé kompresní metody při různých nastavení. Nastavení vyšší komprese celkem podstatně zvyšuje čas komprese, ale jen málo zmenšuje velikost výstupu
https://tukaani.org/lzma/benchmarks.html

hknmtt

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #4 kdy: 14. 01. 2023, 00:34:21 »
uz som to osefoval pridanim konfigurovatelnej urovne kompresie kde som ju pre subory nastavil na rychlost a pre bezne REST api nechal tak ako je. ale skor bude lepsie predkomprimovat subory dopredu, ako pise marek.


hknmtt

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #5 kdy: 14. 01. 2023, 10:02:04 »
samozrejme predkomprimovat subory je uplna blbost. ale to som pisal o pol jednej rano :)
proste som len upravil uroven kompresie podla typu requestu a dat ktore server vracia.

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #6 kdy: 14. 01. 2023, 11:37:49 »
u malých webů to je asi úplně jedno, mohu-li mluvit o velkých (miliony unikátních uživatelů měsíčně), tak online komprese na http serveru se nepoužívá, ale co je potřeba se komprimuje dopředu, jde zejména o statické soubory, tam se dá rozhodnout má-li to cenu nebo nikoliv, webový server pak zvolí správný předkomprimovaný soubor (logicky je přece mrháním výkonu milionkrát komprimovat každý soubor pro každého návštěvníka zvlášť).

Občas je potřeba komprimovat generovaný obsah z aplikace, o to se převážně starají sami aplikace nebo se přidá prostředník k aplikacím, který kompresování zajistí. Důvod je, že aplikační servery se škálují daleko lépe než ty proxy přes které teče obsah.


Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #7 kdy: 14. 01. 2023, 11:53:20 »
Důvod je, že aplikační servery se škálují daleko lépe než ty proxy přes které teče obsah.
To je dost odvážné tvrzení. Dovedu si představit případy, kdy to tak bude, ale častěji je to právě naopak. I proto se ty proxy servery (často spolu s poskytováním statických souborů) používají – protože je daleko jednodušší naškálovat proxy server než aplikační server.

Jinak se zbytkem souhlas – statické soubory komprimovat předem co nejlepšími kompresními metodami, vyplatí se jednou tomu věnovat víc cyklů procesoru a paměti a pak opakovaně posílat menší soubor. U proměnlivého obsahu se to musí řešit případ od případu, zda se to vůbec vyplatí komprimovat. Pokud se to dá postihnout rozumnými pravidly, je lepší to komprimovat až na proxy serveru, kde se to lépe škáluje. Ale mohou nastat i případy, kdy dává smysl nechat rozhodnout aplikační logiku o tom, zda odpověď komprimovat nebo nekomprimovat.

hknmtt

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #8 kdy: 14. 01. 2023, 12:19:34 »
sobory mozno komprimovat iba v pripade ze ide o archiv urceny na stiahnutie. ak ide o fotky alebo video ktore sa maju prezentovat v prehliadaci, tak komprimovat ich nemozno z toho dovodu, ze potom nemozu fungovat range requesty ani spravny content-length, mime a podobne veci. Proste skomprimovany subor je len blby blob uz. Preto sa vsetko zistuje na servery a komprimuje az na kabli. Ale mozno su nejake techniky ktore mi nie su zname na predkompresiu suborov v tomto kontexte?

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #9 kdy: 14. 01. 2023, 13:01:51 »
sobory mozno komprimovat iba v pripade ze ide o archiv urceny na stiahnutie. ak ide o fotky alebo video ktore sa maju prezentovat v prehliadaci, tak komprimovat ich nemozno z toho dovodu, ze potom nemozu fungovat range requesty ani spravny content-length, mime a podobne veci. Proste skomprimovany subor je len blby blob uz. Preto sa vsetko zistuje na servery a komprimuje az na kabli. Ale mozno su nejake techniky ktore mi nie su zname na predkompresiu suborov v tomto kontexte?
Nikoli, komprimují se třeba všechny textové soubory – HTML, CSS, SVG, JavaScript. Archiv určený pro stažení nemá smysl komprimovat, protože už zkomprimovaný je. To samé video, už je zkomprimované. U obrázků záleží na formátů – moderní formáty s vysokou kompresí nedává smysl komprimovat, u PNG nebo JPEG dává smysl kompresi lepším algoritmem vyzkoušet, může to velikost přenášených dat snížit. A u obrázků se range requesty nepoužívají.

Content-Length bude server posílat správně, o to se nemusíte bát. Stejně tak o Content-Type.

Celou dobu je řeč o transportním kódování, tj. je to kódování jenom pro přenos přes síť, prohlížeč si z toho zase vybalí ta původní nekomprimovaná data. A ano, dělá se to tak, že ty soubory jsou uložené na disku už předkomprimované právě pro to transportní kódování (často i zkomprimované více způsoby, aby server mohl odpovídat podle toho, jaké kódování podporuje klient). Takže server nemusí pořád dokola komprimovat to samé, ale použije to, co má už předkomprimované na disku.

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #10 kdy: 14. 01. 2023, 21:05:37 »
samozrejme predkomprimovat subory je uplna blbost

To samozřejmě není. Došlo tu k nedorozumění, každý mluvíme o trochu něčem jiném. Já mluvím o statickém obsahu jako jsou například za prvé css a js součásti html, nebo za druhé csv, log, txt data ke stažení. Je lepší je 1x-3x zkomprimovat dopředu (pokaždé jinou metodou) a poté je x-krát poslat klientům na každý jejich požadavek (podle toho jakou umí kompresi). Přesně za tímto účelem Google v roce 2013 představil zopfli/brotli, program, který komprimuje do starého dobrého zlibu, který umí všechny současné i minulé prohlížeče, ALE produkuje mnohem menší soubory za cenu mnohem, mnohem, mnohem větší spotřeby CPU a RAM. To nám ale nevadí, protože komprimujeme pouze 1x a pak milionkrát posíláme již zkomprimovaný soubor a tím šetříme traffic a https šifrování.

Ty mluvíš o za prvé datech typu png, jpeg a mpeg. Ty už jsou uvnitř zkomprimované a je tedy nesmysl je dále komprimovat http kompresí. Co je ale možné, je mít na serveru x variant stejného obrázku/fotky nebo videa v různých formátech jako je např. jpeg, jpeg-xl, heic, webp nebo mpeg, h264, h265, vp9, av1 a nabídnout klientovi všechny varianty a on si vybere tu nejlepší, kterou umí.

Za druhé mluvíš o výstupech z API, tam je to na zvážení, protože jde o dynamická data. Záleží na trade-off mezi časem potřebným k vygenerování dat + jejich kompresi vs ušetřený bandwidth. Na velmi pomalé lince se vyplatí komprimovat. To už tu rozebrali jiní diskutující.

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #11 kdy: 14. 01. 2023, 21:22:00 »
Ty mluvíš o za prvé datech typu png, jpeg a mpeg. Ty už jsou uvnitř zkomprimované a je tedy nesmysl je dále komprimovat http kompresí.
Jenom upřesním tohle – komprese používané v těchto formátech jsou starší a ne tak dobré a pokud nemůžete použít modernější datový formát s lepší kompresí, může se vyplatit ty málo zkomprimované soubory zkomprimovat ještě jednou výkonnějším algoritmem pro přenos. Ale jak jsem psal, je potřeba to ověřit v konkrétních případech, zda se to vyplatí.

hknmtt

Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #12 kdy: 14. 01. 2023, 21:28:23 »
ok, myslim ze je teda dolezite odlist ci je kontext dynamicky subor(html, css, js) alebo staticky(obrazok, video...). tzn. ci je mozne ze sa obsah suboru v buducnosti zmeni, alebo nie.

z debaty vyplyva ze nekomprimovat staticke subory, lebo tie uz zvecsa nejakou formou zkomprimovane su, len dynamicke.

ja som narazal prave na tie staticke.

takze je pre mna povodna otazka uzavreta. ale dost by ma zaujimalo, ak pride na tie dynamicke asety, ze ked si spravim napriklad brotli verziu nejakeho css suboru, ako tam potom funguje content type/mime, content size, range requesty a podobne, pokial nemam niekde ulozene tieto informacie a mozem z nich cerpat pri zasielani http odpovede? ratam ale ze kvoli malej velkosti takychto suborov sa asi toto vobec neriesi lebo sa proste vzdy nastreamuje cely blob a mime s vezme z koncovky. takze asi len splietam pripady statickych asetov ktore sa s dynmickymi nemusia riesit....



Re:Komprimovat či nekomprimovat data pro HTTP
« Odpověď #13 kdy: 14. 01. 2023, 22:39:22 »
Ne, nezáleží na tom, zda je soubor dynamický nebo statický. Záleží na tom, zda už je komprimovaný nebo není. HTML, CSS, JS komprimované nejsou, ty má smysl komprimovat. Navíc minimálně CSS a JS obvykle jsou statické. HTML také, pokud jde o SPA aplikaci.

Typ souboru, délka a podobně neřešíte, to řeší webový server. Vy se o to nestaráte, vy serveru jenom řeknete, jak má ze jména souboru odvodit komprimované jméno souboru. Takže na server nahrajete třeba index.html.gz a serveru řeknete, že když prohlížeč požaduje index.html a podporuje deflate kompresi, má zkusit připojit příponu .gz a pokud takový soubor najde, má počítat s tím, že už je zkomprimovaný pomocí deflate. Když prohlížeč tento typ transportní komprese nepodporuje, server zkomprimovaný soubor na pozadí dekomprimuje a pošle prohlížeči (proto na serveru vůbec nemusí být uložená nekomprimovaná varianta – dekomprese je rychlá, takže když server náhodou potřebuje nekomprimovaný soubor, vyrobí si ho). Případně jeden soubor může být uložen ve více zkomprimovaných variantách, server pak hledá příslušný soubor podle toho, která komprese je nejlepší.

Takže Content-Type se bere podle přípony, stejně jako u nekomprimovaných souborů. Content size se neposílá, posílá se Content-Length a to je délka přenášených dat (tedy komprimovaných), ne souboru. Range reuesty nejsou pro tyto typy souborů potřeba, HTML, CSS, SVG i JS se vždy stahují celé.