Responzivní načítání obrázků

V moderním a mobilním webu často narážíme na problém s tím, jak velké načítat obrázky.

Sice máme HD (1080p) … a v roce 2014 i QHD (1440p) a od roku 2015 dokonce UHD (4K, což odpovídá 2160p, ale už se tak neuvádí) … displeje, které zvládnou zobrazit opravdu kvalitní obrázky, ale na druhou stranu jsou tyto displeje často malé (4″ – 5″ mobilní telefony) nebo se jsou sledovány z velké vzdálenosti (~50″ UHD/4K televize sledované z několika metrů), takže zobrazit v HD/4K např. graf nebo mindmapu může skončit nečitelnou pavučinou. Navíc velmi často se stává, že se s HD telefonem připojujete přes 3G nebo dokonce GPRS/EDGE a pak takové načtení HD obrázku trvá věčnost.

HTML5 specifikace na to myslí a přináší hned dvě tři možnosti, jak to vyřešit. A samozřejmě existují ještě 2 CSS3 možnosti.

Picture element

První možností je použití picture element, který funguje stejně jako elementy video a audio.

Upozornění: Správný a nově podporovaný zápis picture - source je nyní s vlastností srcset místo src. Nové prohlížeče mohou ignorovat definici source, pokud obsahuje jen src atribut! Viz popis source od Mozilla Foundation nebo upozornění v Chromium.

<picture>
   <source
      media="(min-width: 1080px)"
      srcset="picture_hd.jpg">
   <source
      media="(-webkit-min-device-pixel-ratio: 2)"
      srcset="picture_iphone.jpg">
   <img src="picture_default.jpg">
</picture>

Element picture obsahuje několik definicí source, které pomocí media atributu (který odpovídá CSS3 tagu @media) definují, pro které prohlížeče daný obrázek platí. Tím se dá celkem dobře rozlišit různé velikosti obrazovky, rozlišení (DPI), atd. Picture může také obsahovat další elementy, jako je IMG, který se zobrazí na prohlížeči, který tag picture zatím nezná (obdoba noscript pro prohlížeče bez podpory JavaScriptu) nebo i třeba DIV nebo odstavec P, které se zobrazí na textových prohlížečích atd.

Upozornění: některé prohlížeče (např. ty založené na Chromium) picture vůbec nezobrazí, pokud v něm chybí prvek img. Vždy je tedy kromě source potřeba uvádět i záložní img.

Do definice source můžete přidat ještě hodnotu type, která určí, že daný obrázek se má načíst jen v případě, že prohlížeč podporuje daný typ:

<picture>
   <source
      type="image/svg+xml"
      src="picture.svg">
   <img src="picture.jpg">
</picture>

Další definici, kterou můžete do source zadat je definice velikost obrazovky, pro kterou se má daný source použít:

<picture>
    <source
        media="(max-width: 480px)"
        srcset="logo.jpg,
                logo-200.jpg 2x,
                logo-300.jpg 3x"
    />
    <source
        media="(min-width: 480px)"
        srcset="logo-200.jpg,
                logo-300.jpg 1.5x"
    />
    <img src="logo.jpg" />
</picture>

Pomocí media jsme nadefinovali, že na starých prohlížečích (bez podpory Picture) a telefonech (320px při 160dpi) se načte logo.jpg, zatímco na novějších desktopech (rozlišení 480px+) a HD telefonech (320px při 320dpi) se načte dvojnásobné logo-200.jpg a na velkých telefonech (iPhone6+, Samsung Alpha) nebo HD+ tabletech (iPad Air 2, Samsung Tab S) se načte trojnásobné logo-300.jpg.

Problém ale je, že v současné době žádný z používaných prohlížečů picture element zatím nepodporuje a nebo je podpora jen experimentální (a většinou se musí zapnout v konfiguraci). Existují určité spekulace o nevýhodách této metody (např. že defaultní obrázek se stáhne vždy), ale vzhledem k vývojové fázy se raději nechme překvapit, co z toho nakonec bude.

