Zredukování HTTP požadavků s data URI

Pondělí, 4. Únor 2013

Jestliže máte na webu příliš HTTP požadavků, budete nejspíš řešit jejich snížení. Můžete spojovat CSS soubory a tak podobně. Pro obrázky kromě CSS sprite existuje i další hezká metoda, data URI.

Co to znamená data URI a jak to stránkám pomůže?

Data URI (uniform resource identifier – neplést s URL) je název pro způsob, jak data zobrazit v internetovém prohlížeči bez potřeby externího zdroje. To znamená, že můžete na stránkách zobrazovat obrázek, aniž by externě existoval. Bude zkrátka zapsaný přímo v HTML, případně CSS.

To sebou přináší výhody, ale i nevýhody. Ty si probereme později. Nám jde nyní hlavně o snížení počtu HTTP požadavků a to tato metoda umí perfektně. Dokáže totiž klidně z pěti obrázků / požadavků udělat… žádný požadavek a přitom obrázky zůstanou. Ale čáry v tom nejsou, nebojte.

Jak to dokáže snížit počet HTTP požadavků na nulu?

Už vám to prozradím, tahle metoda totiž nesnižuje, ona rovnou webový požadavek vyloučí. Jestli rozumíte definici, kterou jsem napsal výše, jistě už víte jak na to. Data URI zkrátka přeplácá obrázek na obyčejné textové znaky. Ty pak vložíte do svého CSS namísto adresy k obrázku. Tím úplně vyloučíte webový požadavek, protože jste obrázek vložili přímo do dokumentu.

Obrázek, který se zobrazuje níže je jen hromada znaků. Jestli nevěříte, podívejte se do zdrojového kódu nebo si ho otevřete do nového okna.

Terraria

Díky této metodě ušetříte plno HTTP požadavků. Ale využití to má více. Pokud například svůj obrázek, který používáte v podpisu u mailu převedete na data URI, už nebudete muset v mailu odkazovat někam na web ani přikládat přílohu. Obrázek vložíte prostě přímo do mailu.

HTML kód s data URI obrázkem pak vypadá následovně
<img alt="Šedá tečka" src="data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="/>

Jak můžete vyčíst z kódu, začátek říká, že půjde o data URI, poté, že se jedná o obrázek ve formátu gif a base64 už jen značí kódování. Na konec jen dodám, že data URI je vhodné používat jen pro malé datové objekty. Dá se to krásně použít třeba pro webovou grafiku (proužky, malá loga a podobné prvky). Obrázek by neměl přesahovat cirka 20 kB, protože pak metoda neslouží k tomu, k čemu byla stvořena (vyloučení zbytečných požadavků).

Čeho se dá dosáhnout díky využívání této metody

V první řadě to šetří webové požadavky. Jestli máte na webu 15 maličkých obrázků, převedením na data URI dosáhnete krátké doby odezvy, protože se obrázky nebudou řadit do fronty (v prohlížeči), ale stáhnout se současně. Já převedením webové grafiky weblogu do data URI ušetřil na hlavní stránce 9 požadavků. V článcích pak bylo ušetřeno požadavků 11.

Urychlení stránek ovšem nečekejte. Z mých měření vyšlo najevo, že redukováním HTTP požadavků rychlejší web neuděláte. Alespoň ne skutečně. Pocitově to už je jiná. Stránka s chytře využívanou metodou data URI totiž budí dojem, že je rychlejší. Klasický web se načítá tak, že se zobrazí bílá plocha s texty a až poté vám naskakují obrázky. Web s data URI se načítá tak, že se zobrazí bílá plocha s texty, ale rovněž webová grafika. To budí v návštěvníkovy dojem, že je stránka svižnější, protože ho neruší postupné načítání jednotlivých obrázků, ale vyskočí na něj vše již načteno.

Zvyšujete tím uživatelský zážitek z webu (známé jako UX – User experience). Je to stejné jako, když v Gmailu máte dojem, že se maily načítají rychleji než jinde. Schválně si zkuste kliknout na nějaký mail. Je tam totiž malý trik. Běžné kliknutí se skládá ze dvou částí. Ze stisknutí a povolení. Pokud jste na webu a klikáte na odkaz, začne se něco dít až ve chvíli, kdy tlačítko pustíte. V Gmailu se otevře mail ihned, jakmile zaznamená stisknutí. Nečeká se, až uživatel tlačítko pustí a tím se ušetří 100-200 milisekund. I takový okamžik má vliv na vnímání rychlosti a nejen proto se nám zdá Gmail svižný.

Převádíme obrázky na data URI – snadno a rychle

Zní to všechno skvěle? Já doufám, že ano. Pojďme se tedy vrhnout na samotné převádění obrázků. Celé je to ohromně snadné díky různým online generátorům. V první řadě si analyzujte svou stránku a vytipujte si obrázky, které chcete převést. Data URI se hodí pro webovou grafiku jako maličká loga, různé pixelové proužky a podobně.

