Mistrovská optimalizace obrázků nejen pro WordPress

Tentokrát bych se chtěl věnovat optimalizaci obrázků, jelikož je to poměrně opomíjené téma, které si zaslouží důkladný rozbor. Obrázky tvoří snad největší datový obsah webů a je třeba k nim podle toho přistupovat. Rád bych zde nejprve vyzdvihl pár zajímavých témat, kterým se bude článek věnovat, a jelikož jsme v době „hashtagové“, tak je rovnou použiji:

#wordpress #obrázky #komprese #formáty #webp #jpg #pluginy #cdn #cloudinary #optimalizace #workflow

Před pár dny jsem na fejsbůkové skupině WordPress vývojáři rozjel debatu ohledně komprese obrázků. Sám se optimalizací zabývám hodně a zajímal mě názor ostatních. Potřeboval jsem zjistit, zda mnou používaný plugin TinyPNG dosahuje opravdu nejlepší komprese, případně zda je nějaký lepší postup pro optimalizaci.

Po několika komentářích se rozjela debata o používání CDN služeb, které dokáží s optimalizací hodně pomoci. Já toho nebyl moc velkým zastáncem (pokud nešlo o web s globálním využitím), ale slibované výsledky byly dost povzbudivé. Rozhodl jsem se to tedy pořádně prozkoumat. Začněme ale nejdříve tím, jak jsem to dělal doposud.

Ještě jedna poznámka na začátek: Tento článek je spíše pro vývojáře, kteří staví vlastní šablony na WordPressu. Pokud weby vytváříte na koupených šablonách, nebo jen web spravujete, doporučuji vám přeskočit na část Testování komprese s Elementorem.

Obsah článku:


Předešlé workflow

Při vývoji každého webu jsem vždy začal vytvářet nové velikosti pro obrázky nahrávané do médií ve WordPressu. K tomu vám pomůže funkce add_image_size() a pro úpravu stávajících velikostí update_option(). Sice tím navýšíte čas, který bude potřeba na zpracování jednotlivých velikostí na serveru (při uploadu), ale pomůže vám to maximálně optimalizovat web, protože si můžete nastavit velikosti pro různé layouty a zařízení (velikosti pro mobilní zařízení apod.). Stejně tak vám to zabere na serveru více místa, ale pro optimalizovaný web je to holt potřeba. Tímto mi vždy vzniklo přibližně asi 10 různých velikostí (souborů) od jednoho obrázku a mohl jsem je načítat tam, kde bylo potřeba. Je zde ale nutno poznamenat, že s velikostmi se musí šetřit, protože nejen, že to zpomalí práci s obrázky v administraci, ale také to bude mít vliv na pluginy, které zpracovávají kompresi – vysvětlím v následujícím odstavci.

Vždy po skončení vývoje a naplnění webu obsahem jsem pouštěl kompresi na obrázky pomocí pluginu TinyPNG. V podstatě snad každý plugin na kompresi je limitovaný počtem kompresí, nebo celkovou velikostí zpracovaných obrázků. Zde právě záleží, kolik velikostí si definujete. Například TinyPNG nabízí 500 zpracování za měsíc (nehledě na velikosti souborů). V případě 10 velikostí na jeden obrázek by to bylo přibližně 50 různých obrázků. Proč přibližně?

  1. Ne všechny obrázky musí být zpracované ve všech velikostech (když nahraji obrázek 1000px široký, tak už se nebude zpracovávat ve velikost 1920px)
  2. Záleží, zda necháváte povolenou velikost medium_large. Já osobně ji zakazuji, protože mi moc nedává smysl.
  3. Můžete si vybrat, zda kompresi použijete i na originální obrázek. Pokud ne, nebude se vám počítat do limitu, ale zase tím necháte poměrně veliký soubor na serveru.

Tento způsob mi fungoval na většině prezentačních webů, které jsem dělal doposud. Pokud mi nestačil limit, používal jsem plugin ShortPixel, u kterého mám předplacený tarif. U něj sice máte na výběr z více kompresí Lossy, Lossless a Glossy, jenže u úrovně Lossy je pokles kvality opravdu znát a Lossless už je větší než z pluginu TinyPNG. Testoval jsem vícero těchto pluginů a například Imagify měl v některých případech ještě lepší výsledky než TinyPNG. V článku se dále dozvíte, že lze získat ještě lepší výsledky. Mimochodem Free plán u Imagify není moc velkorysý – 25MB za měsíc a 2MB limit na jeden obrázek.

Rád bych ještě podotknul, že výše zmíněné pluginy (kromě TinyPNG) nabízejí možnost vytvoření formátu WebP, kterému jsem se nějakou dobu vyhýbal, jelikož nemá podporu v prohlížeči Safari. Dále také proto, že když obrázek stáhnete, nelze s ním pak v aplikacích na desktopu pracovat. Popravdě ani jeden argument není moc silný, spíše bych řekl, že šlo o mou lenost s integrací WebP formátu do mého workflow. Proto bych mu rád věnoval následující část.

WebP a jeho integrace do WordPressu