Update: Picture je již plně implementován od Chromium 38 (říjen 2014), které momentálně používá Chrome i Opera a také Android 5.0+. Firefox ho podporuje od verze 38 (květen 2015). Microsoft ho podporuje od verze Edge 13 (IE 13). Sledujte http://caniuse.com/#feat=picture pro současný stav.

Update: Safari 11.1 umožňuje do elementů PICTURE nebo IMG zadat i MP4 video (meta video/mp4) a nahradit tak historicky používaný, ale jinak zcela nevyhovující, animovaný GIF. Pokud umístíte video do obrázku, nebude logicky hrát zvuk.

<picture>
    <source type="image/png"
        srcset="animovany.png">
    <source type="video/mp4" 
        srcset="video.mp4" />
    <img src="animovany.gif" />
</picture>

Poznámka: Starší Safari obsahuje chybu, kvůli které vždy stáhne soubor z prvního source (bez ohledu na type) a teprve když zjistí, že daný formát nepodporuje, stáhne ten správný. Proto vždy uvádějte jako první animované PNG, které je podporováno od Safari 8 (resp. u statického obrázku JPEG-2000, které je preferované pro Safari, případně normální JPG nebo PNG, které také podporuje). Tato chyba byla opravena s uvedením videa místo obrázku ve verzi Safari 11.1.

Zatím (říjen 2015) se zdá, že Apple podporu Picture neplánuje a spíše se zaměří na srcset, se kterým začal v iOS 8 a od iOS 9 má plnou podporu. Apple se naštěstí nechal přemluvit, a do Safari 9.1 a iOS 9.3 doplnil podporu Picture elementů – obě verze by měli vyjít někdy v první (nebo možná až druhé) čtvrtině roku 2016.

Pozor při debugování, protože Firebug či Developer tools zpravidla označí img prvek, pokud na obrázek kliknete a necháte ho zobrazit v DOMu. To ale neznamená, že by zobrazený obrázek byl ten uvedený v IMG, ale jen to, že prohlížeč bere picture jen jako definici pravidel a zvolený obrázek vykresluje do image prvku (který buď vytvoří, nebo použije ten uvedený uvnitř picture). Pokud chcete vědět, který obrázek se skutečně stahuje, musíte se podívat na záložku Síť (Network), kde se zobrazí jméno toho, který se skutečně stáhl.

Pokud máte více pravidel, které stahují stejný obrázek a chcete je otestovat, prostě použijte jména obrázků odkazující na dané pravidlo – i když obrázek neexistuje, prohlížeč se ho pokusí stáhnout a vy ho uvidíte na záložce síť:

<picture>
    <!-- obrázky *.picture-*.jpg neexistují,
     a používají se jen pro debugování -->
    <source
        media="(max-width: 480px)"
        srcset="logo.picture-1x.jpg,
                logo-200.picture-2x.jpg 2x,
                logo-300.pixture-3x.jpg 3x"
    />
    <source
        media="(min-width: 480px)"
        srcset="logo-200.picture-1x.jpg,
         logo-300.picture-1.5x.jpg 1.5x"
    />
    <img src="logo.jpg" />
</picture>

Když se pak prohlížeč pokusí stáhnout obrázek logo-200.picture-1x.jpg, víte, že použil druhý source pro šířku 480+px a DPR 1. Pokud by v tomto případě stáhl původní logo.jpg, znamenalo by to, že je něco špatně, picture pravidla nefungují a prohlížeč použil původní image.

CSS pro picture

Pokud chcete formátovat prvek picture, například aby byl vždy 100% na šířku, musíte se k němu chovat jako k obrázku v DIVu. Prohlížeč totiž strukturu PICTURE-SOURCE přeloží na PICTURE-IMG a tak je také musíte formátovat:


/* zobrazí picture přes celou stránku */
picture {
    width: 100%; 
}
/* přizpůsobí vnitřní obrázek kontejneru */
picture > img { 
    width: 100%;
    vertical-align: middle;
}

