O webu
Zrychlení AJAXové aplikace o 100 ms

Pokud stránka funguje tak, že při kliknutí na odkaz/tlačítko (onclick) zavolá AJAXový požadavek, který změní část obsahu stránky, můžeme celé odbavení jednoduše zkrátit v průměru o 100 a více milisekund.

Vše, co je potřeba udělat, je rozložit akci do dvou kroků.

  1. stažení dat,
  2. zobrazení obsahu

Jak funguje kliknutí

Standardní průběh kliknutí je takový, že uživatel:

  1. najede na tlačítko/odkaz (onmouseover),
  2. stiskne levé tlačítko myši (onmousedown),
  3. uvolní tlačítko myši (onmouseup)

Pointa je v tom, že tyto tři kroky mohou trvat běžně kolem 0,5 vteřiny (mezi stisknutím a uvolněním tlačítka cca 100 milisekund). Pokud tedy obsah začneme načítat už při (1) najetí myší nebo (2) stisknutí tlačítka, může být v době (3) uvolnění tlačítka už připravený (stažený).

Samotné přejetí myší ale může vykonat řadu „planých poplachů“, kdy se data budou načítat zbytečně. Jde tomu pomoci menší prodlevou mezi najetím a přednačítáním.

Při stisknutí tlačítka je sice také možné zrušit akci odjetím pryč, ale počet takových případů nebude příliš vysoký.

Vyzkoušejte si, jak dlouho vám zabere kliknutí od najetí na tlačítko nebo od jeho stisknutí. Celková doba je závislá i na velikosti prvku.

Kliknutí od najetí trvalo:

O tento čas můžeme snadno snížit odezvu aplikace.

Řešení

Při konkrétním použití mohou nastat dva případy.

  1. Přednačtení se stihne před dokončením akce (uvolnění tlačítka).
  2. Načítání bude pokračovat i po dokončení akce.

Pro konkrétní řešení si tedy uložíme dva stavy:

  1. obsah je připraven – pripravenaData
  2. na získaný obsah se má přejít – prejit

Při stisknutí tlačítka se nastaví, že nejsou data připravená a zavolá se funkce pro načtení:

pripravenaData = false;
nacist(url);

Funkce nacist začne načítat obsah a v případě dokončení změní proměnnou pripravenaData.

pripravenaData = true;

Při uvolnění tlačítka (dokončení akce) se v případě, že jsou data už načtena, zobrazí obsah.

if (pripravenaData) {
  // zobrazit obsah
}

Pokud by obsah ještě načten nebyl, změní se proměnná prejit na true. V takovém případě na základě kladné hodnoty prejit funkce nacist rovnou zobrazí obsah.

Celý postup demonstruje živá ukázka. Kde se po stisknutí tlačítka myši začne načítat obsah do přednačítacího <div>u a po dokončení akce se přesune na cílové umístění.

Živá ukázka

Způsob přednačítání

K úvaze je, zda si (před)načtený obsah pouze uložit do proměnné nebo vypsat do pomocného elementu. V případě vypsání do pomocného <div>u se začnou rovnou načítat i případné externí objekty a nový obsah se může vykreslit už před dokončením akce, což také nejspíš zrychlí výsledný dojem.

Dotyková zařízení

U dotykových zařízení jde místo onmousedown a onmouseup použít jejich ontouch* obdoby.

Otevírání do nového okna

V desktopových prohlížečích je běžné, že uživatelé otevírají odkazy do nové záložky nebo do nové záložky na pozadí klávesami Shift/Ctrl + kliknutí.

Případně si kliknutím pravého tlačítka chtějí zkopírovat adresu odkazu a podobně.

V takových případech je nejspíš zbytečné cokoliv přednačítat a při stisku jiného tlačítka než levého nebo při přidržení některých kláves proto nic nedělat.

if (e.which > 1 || e.metaKey || e.ctrlKey) {
  return;
}