Vzhledem k tomu, že se při uploadu médií do WordPressu WebP nevytváří, je potřeba ho buďto vytvořit ručně (zbytečně náročné), anebo nejjednodušeji pomocí pluginu. Komprese u tohoto formátu je opravdu dobrá, ale mějte na paměti, že ne vždy musí být výsledný soubor menší, než u komprese jpg. Jsou výjimečné situace, kdy v závislosti na různé škále barev a velikosti rozlišení vyjde formát jpg menší než WebP. Z toho plyne, že u pluginů nabízejících převod do formátu WebP to nemusí být vždy 100% lepší volba.

Oba dva výše zmíněné pluginy nabízí 2 možnosti, jak formát poskytovat:

  1. Odstraní <img> element a nahradí jej svým zápisem. Tato možnost mi moc nevyhovuje, neboť ruší vlastní zápis obrázků, kterým si lze hlídat různá rozlišení, jemnost displeje atd.
  2. Přidá zápis do .htaccess, který mění formáty po načtení stránky, což je dle mého názoru lepší volba. Samozřejmě to se děje pouze v případě, že web běží na Apache serveru.

Je tu tedy pár nevýhod, které mohou někoho od formátu WebP odradit a jak jsem psal výše, tak z mého testování pluginy neřešily, zda je výsledný soubor větší než jpg a ponechaly pouze WebP. Tím se ale dostáváme k CDN službě Cloudinary, která tohle umí. Pošle vám formát, který je menší. Stejně jako u pluginů řeší podporu v prohlížečích. Získáte pouze URL, takže zápis v .htaccess nebude potřeba a <img> element si můžete zapsat dle svého. Tím se konečně dostávám k CDN službám.

CDN služby

Jak už jsem psal, nebyl jsem velkým zastáncem CDN. Proto jsem nejprve poslal testovací obrázek Borkovi, který mi doporučoval službu Cloudinary. Ten jej provedl kompresí a následně jsme ho porovnávali s obrázkem, který jsem provedl kompresí přes TinyPNG já. Výsledný soubor byl menší a při testování odezvy serveru byla cloudová služba asi o 20ms rychlejší. Díky tomuto výsledku jsem se rozhodl udělat podrobnější testování a zařadit do něj také plugin Optimole, který pracuje dost podobně jako služba Cloudinary (ale využívá svou vlastní CDN síť). Optimole je WP plugin s různou škálou nastavení, zatímco Cloudinary je on-line služba, která plugin do WP sice má, ale není moc přívětivý. O tom ale později, nyní pojďme na testování.

Podrobné testování

Vytvořil jsem celkem 4 duplikáty webu a na každém jsem přidal stránku s jedním obrázkem v rozlišení 1920x1200px, 2 obrázky v rozlišení 765x478px a 3 obrázky v rozlišení 500x312px. Pro potřeby testování mi Vláďa Smitka poskytl svůj vyladěný server, kde jsme nastavili všechny sub-domény s HTTPSHTTP/2. Všechny instance WP běžely bez dalších/jiných pluginů. Do testu jsem zařadil i standardní kompresi WordPressu, která je nyní nastavena na 82 viz. proposal.

WebPageTest

First View (ms)Repeat View (ms)URL
WordPress400358link
TinyPNG374356link
Optimole473939link
Cloudinary355348link

Yellow Lab Tools

ScorePage Size (kB)URL
WordPress93803link
TinyPNG95550link
Optimole95649link
Cloudinary95503link

GTmetrix

ScoreLoad Time (s)Page Size (kB)URL
WordPress89 1,1840link
TinyPNG961566link
Optimole961,1498link
Cloudinary961484link

Google PageSpeed Insights

Desktop ScoreMobile Score
WordPress9997
TinyPNG9998
Optimole9998
Cloudinary10098

Blackfire.io

PHP Time (ms)URL
WordPress145link
TinyPNG136link
Optimole195link
Cloudinary131link

Pingdom Tools

ScoreLoad Time (s)Page Size (kB)URL
WordPress85338529link
TinyPNG85342464link
Optimole85332336link
Cloudinary85289303link

WebPageTest (CZ) proběhl celkově devětkrát pro každou sub-doménu a výsledky zprůměroval. Testy GTmetrix (UK) a Pingdom Tools (DE) jsem provedl alespoň šestkrát a následně je také zprůměroval. Proto se hodnota v odkazu může mírně lišit.

Na výsledcích si můžete všimnout, že Optimole nevychází vždy nejlépe. Popravdě jsem jeho chování moc nepochopil. V jeho nastavení máte možnost, že vám přepíše všechny URL, což je to, co potřebujeme. Jako další možnost má, že vám bude obrázky poskytovat pro určitá rozlišení/zařízení. Tuto volbu jsem zakázal, jelikož si to chci řídit vlastním kódem (stejně tak lazy-loading). Výsledek v Dev Tools vypadal slibně – všechny adresy se opravdu jevily, že mají správné rozměry. I samotné URL adresy se zdály být v pořádku „…/w:1920/h:1200/q:70/…„, jenže reálný obrázek měl rozměry 1600x1200px. V podstatě ignoruje mnou nastavené velikosti a dosazuje si tam vlastní. Stejně tak při testování pomocí nástroje Blackfire.io je vidět, že plugin na pozadí zpracovává data a ubírá trochu na výkonu. Při použití u kupovaných šablon (nebo page builderů) by to nemusel být problém, ale při vývoji vlastní šablony to není moc použitelné. Na konci článku jsem také provedl testování kompresních pluginů se šablonou třetí strany, a to v části Testování komprese s Elementorem.