Source set

Další možností, kterou HTML5 nabízí je sada adres, ze kterých si může prohlížeč vybrat.

Základní myšlenka je ta, že iPhony a většina Androidů má větší fyzické rozlišení než jaké hlásí v prohlížeči. Díky tomu je možnost zobrazit obrázek (zpravidla) v dvojnásobném rozlišení, než jaké prohlížeč hlásí.

<img
   src="picture_default.jpg
   srcset="picture_150.jpg 1.5x,
           picture_200.jpg 2x">

Touto definicí obrázku říkáme prohlížeči, že výchozí obrázek je picture_default.jpg, který se zobrazí na starších prohlížečích. Prohlížeč, který zná source set a má větší rozlišení obrazovky (zde 1,5 krát či 2 krát větší – definuje se písmenem „X“ za číslem) si pak automaticky vybere nejvhodnější URL a tu stáhne.

Obrázek lze nadefinovat i pro šířku obrazu, což se definuje písmenem „W“ za číslem.

<img
   src="picture_default.jpg
   srcset="picture_HD.jpg 1024w,
           picture_FHD.jpg 1880w">

I tato metoda je však ještě v počátcích a zatím je implementována jen v některých verzích webkit prohlížečů a plánuje se do Firefoxu.

Update: Plně podporovaný je v Chrome a Firefox od verze 38. Ostatní prohlížeče využívající webkit (Opera, Android, apod.) ho podporují ve verzích využívajících jádro Chromium verze 38. Sledujte http://caniuse.com/#feat=srcset pro současný stav.

Update: nový iOS 8 již podporuje srcset pro použití „X“ definice (od iOS 9 má plnou podporu vč. „W“ definice), takže můžete poskytovat různě kvalitní obrázky pro jednotlivé verze iPhonů a iPadů.

<img
   src="picture_for_iphone-1-to-4.jpg"
   srcset="picture_for_iphone-4s-to-6.jpg 2x,
           picture_for_iphone-6plus.jpg 3x">

Update: Microsoft Edge (aka Internet Explorer 12 pro Windows 10) také podporuje srcset, i když jen  „X“ definici podobně jako iOS8. Microsoft tvrdí, že pracuje i na „W“ definici, která by měla být k dispozici ve finální verzi (srpen 2015) nebo v některém updatu (což je velká výhoda MSEdge, že se bude updatovat mnohem častěji stejně jako ostatní prohlížeče). Plně podporován je v Edge 13.

Sizes

Source set nabízí ještě jednu možno pro responzivní layout. Například pokud chcete zobrazit 2 obrázky vedle sebe, ale na mobilech jen jeden, můžete přímo u obrázku nadefinovat, jak velký se má načíst v závislosti na šířce stránky:

<img
   src="picture_default.jpg
   srcset="picture_HD.jpg 640w,
           picture_FHD.jpg 1280w"
   sizes="(min-width:1024px) 50vw, 100vw"
>

Tato definice říká, že pokud je šířka stránky větší než 1024px, načte se obrázek podle poloviny šířky obrazovky (50vw = 50% šířky stránky), zatímco pro menší obrazovky se načte obrázek podle celé šířky obrazovky (100vw = 100% šířky stránky).

Pro obrazovku širokou 800px se načte obrázek picture_HD.jpg (100vw * 800px = 800px, což stačí pro 640w v srcset), zatímco pro šířku 1200px se načte obrázek picture_default.jpg (50vw * 1200px = 600px, což je méňě než požadovaných 640w). Obrázek picture_FHD.jpg by se pak načetl jen na rozlišení 2560px a více (1280px * 50vw = 2560px).

Poznámka: jednotky vw a vh jsou známy již delší dobu, takže všechny prohlížeče podporující srcset je určitě budou znát.

Do hodnoty sizes dokonce můžete přidat jednoduché výpočty, abyste pokryli všechny definice v CSS. Například pokud budou mít obrázky nějaký margin:

