Ako nastaviť načítavanie JavaScriptu, aby neblokovali vykreslenie stránky

Obtiažnosť:
Začiatočník
Pokročilý
Skúsený
Expert

Pred pár dňami som popisoval, ako oddialiť načítanie nekritických css, aby neblokovali vykreslenie stránky. Tentokrát sa pozrieme, ako nastaviť asynchrónne načítavanie JavaScript. Pre oddialenie načítania, sa používajú spôsoby async a defer.

Spôsob načítania ASYNC:

  • Súbor sa stiahne na pozadí s nízkou prioritou
  • Počas vykonávania sa môže prerušiť vykresľovanie stránky
  • Vykonanie sa spustí hneď, ako je to možné, aj mimo poradia

Spôsob načítania DEFER:

  • Súbor sa stiahne na pozadí s nízkou prioritou
  • Vykoná sa až po vykreslení stránky a tak neblokuje jej vykresľovaniu
  • Vykoná sa v poradí, tesne po kompletnom vykreslení HTML

Aby sme vedeli použiť toto asynchrónne načítavanie, pridá sa tento atribút do html tagu <script.... Aby to fungovalo, musí tag obsahovať atribút src<script src="..."></script>.

Bez použitia atribútu sa JavaScript načíta a vykoná hneď po jeho načítaní, čo môže blokovať vykresľovanie stránky a spomaliť načítanie. K načítaniu, dochádza postupne, ako sú skripty pridané v kóde smerom z hora dole. Počas načítania a vykonania, blokuje vykresľovanie stránky.

S atribútom ASYNC sa JavaScript načíta a vykoná mimo poradia v momente, keď je to možné. To znamená, že sa môže vykonávať naraz s inými časťami stránky. Tento spôsob, ale nemusí byť vždy vhodný pre JavaScript, ktorý závisí na ostatných súboroch. Po jeho načítaní, ktoré neblokuje vykresľovanie stránky, sa skript vykoná. Počas vykonávania, blokuje vykresľovanie stránky.

S atribútom DEFER sa JavaScript načíta mimo poradia, ale s nižšou prioritou. Vykoná sa až po načítaní celej stránky. Počas načítavanie tiež neblokuje vykresľovanie stránky a k jeho vykonaniu, dôjde až po úplnom vykreslení stránky. To umožňuje, aby sa stránka načítala bez zdržania a aby sa JavaScript vykonával až potom, čo je pripravený.

Graficky, by sa to dalo znázorniť takto:

Kedy používať atribút ASYNC

Použitie atribútu async je najvhodnejšie pre JavaScript súbory s vysokou prioritou, ktoré by mali byť spustené čo najskôr počas načítania stránky. Tento atribút by sa však mal používať s opatrnosťou a len pre súbory, na ktorých závisí prvotné zobrazenie stránky. Súbory s atribútom async sa tiež spúšťajú bez určitého poradia, takže sa zvyčajne používajú pre súbory, ktoré sú úplne nezávislé od ostatných JavaScript súborov.

Kedy použiť atribút DEFER

Atribútu defer je vhodné použiť pre bežné JavaScript súbory, ktoré nie sú kritické pre prvotné zobrazenie stránky a môžu byť spustené neskôr počas načítania. Atribút defer je vo väčšine prípadov najlepšou voľbou pre optimálne načítavanie stránky a užívateľskú skúsenosť. Vďaka tomuto atribútu môže prehliadač zobraziť obsah užívateľovi čo najrýchlejšie tým, že najprv vykreslí najkritickejšie časti HTML a CSS a vykonávanie JavaScript odloží na neskôr.

Rozhodnúť sa, ktorý JavaScript načítať s príznakom async a ktorý s defer a ktorý bez je veľmi dôležité.
Nesprávne nastavenie týchto atribútov môže dokonca viesť k nefunkčnosti stránky. Preto je dôležité zabezpečiť, aby všetky kritické súbory boli načítané správnym spôsobom a aby ste ich testovali na rôznych zariadeniach a prehliadačoch, aby ste sa uistili, že všetko funguje, ako má.

Rovnako, ako pri CSS, aj tu potrebujeme zistiť handle JavaScript súboru, pod ktorým bol registrovaný. …ako pri CSS, tak aj pri JavaScript je k handleru priradená prípona. V prípade skriptov to je -js.

Ak už máte všetky potrebné handleri a viete, ktorý kam bude patriť, použite ich v tomto snippete:

/**
 * Defer render blocking scripts
 * @param $tag
 * @param $handle
 * @param $src
 *
 * @return string
 *
 * url: https://wp-admin.sk/snippets/ako-nastavit-nacitavanie-javascriptu-aby-neblokovali-vykreslenie-stranky/
 * autor: PeterB aka Viking
 */
function viking_defer_blocking_scripts( $tag, $handle, $src ) {
	// overenie, aby sa naša funkcia, vykonala iba ak sme na frontende
	if( ! is_admin() ) {
		// handleri pre defer
		$defer = [ 'viking-script', 'viking-bootstrap', 'select-2', 'contact-form-7' ];
		// handleri pre async
		$async = [ 'skript-pre-async' ];
		// defer
		if( in_array( $handle, $defer ) ) {
			return '<script defer src="' . $src . '" id="' . $handle . '-js"></script>';
		// async
		} else if( in_array( $handle, $async ) ) {
			return '<script async src="' . $src . '" id="' . $handle . '-js"></script>';
		}
	}
	// vrátenie pôvodného tag-u, ak sa nenachádza v zozname pre defer a async
	return $tag;
}
add_filter( 'script_loader_tag', 'viking_defer_blocking_scripts', 10, 3 );

Použili sme filter script_loader_tag, ktorý nám poskytuje 3 premenné.

  • $tag – kompletný tag, generovaný WordPress-om
  • $handle – registrovaný pre tento JavaScript súbor
  • $src – url JavaScript súboru

V príklade použijeme 2 polia:

  • $defer – pole s handlermi pre skripty, ktorým sa má pridať atribút defer
  • $async – pole s handlermipre skripty, ktorým sa má pridať atribút async

Potom už iba za pomoci php in_array() funkcie, kontrolujeme či sa handler nachádza v našom poli a ak áno, vraciame nový tag s pridaným atribútom. Ak nedošlo k zhode ani v jednom prípade, vráti sa pôvodne vygenerovaný tag.

V tomto prípade, ešte raz upozorňujem, aby ste sa do úprav nepúšťali, ak neviete, čo robíte. …ak to chcete aj tak skúsiť, testujte to na zálohe a nie na živej stránke. Po každom prestavení, skontrolujte, či ste si nevyrobili chyby na stránke – môžte si tak znefunkčniť stránku. Ak by sa tie chyby neprejavili na funkčnosti stránky, môže vám to spomaliť stránku, znížiť skóre v nástroji PageSpeed Insights

Ďalšou možnosťou, je použiť plugin, ktorý to dokáže a ak už ideme optimalizovať, tak odporúčam WP Rocket, ktorý tieto oddialenia načítania CSS a asynchrónne nastavenie pre JavaScript má v sebe.


Tento snippet, patrí do functions.php, vašej aktuálnej témy.

Môžte pokračovať na článok: Ako oddialiť načítanie nekritických CSS

5 1 vote
Hodnotenie článku
Autor
Navigácia
Odoberať
Upozorniť na
guest
0 Komentáre
Inline Feedbacks
View all comments