Z těchto výsledků mi Cloudinary vyšel nejlépe. Pustil jsem se tedy do bližšího testování.

Cloudinary

Jak už jsem psal výše, Cloudinary je on-line platforma pro zpracování obrázků a videí. Jejich zpracování se zaměřuje na co možná nejlepší kompresi, různé transformace, efekty, přidání vodoznaku a další. Díky využití CDN dokáží nahraný obsah dodat po celém světě co možná nejrychleji. Mezi jejich klienty patří například CNN, Sony, ShutterStock a jiné.

Testování komprese

Nejprve jsem začal testovat takovou úroveň komprese, aby nebyla na oko poznat. Vzal jsem si tedy obrázek, na který jsem použil kompresi z TinyPNG (u kterého je většinou výsledná kvalita skoro nerozpoznatelná od zdroje), a pak obrázek z Cloudinary, u kterého je velká škála možností nastavení. Nejlépe mi vyšla hodnota komprese na 55. Výsledný soubor byl o 51% menší (v jpg formátu), než po standardní kompresi z WP a o 22% menší než po kompresi z TinyPNG. Mezi obrázky v podstatě nebyl poznat rozdíl. S nastavením komprese pomocí číselné hodnoty vám ale Cloudinary poskytne formát WebP, který byl v tomto případě o něco větší než jpg.

Po důkladnějším prostudování dokumentace Cloudinary jsem zjistil, že dokáží poskytnout takový soubor, který je datově menší, ale je potřeba nastavit hodnotu komprese na auto. Auto má celkem 4 možnosti (best, good, eco, low). Jelikož jsem chtěl co nejmenší soubor, tak jsem zkoušel auto:low, ale bohužel výsledná kvalita nebyla dobrá. Vybral jsem tedy možnost auto:eco, u které jsem dostal výsledný soubor o 45% menší než z WP a o 12% menší než z TinyPNG. Hlavně ale Cloudinary pozná, jestli je WebP větší než jpg a podle toho daný formát poskytne.

WordPress a komprese obrázků
Tento jeden testovaný obrázek měl rozlišení 1920x1200px a jeho původní velikost byla 2,5MB. Auto:eco komprese zmenšila jeho velikost na 293kB.

Mezi soubory na obrázku si také můžete všimnout výsledků z pluginů Kraken, Optimole, ShortPixel, Smush a TinyPNG. Navíc je zde také placeholder, který využívám při lazy-loadingu.

Pár poznámek k jednotlivým pluginům:

  • Kraken – tento plugin má velice slušné výsledky. I při ztrátové kompresi dokáže z obrázku dostat, pouhým okem, nerozpoznatelné maximum. Bohužel Free plán nabízí jen 100MB limit bez měsíčního obnovení.
  • Optimole – výsledek z Optimole byl sice nejmenší, ale není bohužel správný, protože reálná velikost obrázku je 1600x1200px. Nepovedlo se mi dostat obrázek v požadované velikosti, takže jsem jej nemohl důkladně otestovat.
  • ShortPixel – úroveň komprese Lossy je bohužel znatelně ztrátová. Zkoušel jsem také jejich CDN verzi ShortPixel Adaptive Images, ale bohužel ta nefunguje s mou lazy-load knihovnou. Řešil jsem to přímo s vývojáři pluginu, ale zprovoznění by stálo dost práce z mé strany.
  • Smush – úroveň Lossy je pouze v placené verzi a jeho výsledek vyšel stejně jako z předešlého pluginu.
  • TinyPNG – k němu asi není co dodat. Pro mě je to stále king mezi jednoduchými pluginy pro kompresi obrázků.

Poznámka: Chtěl jsem vyzkoušet také Imagify a EWWW. Imagify má obecně dobré výsledky, ale bohužel je omezen velikostí 2MB na soubor a nemohl jsem jej adekvátně otestovat. EWWW datově omezený sice není, ale pro bezplatnou kompresi musíte mít na serveru povolenou funkci exec(), která je z bezpečnostních důvodů na většině hostingů zakázána.

Zbývá poslední otázka – jak nejlépe propojit Cloudinary s webem postaveným na WordPressu?

Pluginy do WordPressu