Až budete mít vybráno, přejděte na data URI generátor. Po jednom do něj nahrajte všechny obrázky a nechte si vygenerovat textovou verzi. Tu pak vložte namísto URL adresy obrázku do CSS. Soubor se styly pak kešujte. To je hrozně důležité, aby bylo zajištěno plynulé načítání. Ve výsledku se může zdát soubor větší než obrázky, ale díky gzip kompresi je rozdíl minimální.

Takto naprosto vyloučíte HTTP požadavky na drobné obrázky a dosáhnete tak pocitově rychlejšího webu. Pokud by zmíněný generátor nefungoval, na internetu je plno alternativ. Zkuste třeba Duri.me.

Výhody a nevýhody, na které je dobré myslet

Závěrem bych shrnul výhody a nevýhody této metody. Výhody dozajista jsou: snadné použití, podpora ze strany prohlížečů, šetření webových požadavků a možnost vložení obrázku bez externího zdroje.

Mezi nevýhody patří:

  • nutnost vložení data URI kódu do souboru, který je kešován, protože to metoda sama o sobě neumí (na rozdíl od obrázků)
  • odkazování na stejný zdroj několikrát je neefektivní, protože musíte kód vložit znovu (a tím velikost dokumentu vzrůstá)
  • data URI obrázky nemají žádný název souboru a vyhledávače je budou zřejmě ignorovat, protože na ně neexistuje žádná URL adresa.

Metoda má dle mého hlavní užitek (kromě již zmíněných) v mobilní verzi stránek. Kvůli většinou hroznému pingu z mobilního internetu by totiž hromada drobných obrázků trvala načíst tak týden. Díky data URI můžete všechno načíst v jednom souboru a prodleva vás tolik trápit už nemusí.

{ Komentáře k článku }

Radek Novák

Díky za fintu s gmailem. To se bude hodit :).

Radek Novák

Tak jsem nastavil funkčnost odkazů již při stisku tlačítka a pocitově je to opravdu rychlejší. Uvedený příklad je pro jQuery.

$("body a").mousedown(function(e) {
// jen pro levé tlačítko
if (e.which === 1) {
	var odkaz = $(this).attr("href");
	$(location).attr('href',odkaz);
return false
}
});
Tomáš Erlich

Neměl bys nějakou živou ukázku? Když jsem tenhle kód testoval tady na webu, nešlapalo to. Docela rád bych to aplikoval. Udělá to web zas o něco rychlejší. Taky mě zajímají reakce lidí. Jestli se to bude zamlouvat či mást… Co myslíš ty?

Radek Novák

Živá ukázka viz webgames.cz. Já si této vychytávky v gmailu za 5 let nevšiml, tak předpokládám, že návštěvníci webgames si toho také nevšimnou a nebude to tedy nijak matoucí. Ovšem pocitové zrychlení je znatelné.

Tomáš Erlich

Páni, to je rychlé jako blesk! Upřímně, já si toho v mailu také dříve nevšiml. Pověděl mi to chlápek, který se staral o „uživatelský prožitek“. Myslím, že do toho půjdu s tebou. Působí to skvěle.

Při proklikávání jsem ovšem narazil na jeden problém. Když otevíráš nové okno v Chromu přes Ctrl + kliknutí myší – otevře se cílový odkaz do nového okna a zároveň se načte v již otevřeném. Někdo otevírá nové okno třeba kolečkem, ale já to dělám takhle. Myslíš, že by to šlo nějak ošetřit?

Radek Novák

Vidíš, to mě nenapadlo. Teď už by to mělo šlapat.

if (!e.ctrlKey) {
	if (e.which === 1) {
		var odkaz = $(this).attr("href");
		$(location).attr('href',odkaz);
	return false
	}
}
Tomáš Erlich

Tak jsem to zkoušel aplikovat na WordPress a mám všelijaké pocity. Prvně to pořád hlásilo chybu „TypeError: Property ‘$’ of object [object Window] is not a function“ a nešlo to. Až potom jsem našel, že značka $ je ve WordPressu kvůli konfliktům zakázaná.

Pokud jí chce člověk použít, musí kód obalit tímto jQuery(function ($) { a vevnitř už může znak používat. Nesmí se samozřejmě zapomenout vše uzavřít (});).

Funkční kód vypadá tedy následovně:
jQuery(function ($) {
$("#page").on('mousedown','a', function(e){
	if (!e.ctrlKey) {
	if (e.which === 1) {
		var odkaz = $(this).attr("href");
		$(location).attr('href',odkaz);
	return false
}}});
});