<img
   src="picture_default.jpg
   srcset="picture_HD.jpg 640w,
           picture_FHD.jpg 1280w"
   sizes="(min-width:1024px) calc(50vw - 2em),
           calc(100vw - 3em)"
>

Update: Podle nové W3C specifikace (jaro 2015), definice sizes je povinná v případě, že používáte určení šířky v srcset. To znamená, že pokud máte v definici srcset uvedeny obrázky pro 320w a 640w, musíte pomocí sizes uvést, pro jaké poměry se dané obrázky mají načítat. Důvod je ten, že většinou nezobrazujete obrázek přes celou šířku stránky (100vw) ale většinou má nějaké okraje. A tak se často stane, že na telefonu s 360px na šířku by se pro 100vw musel stáhnout obrázek pro 640w, ale když uvedete sizes="calc(100vw - 3.2em)" (protože máte 1em margin, 0.5em padding a 0.1em border), může se použít jen 320w obrázek (a ušetří se 3/4 stahovaného objemu).

I když je sizes povinné, nemusíte si vymýšlet nějaké podmínky a pokud k tomu máte důvod, stačí uvést jen 100% šířku:

<img
   src="picture_default.jpg
   srcset="picture_HD.jpg 640w,
           picture_FHD.jpg 1280w"
   sizes="100vw"
>

Bohužel sizes není možno použít v případě, že definujete srcset podle fyzického rozlišení (2x, 3x, apod.). Naopak Picture tohle umí díky kombinaci definic media a srcset.

