Optimalizujeme pro rychlost: Obrázky

Posted 12. 10. 2014 / By Petr Soukup / Vývoj

Při tvorbě eshopů klademe velký důraz na rychlost načítání. Je to poměrně komplikovaná problematika a zhruba čtvrtinu času u vývoje strávíme právě na tom. Rychlost má totiž spoustu důsledků - vyšší konverze, lepší pozice v Google, vyšší skóre kvality u PPC atd. Spousta věcí, které takto řešíme je dále přenositelná, takže bych se o ně chtěl podělit. Dnes začneme zlehka - s obrázky.

Obrázky jsou žrouti

Pro eshopy je typické, že obrázků obsahují spoustu. Například ve výpisu kategorie je 30 produktů a to bude znamenat 30 obrázků. Nejde je nijak spojovat a cache nás taky nezachrání, protože při procházení katalogu zákazník vidí různé produkty a ke každému se musí obrázky stáhnout. Rozložení stahovaných dat pak vypadá nějak takto: 2014-10-12 16_50_51-WebPagetest Test Result - Dublin _ www.jadi.cz_Panska-obuv_ - 10_12_14 16_47_52

Zmenšeniny

Obrázky samozřejmě chceme (obvykle) návštěvníkovi servírovat v takové velikosti, jak se budou zobrazovat, takže je nejprve budeme chtít zmenšit. Třeba v Nette je asi nejpřímočařejší postup tento:

use Nette\Utils\Image;
Image::fromFile('big.jpg')
    ->resize(50, 30)
    ->save('small.jpg', 90, Image::JPEG);

Jenže s tím je spojena zrada. Zmenšení proběhne přes GD knihovnu, která není zrovna rychlá, kvalita není zázračná a o nic lepší to není s velikostí. Proto jsme ji zavrhli a místo ní používáme ImageMagick a s ním spojené utility.

Zmenšování je úspornější, protože do něj není potřeba zatahovat PHP. ImageMagick je navíc lépe optimalizovaný než GD knihovny, takže vytváří kvalitnější obrázky při menší datové velikosti. Oproti GD navíc můžeme správně nastavit i ořezávání hlaviček JPG atd. Výsledkem jsou zhruba o 5-8% menší soubory než při použití GD.

Lepší formát - WebP

Daleko lepších výsledků ale dosáhneme, když JPG úplně vyměníme za jiný formát - WebP. Je to formát od Google, kterému při stejné kvalitě stačí o zhruba 35% menší soubor. Není to přitom nijak nadsazené číslo - záleží samozřejmě na konkrétní fotce (počet barev, jednobarevné plochy, ...), ale u produktových fotek sledujeme až o 60% menší soubory.

Pro představu srovnání velikosti zmenšení fotky na 184x280px:

jpgwebp

Úspora je to značná, ale je s ní spojena komplikace. WebP aktuálně podporuje jen Chrome, Android a Opera. Sice to znamená 49% trhu, ale není možné vybrat si WebP jako hlavní formát. Naštěstí je to snadno řešitelné.

Pokud prohlížeč podporuje WebP, tak to tom sám dá vědět v HTTP hlavičce "Accept". Stačí nám tak hlídat tuto hlavičku, a pokud obsahuje "image/webp", tak návštěvníkovi můžeme servírovat obrázky s koncovkou webp místo jpg. Alternativní možností pak je mít obrázky bez koncovek a podle hlavičky se rozhodnout, jaký obrázek vrátit.

Zrady kolem WebP

Pokud servírujeme různý obsah podle hlaviček, je potřeba o tom dát prohlížeči vědět pomocí hlavičky "'Vary: Accept". Jinak by se mohlo stát, že zákazník s Chrome vytvoří cache na proxy serveru a ta se pak použije pro zákazníka s Firefoxem. Stejným způsobem je potřeba ošetřit i vlastní cache uvnitř systému. Pokud se kus vygenerovaného HTML uloží do cache a obsahuje odkazy na WebP obrázky, musí se ukládat extra cache pro každý formát.

Používat obrázky ve dvou formátech znamená více diskového prostoru. Protože jsou ale menší, tak to je jen asi o 30% víc. V našem případě jsme ale třeba zjistili, že v AWS S3 je prostor tak levný ($24/TB/měsíc), že naopak ještě ušetříme na menším trafficu.

Uspořeno

Výsledkem optimalizace JPG a přidání dalšího formátu je o cca 30% nižší traffic, což znamená o 30% rychlejší načítání. Nebylo přitom potřeba dělat žádný kompromis, ani nikomu přidávat práci navíc.

Kromě optimalizace velikosti obrázku je samozřejmě potřeba řešit u něj i další faktory - servírování podle geolokace (CDN), režie kolem obrázku (cookies, ...) nebo protlačení více obrázků v jednom spojení. To si ale nechám zase na příště :)

 

Další díly:

  1. Jak se loví milisekundy (nejen v #nettefw)
  2. Optimalizujeme pro rychlost: Obrázky
  3. Optimalizujeme pro rychlost: HTTPS
  4. Efektivní minifikace Javascriptu
  5. Optimalizujeme: critical+asynchronní CSS


O blogu
Blog o provozování eshopů a technologickém zázemí.
Aktuálně řeším hlavně cloud, bezpečnost a optimalizaci rychlosti.

Rozjíždím službu pro propojení eshopů s dodavateli.