Lazy loading - odložené načítání obrázků

Lazyloading v HTML - Historické pokusy o lazyloading - Javascriptový lazy loading - Opožděné načítání iframe

Od srpna 2019 začal nejrozšířenější prohlížeč Chrome ve verzi 76 podporovat odložené načítání obrázků pomocí jednoduchého atributu loading="lazy".

Říká se tomu anglicky "lazy loading", občas se to píše dohromady jako "lazyloading" a do češtiny by se to snad dalo přeložit jako líné nahrávání.

Zápis v HTML vypadá takhle jednoduše:

<img src="obrazek.jpg" loading="lazy" alt="obrázek načtený dle potřeby">

Důvod, proč řešit odložené načítání obrázků, je zejména zbytečný přenos dat. Obrázky jsou zpravidla datově nejobjemnější objekty na stránkách. Pokud se nikdy neviděné obrázky vůbec nebudou přenášet, může to znamenat velkou úsporu, která se projeví hlavně při pomalejším spojení nebo při připojení účtovaném za přenesená data (FUP na mobilech).

Lazyloading v HTML

Lazy loading zapsaný takto jednoduše v HTML se nazývá nativní lazy loading, protože je podporovaný prohlížečem přirozeně (tedy nativně), aniž by se něco muselo skriptovat nebo nastavovat.

Ještě jednou připomenu kód.

<img src="obrazek.jpg" loading="lazy" alt="popisek">

Atribut loading má i jiné hodnoty než "lazy", ale ty nejsou tak zajímavé:

loading=  
lazy Nestahuj obrázek, stáhni ho jenom, až bude vidět
eager Stáhni obrázek ihned a s co nejvyšší prioritou
auto chovej se jako dřív, tedy jako by žádný loading nebyl zadán

Podpora atributu loading je zatím omezená na Chrome a Operu, což je ale dost dobré, protože se to tím pádem týká asi dvou třetin všech uživatelů. Zbylé třetině se obrázky načtou ihned, ale předpokládám, že se podpora do budoucna zvýší. Blbé je, že (v prosinci 2019) ještě neexistuje oficiální specifikace, takže se Firefox zdráhá to naprogramovat.

Při experimentech jsem zjistil, že nedokážu nijak řídit hranici, která určuje, jak hluboko pod obrazovkou obrázky musejí být, aby se už načítaly nebo ještě nenačítaly. Podle mojí zkušenosti je nyní v prohlížeči Chrome velmi hluboko (asi pět obrazovek dolů), což znamená, že se raději načítá obrázků více, než aby bylo nebezpečí, že uživatel uvidí, jak se obrázky teprve natahují. Podle vyjádření vývojářů se tato hranice bude automaticky posouvat nahoru a dolů podle rychlosti připojení a nastavení prohlížeče.

I tak jsem nastavil loading="lazy" u většiny obrázků na svých webech. (Na tomhle ne, aby to nenarušilo pochopení příkladů.)

Jak testuju lazyloading

Otevřu si v prohlížeči DevTools (F12), přepnu se na kartu Network a načtu stránku s obrázky s loading="lazy". Podívám se, které se stáhly. Pak si stránkou roluju a dívám se doprava, které se dotahují. Typicky je dobré dělat to na nějaké stránce s mnoha obrázky, takže já na to používám nejčastěji svoje různé galerie obrázků rostlin. testování stahování obrázků přes lazy loading a dev tools v prohlížeči Chrome

Historické pokusy o lazyloading

Je pro mě skoro neuvěřitelné, že se jednoduchý a použitelný HTML atribut na lazyloading objevuje až v roce 2019, ačkoli potřeba něčeho podobného tu byla od začátku internetu. Nedalo se to ale snadno řešit, protože prohlížeče jsou odnepaměti slušně vychované tak, že když vidí obrázek, tak ho hned stáhnou. Zpomalit je v tom mohla jenom vnitřní omezení počtu stahovaných objektů z jednoho serveru. Typicky jich prohlížeč stahuje najednou nejvýše šest a sedmý musí počkat, než nějaký dřívější dorazí. Toto omezení stále platí (ale ne pro HTTP 2), ale nijak zvlášť nepomáhá.

Občas se může stát, že někdo roluje rychleji, než se obrázky stíhají stahovat, takže může mít pocit, že se mu obrázky donačítají podle toho, jak roluje. Ale to je jen klam daný tím, že se obrázky načítají v pořadí, v jakém jsou uvedeny v HTML kódu stránky, takže ty nižší dorazí později. Případně může mít uživatel slabý hardware, takže se mu již načtené obrázky nestíhají vykreslovat. Nic z toho není ale lazyloading. Obrázky se vždy stahovaly všechny, jakmile je prohlížeč uviděl v html kódu, bez ohledu na velikost monitoru nebo na chování uživatele. To ale může být hodně zbytečně přenesených dat.

Málo rozšířené prohlížeče Internet Explorer a Edge implementovaly svůj vlastní přístup, atribut lazyload (bez hodnoty nebo s libovolnou hodnotou). Ostatní prohlížeče se nepřidaly. Dnes (2019) nemá smysl tenhle atribut používat, protože nejnovější Edge už ho taky nepodporuje.