Nakonec jsem od použití upustil. A proč? Zdá se mi totiž, že se na web posílají dva požadavky. Jeden při stisknutí a druhý při puštění tlačítka. Takže to ve výsledku vlastně nefunguje. Musela by se nějak deaktivovat funkce otevření odkazu při puštění. Možná se pletu, ale při pozorování se mi to opravdu zdá…

Tesy

Toto se mi docela líbí ;). Má to zajímavý „účinek“ akorát jsem si k tomu přidal, aby to nereagoval na ctrl i shift, protože je možno otevírat nové taby i pomocí shiftu a dělalo to paseku.

Tomáš Erlich

Nezapomeň na to, o čem jsem tu psal. Posíláš totiž na server dva požadavky. Jeden, když klikneš a druhý, když pustíš tlačítko. Pokud to chceš mít naprosto dokonalé, musíš zablokovat ještě účinek puštěného tlačítka. Radkovo kód funguje dobře.

$("#page").on('click','a', function(e){
	if (!e.ctrlKey) {
	if (e.which === 1) {
	return false
	}}
});
Lostindream

Wow, tak tohle vypadá skvěle, super tip! :-). Asi taky použiju. :-).

Macecha

Ohledně snížení počtu požadavků na server, mi příjde lepší dát všechny malé obrázky, ikony apod. do jednoho velkého
Více ikonek (obrázku) v jednom souboru
Fast Rollovers Without Preload

Dále mám obavy z podpory vyhledávačů :) mi co jsme zažili IE 5 a podobně, tak stále máme psychické následky, ale snad už to je jen přežitek co se týče prohlížečů, a podpora by mohla být přes 90 %.

Naopak v emailech, je to skvělý nápad, dále u stránek, které si uživatel ukládá, a tak jim obrázek zůstane již ve stránce v html kódu. I když většinou prohlížeče podporují plnou archivaci webu se všemi prvky… tak třeba u nabídky na stažení stránek například v zipu je lepší to dát do jednoho html souboru.

Díky za další poznatek.

Štěpán Sršeň

Pokud chceš v emailech vložit obrázek přímo a ne klasicky, tak bych volil mime multipart/related, a to kvůli podpoře klientů. Výše zmíněný způsob bývá někdy blokován a častěji končí ve spamu. Když už je řeč o gmailu, tak taky vkládaj obrázky pomocí multipart.

Tomáš Erlich

Myslíš CSS sprite? Té metodě jsem též věnoval článek, ale přijde mi to příliš omezující a pracný. V tomhle se mi data URI líbí mnohem více. Vezmu obrázek, převedu ho, text vložím do CSS a je hotovo. Žádné problémy, žádná omezení a funguje to skvěle.

Ohledně podpory ze strany vyhledávačů bych se nebál a data URI používal všude tam, kam potřebuješ vložit maličký obrázek. Používá to třeba i Google. Všimni si v políčku na vyhledávání těch maličkých obrázků (foťák, klávesnice…), všechno to jsou data URI obrázky.

Pilda

A srovnával jsi i velikosti těch obrázků s velikostí kódu? Předpokládám, že ten kód nepodporuje žádnou kompresi (když pominu gzip u všeho kódu, ale ten je beztrátový, tudíž neefektivní pro obrázky) a obávám se, že ten kód pak bude datově mnohem větší než třeba jpeg, nebo gif obrázky. Takže toho pak ve výsledku teoreticky stahuješ více. Mnohem více, protože ztrátové komprese pro obrázky redukují jejich velikost opravdu hodně, ale beztrátové málo.

Ale neměřil jsem to, můžeš to zkusit.

Tomáš Erlich

V článku sem se o tom nezmiňoval, protože velikost není příliš rozdílná. Když už se ovšem ptáš, našel jsem si chvilku a zde máš pěkné srovnání. Vzal jsem 3 maličké obrázky a porovnal je.

První PNG obrázek má 7,5 kB v originále, převedený na data URI má 10 kB. S gzip se přenáší ovšem 7,7 kB, takže rozdíl je minimální. Druhý obrázek má v originále 6,7 kB, převedený 9 kB. S gzip se přenáší rovných 7 kB. Poslední obrázek měl 13 kB, po převedení na data URI 17,4 kB, ale s gzip 13,5 kB.

Z tří vzorků vidíš, že rozdíl v přenesených datech je minimální. Takže se to skutečně vyplatí, protože ušetřené HTTP požadavky jsou znát. Kdyby se to nevyplatilo, nepíšu o tom. A už vůbec bych to nepoužíval (veškerá grafika tady je přes data URI). Ostatně to namátkou používá třeba i Google a zkracovač adres bitly.

Komentáře jsou pro tento článek již uzavřeny.

Předchozí příspěvek:

Následující příspěvek:

Tato stránka již není udržována. Děkuji za pochopení.