Hledal jsem pluginy, které by s Cloudinary pracovaly a jako první jsem našel jejich vlastní. Nabízí stejné možnosti, jaké umí Cloudinary (myšleno administrací ve službě), ale vše se děje ve WP prostředí. To mi ale bohužel přijde nešikovné. Celou práci v administraci to může znesnadnit a co je důležitější, nenašel jsem možnost propojení s custom fields. V něm najdete pouze práci s obrázky v TinyMCE WYSIWYGu, což je v dnešní době Gutenbergu poněkud nepraktické. Možná se plugin postupně vylepšuje, ale v době psaní článku měl hodnocení 3,5 hvězdyposlední aktualizace proběhla před 5 měsíci, což mluví samo o sobě.

Našel jsem ale druhý plugin Auto Cloudinary, který měl nejen dobré hodnocení a dobře popsanou dokumentaci, ale jeho použití bylo přesně to, co jsem hledal. Pomocí návodu se jednoduše propojíte s Cloudinary a pak pomocí funkce cloudinary_url() načtete obrázek ze CDN (stačí pouze ID obrázku a atributy jako šířka, výška apod.). Další přidanou hodnotou je to, že nemusíte řešit žádné velikosti ve WP, jelikož ty za vás zpracuje Cloudinary. Tím ušetříte jak čas pro zpracování obrázků na serveru, tak i místo.

Aktualizace (1/4/2020): Včera konečně vyšla nová verze pluginu od Cloudinary. Neměl jsem ještě čas na řádné testování, ale už před nějakou dobou jsem plugin testoval a měl jsem k tomu i pár postřehů. Pro vývojáře se sice nic nemění, ale pro uživatele by to mělo znamenat velké zjednodušení. Nemuseli by přidávat další plugin, nebo zasahovat do kódu. Plnému testování se budu věnovat snad v létě.

Díky těmto poznatkům jsem začal vymýšlet, jak nejlépe budu přistupovat k obrázkům pro následující vývoj.

Nové workflow

Pokud víme, že nepotřebujeme velikosti, tak je nejprve zakážeme:

Jak si můžete všimnout, tak standardní velikosti WP nastavuji na 0, což je nejjednodušší způsob, jak zakázat vytváření dalších souborů obrázku. Dále ruším velikost medium_large a nakonec nastavuji úroveň WP komprese na 100, jelikož to za nás bude dělat Cloudinary.

V praxi to znamená, že do médií na webu nahrajete obrázek v největším rozlišení a ten se zpracuje jako jediný soubor na serveru. Tím ušetříte (jak už jsem psal výše) dost zpracovaných dat na serveru.

Aktualizace (15/9/2019): Výsledný kód pro odstranění velikostí obrázků jsem nakonec změnil a ponechal náhledy (thumbnails) . Při odstranění náhledů se vám může stát, že při prohlížení obrázků v administraci, budete na každý obrázek čekat, než se načte do mezipaměti prohlížeče. WordPress by tak neměl jinou velikost než originální, a tak byste mohli poměrně dlouho čekat, než všechny načte. Proto jsem nastavil náhledový obrázek s rozměry 192x192px, který lze použít napříč celou administrací . Pro tento případ jsem ponechal WP kompresi, jelikož u těchto řezů nepotřebuji maximální kvalitu. Tak či tak, i tento způsob vám šetří dost dat na serveru.

Abych pro začátek plugin Auto Cloudinary vyzkoušel, využil jsem pouze funkci cloudinary_url() a použil ve svém zápisu obrázku. Zápis pro obrázek ve Full HD rozlišení by mohl vypadat například takto:

Funkce get_post_thumbnail_id() je asi všem známá – vrací ID náhledového obrázku aktuálního příspěvku. Jako další funkci vidíte get_post_meta(), která v našem případě vrací alternativní text obrázku. Nakonec je zde funkce cloudinary_url(), která nám vrací URL z Cloudinary dle námi zadaných parametrů. Asi si teď sami říkáte, že takový zápis kvůli jednomu obrázku je prostě hardcore, ale nezoufejte, řešení je na cestě.

Autor pluginu Auto Cloudinary doporučuje jako své „Best Practices“ nejprve zjistit, zda plugin existuje. Pokud ne, použít další jeho plugin Fly Dynamic Image Resizer, který pracuje s obrázky na serveru, ale dodává/vytváří pouze ty velikosti, které si definujete. Tudíž stále nebudete potřebovat velikosti obrázků ve WP, ale budete potřebovat navíc plugin na kompresi. Podle mého názoru je to slušná alternativa za Cloudinary. Na druhou stranu pokud jste jako já a neradi necháváte na webu nevyužité pluginy, tak je otázka, co potom.

Jeden ze způsobu řešení vypadá následovně:

Zde jsem vytvořil jednoduchou funkci s několika argumenty, ve které zjišťuji, zda existuje plugin Auto Cloudinary. Pokud ne, zjistím, zda existuje plugin Fly Dynamic Image Resizer, a pokud ani ten neexistuje, načtu pouze URL obrázku z webu.

U psaní funkce jsem se nechal inspirovat autorem pluginu, který nastínil svou představu v dokumentaci. Já jsem funkci přepsal a doplnil 2 důležité věci:

  1. Přidal jsem do funkce argumenty, které se využívají při zápisu src atributů u <img> elementu a doplnil k nim statické hodnoty, které se většinou měnit nebudou (jako například úroveň komprese nebo ořez obrázku).
  2. Přidal jsem podmínku, která vrací URL obrázku v případě, že ani jeden z pluginů není aktivovaný.