Kolem roku 2014 jsem zaznamenal první funkční řešení odloženého načítání v javascriptu a časem se jich objevilo hodně. Typický javascriptový kód při lazyloadingu kontroluje, jak uživatel na stránce scrolluje. Spočítá si také souřadnice obrázků ve stránce a porovnává, jestli už je čas obrázek načíst. Obvykle to jsou velmi chytré javascriptové knihovny, které se časem hodně zlepšily, zejména díky tomu, že jim to prohlížeče usnadnily APíčkem intersection observer, které říká, který objekt je ze stránky zrovna vidět.

Zdaleka nejlepší český článek o lazyloadingu v javascriptu napsal Martin Michálek. Nově do něj na začátek doplnil i informace o nativním lazylodingu, který probírám v tomto textu.

Pro mnoho autorů webu jsou javascriptové knihovny na lazy loading dokonalým řešením. Pro mě ne, vysvětlím proč.

Javascriptový lazy loading

Aby fungoval javascriptový lazyloading, musí se napřed prohlížeči při načtení stránky zabránit, aby obrázky ze serveru načetl. To se ale nedá udělat nijak snadno. Jak jsem zmínil, prohlížeč chce vždy ihned stahovat všechno, co je obrázek, tedy co je tag <img> s atributem src.

<img src="něco.jpg">

Aby se takový obrázek nestahoval, je tedy potřeba tenhle zápis nějak v HTML poničit. Když se neponičí už v HTML, tak se obrázek hned stáhne, což při lazyloadingu nechci. Jsou zhruba dva způsoby ničení HTML obrázků. Buďto se místo img dá něco jiného, nebo se místo src dá něco jiného. Příklad poničení tagu img:

<blabla-img src="něco.jpg">

v praxi nejčastěji

<amp-img src="něco">

Nebo příklad poničení atributu src:

<img blabla-src="něco.jpg">

v praxi nejčastěji

<img data-src="něco.jpg">

Javascriptový lazyloading potom funguje následujícím způsobem:

Proč nepoužívám javascriptový lazyloading

  1. Nemám rád rozbité HTML. Nikdy nevíte, jakým způsobem bude klient stránky číst. Je možné, že bude mít funkční javascript z roku 2019, ale taky je možné, že ho mít nebude. Určitou náplastí je dát za poničený obrázek do HTML kódu stejný neponičený obrázek do <noscript>, což se i doporučuje, ale z mého pohledu to jenom smutně nafukuje kód.
  2. Jistá lapálie z toho vzniká pro indexovací roboty, kteří se snaží indexovat obrázky. Nutno říct, že už si na tyhle zmršené zápisy obrázků musely zvyknout, takže tenhle argument není tak důležitý ale ještě si nezvykli všechny a dobře. Poničené obrázky prostě občas zůstávají neviditelné.
  3. Je celkem obtížné zadávat tyhle poničené konstrukce prostřednictvím dnešních editorů a starších řešení redakčních systémů, které na něj nejsou připravené. (Oproti tomu přidat jeden atribut taková práce není.)
  4. Neznám žádné javascriptové řešení lazyloadingu, které by fungovalo perfektně. Částečně se to lepší tím, jak přicházejí lepší a lepší prohlížeče. Stále ale zůstává nutnost načítat do stránky javascriptové knihovny a řešit jejich aktualizace.
  5. Hlavně to už ale javascriptem dělat nemusím, jde to přes loading="lazy" přímo v HTML. Což je i hlavní poselství téhle stránky.

Pokud přesto všechno chcete javascriptový lazyload použít, určitě po webu najdete tisíce různých řešení. Třeba budete mít štěstí a bude vám to fungovat dobře. Pravděpodobnější ale je, že to bude chybovat, ale nebudete o chybách vědět. Pokud si mohu dovolit doporučení, tak se prosím zaměřte na řešení využívající Intersection Observer, ta bývají nejlepší.

Opožděné načítání iframe

Iframe má od roku 2019 stejný parametr loading s hodnotou lazy.

<iframe src="adresa-stranky.html" loading="lazy">

Použití je podobné jako u obrázku. Pokud chci do stránky vložit iframe, který uživatel uvidí až po rolování, je lepší ho nenačítat hned a načítání pomocí loading="lazy" odložit, než se k němu uživatel dostane. Řekl bych, že to je ještě užitečnější než v případě obrázků, protože přes iframe se načítá celá stránka se všemi svými dalšími objekty (skripty, styly, obrázky).

Naneštěstí v praxi se iframe používá hlavně pro počitadla a reklamu. Reklamní frikulíni dostávají infarkt z představy, že by se reklama mohla nenačíst, když už ji prodali. Je jim jedno, že uživatel reklamu načítá zbytečně, i když ji stejně neuvidí. Naopak vyžadují (z mého pohledu nešťastně) nastavit reklamě loading="eager", aby se načetla určitě a prioritně.

Psáno v srpnu 2019, publikováno 21. 12. 2019

 

Reklama

www.webhosting-c4.cz, webhosting s doménou v ceně. 20GB
o tvorbě, údržbě a zlepšování internetových stránek

Návody HTML CSS JavaScript Články Ostatní

Články Katalog zdrojů SEM SEO

Jak psát web píše Yuhů, Dušan Janovský. Kontakt.