Podmínku pro sizes musíte vždy uzavřít do závorky (aby prohlížeč poznal, co vše do ní patří) a nemůžete uvnitř používat čárky (protože těmi se oddělují jednotlivé definice; můžete ale používat klíčová slova AND a OR:

<img src="..." srcset="..." sizes="
((min-width: 300px)or(min-height:200px)) 320px,
((max-width: 300px)and(max-height:200px)) 160px,
240px" />

Některé prohlížeče ale nemusí správně zpracovat kombinované podmínky, pokud obsahují pro ně neznámé (nebo nepoužitelné) definice. Například pokud chcete použít podmínku pro natočení obrazovky, nemusí podmínka fungovat tam, kde se obrazovka otočit nedá (např. desktop); proto bude lepší vytvořit ještě jednu podmínku bez daného klíče:

<img src="..." srcset="..." sizes="
((min-width: 300px) and
    (orientation:portrait)) 320px,
((min-width: 300px) and
    (orientation:landscape)) 160px,
(min-width: 300px) 160px, //pro desktop
320px" />

A v kombinaci s „W“ pak záleží na browseru, zda definice „(min-width:1024px) 50vw“ na iPhone 5 načte obrázek pro rozlišení 160px (relativní rozlišení 320px * 50vw) nebo správných 320px (fyzické rozlišení 640px * 50vw). Podle všech předpokladů, prohlížeč by měl počítat s fyzickým rozlišením, protože to je to, oč u srcset beží a tak by s tím neměl být problém. Viz další kapitola.

V tomto případě platí, že prohlížeč načte první obrázek, který splňuje dané podmínky (což znamená, že definici bez orientace použijí jen prohlížeče, které ji neznají). Tímto se sizes liší od CSS, kde vždy vyhraje až ta poslední definice.

Kombinace

Podle HTML definice lze kombinovat Picture source, srcset i sizes takto:

<picture>
    <source
        media="(min-width: 36em)"
        srcset="large.jpg  1920w,
                medium.jpg  960w,
                small.jpg   480w"
        sizes="calc(100vw - 1em)"
    />
    <img src="medium.jpg" />
</picture>

Ale otázka je, které prohlížeče (a kdy) to budou podporovat… Dnes (2016+) je naopak tohle jediný správný zápis picture!

Výjimku samozřejmě tvoří použití Picture a srcset pro načtení SVG (s fallbackem na image s JPG):

<picture>
    <source type="image/svg+xml"
        src="logo.svg" />
    <img src="logo.jpg"
        srcset="logo-150.jpg 1.5x,
                logo-200.jpg 2x,
                logo-300.jpg 3x" 
    />
</picture>

V tomto případě použije moderní prohlížeč s podporou vektorové grafiky soubor SVG, u kterého nezáleží na rozlišení, protože se vždy správně přizpůsobí – a proto není potřeba uvádět media, sizes ani více hodnot v srcset. Pokud by ale prohlížeč nemohl SVG načíst (nebo nepodporuje Picture), použije místo něj JPG soubory podle příslušného rozlišení (např. logo-300.jpg pro iPhone6+ a logo.jpg pro desktop). Prohlížeč, který nezná ani Picture ani srcset, pak samozřejmě použije původní logo.jpg.

Novější verze prohlížečů dokonce podporují kombinace „X“ a „W“ hodnot v srcset:

<picture>
    <source
        media="(min-width: 36em)"
        srcset="large.jpg  1920w,
                medium.jpg  960w,
                small.jpg   480w,
                medium.jpg 480w 2x,
                large.jpg 480w 4x"
        sizes="calc(100vw - 1em)"
    />
    <img src="medium.jpg" />
</picture>

V tomto případě totiž prohlížeč hodnotu „W“ bere podle hlášeného rozlišení (např. 320px na mobilu) i když fyzické rozlišení je větší (např. 640px na iPhone 5). Proto je potřeba uvést hodnoty jak pro různé šířky obrazovky (desktop) tak i různá rozlišení (mobily).

Src-N

Třetí možností (první specifikace vznikla koncem roku 2013)  je tzv. src-n zápis, jehož jméno vychází z toho, že do tagu IMG můžete zapsat libovolný počet vlastností src, které označíte pomocí čísel:

<img
    src="image_default.jpg"
    src-1="image_hd.jpg"
    src-2="image_uhd.jpg"
/>

Prohlížeč, který zná jen klasický HTML4 tag, načte obrázek image_default.jpg, ale moderní HTML5 prohlížeč (zatím ale nevím o žádném, který to podporuje – vývojáři Chromu se už přes rok hádají, zda ho podporovat, ale nenašel jsem zprávu o tom, že už to implementovali) si může vybrat, který z oněch 3 načte.

Samozřejmě výše uvedený zápis nemá moc smysl, protože prohlížeč neví, jak by si měl vybírat. Proto mu můžete v každém src-n poradit, k čemu se daný obrázek určený:

<img
    src="image_hd.jpg"
    src-1="(min-width: 1400px) image_uhd.jpg"
    src-2="(max-width: 400px) image_phone.jpg,
            image_hd.jpg 2x"
/>

V tomhle kódu je vidět několik příkladů toho, jak prohlížeči pomáháme se rozhodnout:

  • defaultní obrázek je určen pro HD, tedy desktopy a HD telefony či televize (což prohlížeč přímo neví, ale dojde mu to z dalších podmínek), načte tedy image_hd.jpg,
  • pro moderní QHD/UHD/4K monitory a televize načte velmi kvalitní obrázek image_uhd.jpg,
  • pro malé telefony s displejem do 400px naopak načteme menší a méně kvalitní obrázek image_phone.jpg,
  • ale pro telefony s vyšším rozlišením 2x a více (tedy 320dpi a více) načteme původní a kvalitnější image_hd.jpg, aby se lépe zobrazil na retina displejích (iPhone 6, Samsung S6, apod.).

Stejně jako v případě výše uvedeného Picture elementu i src-n umožňuje definici pro různé responzivní layouty – opět si vezměme případ, kdy na desktopu budou dva obrázky vedle sebe (width = 50%), ale na telefonu budou pod sebou (width = 100%):

<img
    src="image_hd.jpg"
    src-1="100% (30em) 50%;
            image_phone.jpg 400,
            image_hd.jpg 1080,
            image_uhd.jpg 2160"
/>

V tomto zápisu říkáme prvním řádkem „100% (30em) 50%“ říkáme:

  • obrázek by se měl načíst v rozlišení odpovídající 100% šířky stránky
  • pokud je ale stránka širší než 30em (480px), bude se načítat v rozlišení odpovídající jen 50% šířky stránky.

V dalších řádcích pak definujeme různé obrázky a jejich šířku, takže prohlížeč bude vědět, že obrázek image_phone.jpg je vhodný pro šířku 400px, zatímco obrázek image_hd.jpg je vhodnější pro šířky kolem 1080px.

Pokud pak prohlížeč ví, že šířka displeje je 320px při 240dpi, zobrazí obrázek určený pro telefony, protože nejblíže odpovídá 100% šířky stránky (320 * 1,5 = 480px, což je nejblíže 400px u image_phone.jpg).

Pokud bude šířka stránky 1800px (WQXGA+ monitor), prohlížeč zobrazí image_hd.jpg – sice UHD obrázek je nejblíže (1800px je blíže 2160px než 1080px), ale jelikož je to více než 30em (480px), tak rozměr vydělí 2 (1800px * 50% = 900px) a tudíž je nejblíže obrázek o rozměru 1080px.

Definice layoutu může vypadat i takto: "(max-width: 400px) 100%, (max-width: 1080px) 50%, 33%", na telefonech bude jeden obrázek na řádku (se 100% šířkou), na HD budou 2 vedle sebe a na větších rozlišeních budou 3 obrázky (33% pro „více než 1080px“).

Jak už jsem psal, zatím není znám žádný prohlížeč, který by src-n podporoval, ale pokud se vám tento zápis líbí, můžete použít Polyfill od Merkle-XD.

Image-set a CSS Media

Načítání responzivních obrázků pomocí image-set se netýká HTML ale CSS3 a ve skutečnosti byla první metodou, podle které byly později navrženy výše uvedené HTML metody.

Definice image-set() se dá použít kdekoliv v CSS, kde byste jinak používali definici url():

.test {
    background-image: image-set(
                   'normal-logo.jpg',
                   'big-logo.jpg' 2x);
    border-image: image-set(
                   'border.png' 1x,
                   'nice-border.png' 2x);
}

Bohužel, i když byla tahle metoda první navržená a je tedy specifikovaná nejdelší dobu, má nejmenší podporu mezi prohlížeči. Konkrétně Webkit (Safari, Chrome, Opera) ji podporuje, ale jen s prefixem -webkit-, a Firefox a IE ji nepodporují vůbec.

Je to pravděpodobně způsobeno tím, že stejného výsledku, i když trochu obtížněji, lze dosáhnout i pomocí media definice:

.test {
    background-image: url('normal-logo.jpg');
    border-image: url('border.png');
}
@media
/* pro iPhone a některé Androidy */
(-webkit-min-device-pixel-ratio: 2),
/* pro dektop and starší mobily */
(min-resolution: 192dpi),
/* pro nová mobilní zařízení */
(min-resolution: 2dppx)
{
.test {
    background-image: url('big-logo.jpg');
    border-image: url('nice-border.png');
}}

Pokud chcete rozlišení zkombinovat se šířkou obrazu, např. pro obrázky, které se roztahují na celou šířku obrazovky, nebo pozadí celé stránky, použijte CSS:

.test {
    background-image: url('normal-logo.jpg');
}
@media
(min-width: 1025px) AND (-webkit-min-device-pixel-ratio: 2),
(min-width: 1025px) AND (min-resolution: 192dpi),
(min-width: 1025px) AND (min-resolution: 2dppx) {
  .test { 
    background-image: url('very-big-logo.jpg');
    border-image: url('very-nice-border.png'); 
  }
}
@media
(max-width: 1024px) AND (-webkit-min-device-pixel-ratio: 2),
(max-width: 1024px) AND (min-resolution: 192dpi),
(max-width: 1025px) AND (min-resolution: 2dppx) {
  .test { 
    background-image: url('mostly-big-logo.jpg');
    border-image: url('mostly-nice-border.png'); 
  }
}
@media
(max-width: 399px) AND (-webkit-min-device-pixel-ratio: 2),
(max-width: 399px) AND (min-resolution: 192dpi),
(max-width: 399px) AND (min-resolution: 2dppx) {
  .test { 
    background-image: url('big-logo.jpg');
    border-image: url('nice-border.png'); 
  }
}
@media
(max-width: 399px) AND (-webkit-min-device-pixel-ratio: 3),
(max-width: 399px) AND (min-resolution: 288dpi),
(max-width: 399px) AND (min-resolution: 3dppx) {
  .test { 
    background-image: url('big-logo.jpg');
    border-image: url('nice-border.png'); 
  }
}

Podmínky kombinujte přes AND a čárku tak, jak je zde uvedeno.
Nejprve uveďte podmínky pro nejvyšší rozlišení pomocí podmínky min-width a následně pro menší rozlišení s použitím max-width, přičemž postupujte od největšího k nejmenšímu, aby se pravidla správně kaskádově přepsala. U prvního (min-width) stylu můžete vynechat rozlišení 1x, protože pro něj bude platit výchozí styl (ten bez @media). Rozlišení (uváděné přes min-resolution) pak uvádějte od nejmenšího k největšímu, aby se opět kaskádově přepsaly.

Pokud máte výchozí styl (bez @media) naopak uveden pro mobilní rozlišení (tzv. mobile-first), použijte jen pravidla s min-width a postupujte od nejmenšího k největšímu (např. výchozí je pro 320px a @media budou postupně pro 400px, 480px, 720px, 960px, atd.).

3 komentáře u „Responzivní načítání obrázků“

  1. Díky za užitečný a hlavně přehledný článek.
    Ale jak tedy ošetříme situaci: retina + pomalé připojení k internetu?

    Existuje způsob jak přes HTML5 nabídnout prohlížeči „malý soubor“ pro pomalé připojení, který načte jako první a pak načte další větší, kterým ho pak nahradí?

    Děkuji za tip ! 😉

    1. Pro JPG lze použít progresivní načítání. To spočívá v tom, že se do souboru nejprve uloží nekvalitní (rozmazaný) základ obrázku, který se rychle stáhne a zobrazí, a pak teprve se do souboru ukládají další verze téhož obrázku v lepší kvalitě. Díky tomu může prohlížeč zobrazit celý obrázek dříve a vyhne se onomu nechtěnému zobrazování po řádkách. Navíc díky JPG kompresi se velikost celého souboru nezvětší (ale naopak se často zmenší). Uložit progresivní JPG lze třeba ve Photoshopu nebo programu RIOT (viz Úprava obrázků pro web).
      Pro PNG a jiné formáty (WEBM, apod.) se používá technika spritů, díky čemuž lze rychleji stáhnout větší množství menších obrázků (viz Dynamicky zvětšované sprite).
      U SVG problém není, protože ty jsou stejně velké nezávisle na rozlišení. Jediná věc, která může zrychlit jejich načítání, je povolení gzip komprese na webserveru (díky tomu, že SVG je vlastně XML a tedy text, dá se dobře komprimovat). Jak použít SVG viz SVG s fallbackem na PNG.

      Pokud netrváte na HTML5 řešení, lze použít tzv. Lazyloading. Tedy postupné stahování obrázků pomocí JavaScriptu. Pro jQuery můžete použít plugin LazyLoad. Příp. si napsat vlastní řešení, které vždy v onload obrázku změní jeho src na obrázek v lepší kvalitě dokud nestáhne obrázek dostatečně kvalitní pro dané zařízení (na základě devicePixelRatio).

    2. Možná by to šlo nějak řešit přes ServiceWorker, ale vzhledem k současné podpoře (pouze webkit) to je spíš otázka do budoucna.

      Edit: Podobným problémem se zabývá tenhle článek, kde se pomocí ServiceWorkeru nahrazují JPG a PNG za menší WebP tam, kde jsou podporovány. Kvůli podpoře je použitelné jen pro Chrome a Android.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..