Díky této funkci se zápis jednoho obrázku dost zjednoduší:

Pomocí funkce my_image() jsme se zbavili vytváření jednotlivých zápisů s cloudinary_url(). Takto si stačí definovat šířkuvýšku přímo do funkce k požadovaným velikostem obrázku. V případě, že byste potřebovali jinou úroveň komprese aj., stačí je tam dopsat. Tento případ můžete vidět u obrázku, který používám jako placeholder na lazy-loading. Stačí jen dodržet posloupnost argumentů, tedy my_image( id_obrázku, šířka, výška, ořez, úroveň_komprese, efekt ). Výška, ořez, úroveň kompreseefekt nejsou povinné. Efekt obrázku se propíše pouze v případě, že bude přidán do funkce. Navíc můžete tuto funkci použít i bez Cloudinary, při instalaci pluginu Fly Dynamic Image Resizer, ale pouze s parametry šířky a výšky.

V případě používání custom fields doporučuji načíst všechna data postu jedním databázovým požadavkem – získáte ID zadaných obrázků. Pak stačí opět využít funkci my_image(), která udělá zbytek.

Poslední myšlenka k používání Cloudinary

Možná si někdo z vás řekl – co když tato služba zruší svůj Free plán, nebo co když přestane z ničeho nic fungovat? Přesně z těchto důvodů jsem napsal funkci, která by tyto případy měla řešit za vás. Pokud se vám služba přestane zamlouvat, anebo už nyní víte, že není pro vás, můžete plugin Auto Cloudinary vyměnit za Fly Dynamic Image Resizer a přidat ještě jeden plugin pro kompresi.

V případě výpadku CDN, nebo výše zmíněného pluginu má funkce my_image() záchranný bod a tím je načtení obrázku ze zdrojového souboru. Pamatujte ale na to, že pro záchranný bod musíte pluginy deaktivovat. Obrázek načtený ze zdrojového souboru není pro rychlost webu žádoucí, ale aspoň vám obrázky nezmizí úplně a dá vám to čas na řešení potíží.

Pokud sami máte jiné/lepší workflow, budu rád, když se o tom podělíte s ostatními v komentářích.

Dodatek (12/1/2020): Obrázky v Gutenbergu

;Nový editor Gutenberg je zde s námi už delší dobu a oproti TinyMCE přinesl nový přístup k vytváření obsahu. Někdo už podobný přístup zná z různých page builderů typu Divi, Elementor, Visual Composer apod., ale přece jen Gutenberg je součástí WP jádra, a to je z pohledu udržitelnosti a správy nejlepší možný formát pro vývoj webu. Na Gutenberg jsou různé názory. Můj pohled je takový, že ve svých posledních verzích se mi Gutenberg začíná opravdu líbit. Tento článek se ale zaměřuje na obrázky, a těm se budeme věnovat i nyní.

Hlavní nevýhodu Gutenbergu jsem viděl především v tom, že nebylo možné jednoduše změnit výstup na Front-Endu. Bloky Gutenbergu jsou totiž napsané v Reactu a já se v pokročilejším JavaScriptu bohužel nevyznám. To by mohly vyřešit různé pluginy, například ACF, ve kterém si můžete naklikat vlastní blok sami, s tím rozdílem, že vzhledově nebude vypadat jako ostatní. Navíc si tím přidáte další dotazy do databáze, protože obrázky se uloží jako custom field. Asi nejzajímavější plugin, na který jsem v tomto ohledu narazil, je Lazy Blocks. Já se ale snažím pluginům vyhýbat, takže co teď?

Proto jsem hledal dál a narazil na filtr render_block, který umožňuje odchytit jakýkoliv zaregistrovaný blok a s tím si následně můžeme dělat, co uznáme za vhodné. V našem případě si odchytíme blok core/image a po vypsání $block_content (popsáno v dokumentaci filtru) zjistíme, že jsme získali kompletní HTML samotného bloku, což se nám ale moc nehodí. Naštěstí existuje velice šikovná PHP knihovna Simple HTML DOM Parser, která nám pomůže rozklíčovat získaný HTML zápis a díky tomu si můžeme vytvořit vlastní.

Možná při hledání narazíte i na funkce render_block()parse_blocks(). To jsou poměrně šikovné funkce, ale bohužel nevypisují dostatek atributů. Například u obrázku tak nezískáte alternativní popisek apod. Proto jsem zůstal u výše popsaného filtru. Pojďme si tedy nyní ukázat, jak takový zápis může vypadat:

