Ja­vaScript: Pri­o­ri­ty sta­ho­vá­ní a spouš­tě­ní

Naposledy upraveno: 13. 3. 2019 – Autor: Martin Michálek

Navážu zde na výborný přehled od autorů Chrome a doplním jej dalšími postřehy.

Jak je to s prioritami JavaScriptu při různých způsobech vložení do stránky?

Způsob servírování Stahování Spouštění
1) <script> uvnitř <head> +++ ++++
2) <script type="module" async> +++ +++
3) <script async> ++ +++
4) <script defer> ++ +
5) <script> na konci <body> +++ ++
6) <script defer> na konci <body> + +

Tabulka přeložená do řeči prohlížeče: Priority stahování: +++ „Medium/High“, ++ „Lowest/Low“, + „Lowest/Low“ - na konci fronty. Priority spouštění: ++++ „VeryHigh“ - zablokuje parser, +++ „High“ - přeruší parser, ++ „Low“ - čeká na konec parsování, + „VeryLow“ - pouští se až po skriptech na konci HTML

Pojďme se teď na jednotlivé typy podívat podrobněji:

1) <script> uvnitř <head>

Nejvyšší priorita všeho a zablokování parsování dokumentu během stahování i spouštění. Taková ta klasika když chcete zabít rychlost webu.

V některých situacích je ale takhle vysoká priorita potřebná. Obecně se doporučuje pro skripty, které ovlivňují metriku první zobrazení obsahu (FMP) a zároveň renderují prvky nad zlomem stránky. Dále pro knihovny, které musejí předcházet jiným. Příklady:

  • Knihovny, které renderují obsah SPA (React, Angular, Vue…).
  • Polyfilly.
  • Detekční knihovny typu Modernizr.
  • Skripty pro A/B testing.

2) <script type="module" async>

Vysoká priorita stažení i spouštění, které přeruší HTML parser.

type="module" je poměrně nový. Jde o vkládání ECMAScript modulů do stránky. Vysvětluje to Jake Archibald a má to podporu všech moderních prohlížečů, když mezi ně nepočítáme Explorer. Ale fallback je možný.

Podle zdrojového článku je to vhodné pro skripty, které generují obsah pro FMP, který je až pod zlomem stránky. Nebo pro skripty, které stahují dynamický obsah. Příklad:

  • Vykreslení něčeho do <canvas>.

3) <script async>

Nízká priorita stažení. Spouštění má ale vysokou prioritu a přeruší HTML parser.

async skripty při stahování nepřeruší parsování stránky. Stahují se asynchronně v jiném vlákně a prohlížeč na ně tedy nečeká se zobrazením stránky. Jakmile je má ale stažené, spustí je okamžitě. To se ale může minimálně v Chrome změnit. Jeho autoři zvažují změnu spouštěcí priority těchto skriptů na nízkou.

Nevýhodou async skriptů je to, že není možné garantovat pořadí jejich provádění. Tohle nastavení není proto vhodné pro posílání knihoven a jejich závislostí v jednotlivých souborech.

Příklad použití:

  • Nemáte HTTP/2 a tedy šetříte dotazy na server. Všechny JS soubory sbalíte do jednoho a ten vyšlete jako async, aby vám neblokoval zobrazení stránky.

4) <script defer>

Nízká priorita stahování. Velmi nízká priorita spuštění – Chrome tyhle skripty pouští až po těch, které jsou na konci dokumentu.

Na rozdíl od async je u defer skriptů garantováno pořadí provedení, tyhle skripty mají navíc nízkou prioritu spouštění. Stahují se ale opět asynchronně, takže nám nezablokují zobrazení stránky.

V odkazovaném článku se obecně doporučuje použití pro skripty, které generují nekritický obsah nebo vlastnosti, které použije méně než polovina uživatelů webu. Zkusím ale raději nabídnout konkrétní příklad použití:

  • Obsah třetích stran, který není pro stránku nezbytný: Facebook pluginy, komentářové služby, reklamní skripty…

5) <script> na konci <body>

Vysoká priorita stahování. Spuštění po konci práce HTML parseru.

Jde o dobrý způsob, jak zrychlit zobrazení stránky díky tomu, že prohlížeč nemusí čekat na stažení JavaScriptu. Je ale dobré vědět, že všechny zde uvedené skripty budou mít vysokou prioritu stahování, takže vám můžou odložit důležitější prvky typu obrázků nutných pro zobrazení uživatelského rozhraní. Dobrý příklad použití je tento:

  • Servírování knihoven typu jQuery a jejich pluginů na prezentačních webech.

6) <script defer> na konci <body>

Nejnižší priorita stahování i spouštění.

Je to vhodné pro skripty, které zajišťují zřídka používané vlastnosti rozhraní stránky. Příklady:

  • Stažení podobných článků.
  • Widgety pro dávání zpětné vazby, zobrazení chatu s uživatelem a tak dále.

Pár poznámek k textu

  • Do prioritizace dále vstupuje <link rel="preload">, který maximalizuje prioritu stahování. Pokud jej nasadíte například v kombinaci se <script async>, dostanete vysokou prioritu stahování i spouštění.
  • Uvedená tabulka platí pro Chrome. Není jisté, že v jiných prohlížečích bude prioritizace fungovat stejně, i když v základech by to mělo být podobné.
  • Může se to změnit. Ostatně to je i důvod, proč v případě Chrome dokument vznikl. Autoři prohlížeče si v tom dělají pořádek. Vypadá to, že chtějí změnit spouštěcí prioritu async na nízkou, stejně tak v případě vkládání <script> na konec HTML.
  • V Chrome je možné priority stahování vidět ve vývojářských nástrojích v záložce Network.

Rada pro prezentační weby typu e-shopů

Nedá se to úplně snadno zobecnit, ale zkusím poradit alespoň vývojářům z webů, které stahují jQuery (nebo jinou knihovnu) a pak řadu navazujících pluginů nebo vlastních skriptů. Usiloval bych o následující:

  • Co nejméně skriptů v hlavičce HTML bez parametrů. Ty blokují zobrazení stránky.
  • Pokud máte nasazené HTTP/2, skripty pro danou stránku stahovat po samostatných souborech.
  • Zajistit, aby stránka se dokázala hezky zobrazit i bez JavaScriptu, alespoň na chvíli potřebnou pro jeho stažení a spuštění.
  • Vložit <script> buď s defer do hlavičky nebo bez parametru před uzavírací značku </body> v HTML dokumentu.

Komentáře