Nejdříve je potřeba načíst parsovací knihovnu. Poté použít filtr a specifikovat, jaký blok chcete získat. Následně použít funkci knihovny str_get_html() (viz. dokumentace), která nám rozklíčuje získané HTML. Pak už jen stačí zadat, které elementy hledáte a uložit si je do proměnných a nakonec vypíšete jednotlivé atributy zachycených elementů. Není to zas tak složité, jak se zdá. Především PHP knihovna má skvěle popsanou dokumentaci i s příklady. Svůj zápis si samozřejmě můžete jakkoliv změnit. Zde jsem pouze pro příklad nechal samotný <img> element a nepřidával jsem žádné elementy a atributy navíc.

Rozhodně neříkám, že toto řešení je ideální. Pokud ale potřebujete změnit výstup několika bloků a na webu se nepředpokládá enormní množství dat, tak je tento způsob dostačující. V ideálním případě bych vám samozřejmě doporučil si napsat blok vlastní.

Testování komprese s Elementorem

Ať už použijete Elementor s jeho čistou šablonou Hello (jako v mém případě), anebo jinou šablonu/builder třetí strany, nepředpokládá se, že budete zasahovat do kódu. V takovém případě je potřeba se zaměřit na pluginy, které vám provedou nejen kompresi obrázků, ale celistvou optimalizaci jako například lazy-loading, nebo převod formátů.

Z mého předešlého testování jsem pro tyto účely zvolil 4 pluginy – Auto Cloudinary, Optimole, ShortPixel Adaptive ImagesTinyPNG. Auto Cloudinary a TinyPNG sice lazy-loading neumí, ale k nim můžeme ještě přidat plugin Lazy Load, který se o to postará. Rád bych ještě zmínil, že TinyPNG sice převody formátů (například do WebP) neumí, ale v jeho případě je komprese natolik silná, že bych to zde ani moc neřešil, pokud nejste „optimalizační šílenci“ jako já.

Vzhledem k tomu, že většina online nástrojů na testování rychlosti webu nepracují s vyšším rozlišením než 1000px na šířku, musel jsem zvolit trochu jiné metody. V případě nástroje WebPageTest jsem si u Vládi Smitky nechal upravit jeho privátní instanci pro rozlišení 1920x1200px (testování jsem nechal proběhnout na všech instalacích devětkrát a výsledky zprůměroval). Dále jsem měřil pomocí DevTools v prohlížeči Chrome, protože tam mám rozlišení v podstatě neomezené. Tyto testy jsem pro každý typ instalace provedl šestkrát a výsledné hodnoty také zprůměroval. Pro dokreslení výsledků jsem ještě zařadil Google PageSpeed Insights.

A proč jsem si testování takto ztížil? Chtěl jsem demonstrovat co možná nejlepší rozdíly ve výsledcích. Elementor si při vykreslení obrázků načítá vlastní velikosti, kde do 1600px na šířku obrazovky přidává jiné velikosti než originální, kterou jsem chtěl testovat. Důvodem bylo přidání obrázku s šířkou 5000px, aby bylo jasné, jak moc komprese ovlivní celkovou velikost webu.

Vytvořil jsem tedy 4 duplikáty webu s HTTPS a HTTP/2 na wp-hosting.cz. Na každé instalaci jsem měl plugin Elementor a Elementor Pro, kde v testované stránce bylo 12 obrázků. Dva s šířkou 5000px a zbytek s šířkou 500px. Mezi obrázky jsem ještě doplnil textové odstavce, abych si byl jistý postupným načítáním (lazy-loading). U pluginů označených hvězdičkou jsem ještě přidal plugin Lazy Load, což je plnohodnotné nastavení oproti dalším dvěma pluginům, které mají už tuto funkci implementovanou. Mimo jiné zde naleznete pro porovnání i výsledek základní komprimace WordPressu. Testy proběhly bez jakéhokoliv cachovacího pluginu.

WebPageTest – Private Instance

First View (ms)Repeat View (ms)
WordPress22351080
TinyPNG15781122
TinyPNG *11461016
Optimole12101103
ShortPixel AI15401056
Auto Cloudinary15071041
Auto Cloudinary *11161041

DevTools – Desktop – Online

Finish (ms)Transferred (MB)
WordPress17855,2
TinyPNG18202,1
TinyPNG *16201,1
Optimole15950,53
ShortPixel AI18401,9
Auto Cloudinary16502,3
Auto Cloudinary *16101,2

Google PageSpeed Insights

Desktop ScoreMobile Score
WordPress9075
TinyPNG9376
TinyPNG *9382
Optimole9485
ShortPixel AI8974
Auto Cloudinary9581
Auto Cloudinary *9582

DevTools – Mobile – Fast 3G

Finish (s)Transferred (kB)
WordPress8,2801
TinyPNG8,2783
TinyPNG *6,5413
Optimole7,3432
ShortPixel AI6,7437
Auto Cloudinary6,4605
Auto Cloudinary *6,4374

Jak si můžete všimnout, tak při základní komprimaci WP se přeneslo 5,2MB, což je obrovské množství dat. Na mobilech to bylo sice „jen“ 801kB, ale pokud byste používali šablonu/builder, který nepoužívá rozdílné velikosti obrázků pro různé šířky obrazovky, byl by to opravdu problém. Věřím ale, že většina moderních šablon/builderů to řeší. I v Gutenbergu je do obrázků zavedený atribut srcset.

Poznámky k výsledkům:

  • ShortPixel AI zde dopadl v podstatě nejhůře. Nerad bych ale navozoval dojem, že je to špatný plugin. I tak jsou jeho výsledky velmi dobré a vzhledem k tomu, že je to komplexní plugin bez zbytečně složité administrace, tak bych ho nezatracoval.
  • Optimole je pro mě stále trochu záhada. Výkonnostně se vyrovnává pluginu TinyPNG. Na desktopu se díky němu přeneslo nejmenší množství dat, ale na mobilech už to nebylo tak dobré. Nastavení má poměrně komplexní, ale narážel jsem na občasné problémy jako třeba ořez obrázků. U obrázků na pozadích s ořezem nevyhodnocuje vždy správné pozicování. Zdá se mi v jistých ohledech nedotažený. A navíc když řeší adaptivní rozpoznání, tak by měl být vlastně nejlepší – jak ale ukazuje praxe, není to vždy výhra.
  • Mile mě překvapilo, že TinyPNG si drží v podstatě druhé místo (s použitím lazy-loadingu). Jeho komprimace je natolik silná, že výsledný výkon webu je i před weby s pluginy, které řeší i převody formátů a adaptivní servírování velikostí (tzn., že poskytuje obrázek v určité velikosti pro určitá zařízení/rozlišení).
  • Testování s Auto Cloudinary opět ukazuje první pozice, jako v mém testování s vlastní šablonou. Tento plugin se zaměřuje spíše na vývojáře, což znamená, že není až tak přívětivý pro uživatele. Při jeho základní instalaci poskytuje obrázky bez komprese a pro její změnu je potřeba menšího zásahu. Pojďme se tedy podívat, co je v tomto případě potřeba.

Cloudinary v Elementoru

Cloudinary je CDN služba, o které si více můžete přečíst v části Cloudinary. Zde bych se rád zaměřil na její implementaci do WordPressu s šablonou/builderem třetí strany. Samozřejmě pro spojení s Cloudinary existuje více pluginů, ale pro nás jsou zajímavé pouze dva, které se aktuálně nacházejí ve WP repositáři. Tyto dva pluginy jsem rozebíral v části Pluginy do WordPressu. Jak už asi víte, dobře použitelný je prozatím pouze jeden, a to Auto Cloudinary. Doufejme že betaverze, kterou Cloudinary nedávno zveřejnil, již brzy spatří světlo WP repositáře.

Po instalaci Auto Cloudinary jej musíte propojit s Vaším účtem na cloudinary.com. Návod můžete najít na stránkách autora pluginu viz. link. Ve stručnosti – založíte si účet, v nastavení pod záložkou Upload si vymyslíte název složky pro požadovaný web a přidáte jeho URL adresu včetně cesty do složky uploads. Přímo v pluginu následně zadáte název vašeho účtu, název vytvořené složky a zaškrtnete položku Content Images.

Při tomto nastavení nám již spojení mezi webem a službou funguje. Generace obrázků probíhá vždy při prvním náhledu, případně při změnách parametrů (například změna komprese atd.). Po prvním vygenerování (může se zdát pomalé, ale jde o první načtení, které je závislé i na velikosti obrázků) se již budou načítat obrázky rychle. Proto doporučuji, abyste stránku vždy po uložení (s nějakými obrázky) v administraci otevřeli ihned veřejně (na Front-Endu), aby se provedlo generování a už jej nebylo zapotřebí. Jenže tímto způsobem se vám obrázky budou načítat v plné velikosti bez komprese, protože plugin nenabízí žádné nastavení parametrů (kromě ořezů). Proto je potřeba přidat zápis do kódu, nebo použít můj jednoduchý plugin.

Pokud nechcete nijak zasahovat do kódu šablony, připravil jsem pro vás to nejjednodušší možné řešení. Vytvořil jsem plugin auto_cloudinary_defaults.zip, který vám nastaví základní hodnoty komprese a formátu na nejlepší možnou variantu. Pokud vás zajímá jak tento plugin pracuje, anebo máte svou vlastní child šablonu, do které si můžete funkci zkopírovat, podívejte se na následující vysvětlení.

Jak jistě víte, při zápisu vlastního kódu v šablonách třetích stran je vždy potřeba vytvořit child šablonu, do které je možné zapsat změny. Přidávat/měnit kód v originální šabloně je velmi neprofesionální. Pokud tedy máte child šablonu vytvořenou, stačí do functions.php přidat tento kód:

V tomto kódu je zprvu podmínka, která zjistí, jestli je Auto Cloudinary na webu aktivní. Pokud není, funkce se nezpracuje a chrání vás před možným chybovým hlášením. Pokud je plugin aktivní, zpracuje se jednoduchá funkce (tzv. filter hook), který v našem případě mění základní parametry pro načítání obrázků ze služby Cloudinary. Já jsem vám zde připravil dva parametry:

  1. quality – nastavuje úroveň komprese, která má nyní hodnotu auto:eco. Podrobně jsem se těmto hodnotám věnoval v části Testování komprese.
  2. fetch_format – díky nastavení na hodnotu auto vám cloudinary, nehledě na formát, pošle vždy datově menší obrázek (ať už je jpg, nebo WebP – formátu WebP jsem se zas věnoval v části WebP a jeho integrace do WordPressu)

Tyto dva zápisy by vám měly bohatě stačit, ale pokud si chcete vyzkoušet další možnosti, v dokumentaci pluginu naleznete podporované parametry.

Sice tento postup není úplně přívětivý, ale získáte tím co možná nejlepší optimalizaci obrázků a navíc mnohem více zpracování, než u pluginu TinyPNG. Ten dokáže zdarma zpracovat 500 velikostí/řezů obrázku za měsíc. Cloudinary mnohem více.

Závěrem

Dozvěděli jste se, že Cloudinary, jakožto CDN služba se zaměřením na optimalizaci médií, poskytuje snad nejlepší dostupnou kompresi a nejlepší způsob poskytování obrázků/videí pomocí různých transformací. Co jste se ale ještě nedozvěděli, je jeho cena, která vás asi příjemně překvapí.

Cloudinary zdarma nabízí 25GB zpracovaných dat za měsíc, což je dost velkorysá nabídka. Pro představu – jeden nejmenovaný portál, který jsem vyvíjel, má denní návštěvnost 1000 lidí. Každý článek na tomto webu obsahuje 1 náhledový obrázek, 1 obrázek v těle článku (někdy žádný, někdy více) a pod článkem jsou zobrazené 3 nejnovější články, tzn. další 3 náhledové obrázky. A to je pouze popis detailu článku, ostatní stránky mohou mít obrázků mnohem více. Při tomto množství a návštěvnosti se měsíční zpracování dat pohybuje kolem 16GB, takže sami jistě uznáte, že nabídka s 25GB dat je velice příznivá. Limit na jeden obrázek je 10MB a na video 100MB.

Na konec bych si ještě dovolil pár poznámek:

Pro uživatele

Pokud se vám Cloudinary zamlouvá a nebojíte se dalšího pluginu nebo malého zásahu do kódu, bude pro vás tato volba opravdu nejlepší. Pokud se vám tato cesta použití nezdá, doporučuji použít plugin TinyPNG, který také dosahuje skvělých výsledků *. Oba tyto pluginy v kombinaci s pluginem Lazy Load představují skvělou optimalizaci pro váš web. Případně, pokud již vlastníte cache plugin WP Rocket (placený), tak nebudete plugin Lazy Load potřebovat, protože ho má v sobě implementovaný. S jeho cachovacími praktikami, lazy-loadingem a optimalizovanými obrázky by měl váš web lítat jako drak.

* Nebo si můžete počkat na již zmíněný nový plugin od Cloudinary, který je nyní v betaverzi.

Pro vývojáře

Pro vás už moc poznámek nemám. Jak už jsem psal, pro mě se stal Cloudinary jasnou volbou a díky mé funkci my_image() ještě získáte záchranné body pro případ, že by se se službou cokoliv stalo. Doufám, že vám článek dal dostatek nových poznatků, nebo vás alespoň ujistil, že máte své workflow co nejlepší. Budu vám vděčný za jakýkoliv feedback.

V závěru bych ještě rád poděkoval Borkovi, který mě přivedl ke službě Cloudinary a také velké díky patří Vláďovi, který mi poskytl skvělý feedback a testovací prostředí.

Pokud byste mě chtěli zastihnout na nějaké akci a promluvit si o optimalizaci osobně, nezapomeňte na naši konferenci
WordCamp Praha 2020 (29. Února).

Líbil se Vám příspěvek a rádi byste podpořili WordPress - hlavně lidi okolo něho?
Sdílejte ho s přáteli.
Případně nám napište komentář.
Článek pro vás připravil: Adam Laita

WordPress Specialista / Front-End Kodér

Adam se specializuje na přívětivou administrační část WP, stejně tak na optimalizaci Front-End části.
Mimo jiné také organizuje WordCampy.

Více na laita.cz

6 komentářů u „Mistrovská optimalizace obrázků nejen pro WordPress“

  1. Zrovna jsem řešil obrázky a jak na ně, pak jsem narazil na tento článek, který mě velmi zaujal. Je neuvěřitelné jak optimalizace obrázků může být snadná a zdarma. Velké dík autoru za sdílení! Je to velký kus práce.
    PS – už mám obrázky optimalizované dle tohoto návodu 🙂

  2. Ahoj,

    Díky za super článok.

    Celý natešený som sa pustil do Cloudinary, všetko som urobil podľa návodu, avšak na webe mi prestali fungovať všetky obrázky 🙁

    Neviete čím to môže byť?

    S pozdravom
    Viliam, Wpromotions.eu

    • Ahoj,
      jsem rád, že se článek líbil. Důvodů může být více a obávám se, že to v komentářích nevyřešíme. Napiš mi na e-mail a zkusíme se na to podívat.

Komentáře nejsou povoleny.