- Pozycja ma znaczenie
- Async i defer
- Porównanie wydajności
- Bez defer lub async, w głowie
- Bez defer lub async, w ciele
- Z async, w głowie
- Z defer, w głowie
- Blokowanie parsowania
- Blokowanie renderowania
- domInteractive
- Utrzymywanie rzeczy w porządku
- Po prostu powiedz mi najlepszy sposób
Podczas ładowania skryptu na stronę HTML, musisz być ostrożny, aby nie zaszkodzić wydajności ładowania strony.
Skrypt jest tradycyjnie dołączany do strony w ten sposób:
<script src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
Gdy parser HTML znajdzie tę linię, zostanie wykonane żądanie pobrania skryptu, a skrypt zostanie wykonany.
Gdy ten proces jest zakończony, parsowanie może zostać wznowione, a reszta HTML może zostać przeanalizowana.
Jak można sobie wyobrazić, ta operacja może mieć ogromny wpływ na czas ładowania strony.
Jeśli załadowanie skryptu trwa trochę dłużej niż oczekiwano, na przykład jeśli sieć jest trochę wolna lub jeśli jesteś na urządzeniu mobilnym i połączenie jest trochę niechlujne, odwiedzający prawdopodobnie zobaczy pustą stronę, dopóki skrypt nie zostanie załadowany i wykonany.
Pozycja ma znaczenie
Gdy po raz pierwszy uczysz się HTML, powiedziano ci, że znaczniki skryptu znajdują się w znaczniku <head>
:
<html> <head> <title>Title</title> <script src="https://flaviocopes.com/javascript-async-defer/script.js"></script> </head> <body> ... </body></html>
Jak mówiłem wcześniej, gdy parser znajdzie tę linię, idzie pobrać skrypt i wykonuje go. Następnie, po wykonaniu tego zadania, przechodzi do parsowania ciała.
Jest to złe, ponieważ wprowadzane jest duże opóźnienie. Bardzo częstym rozwiązaniem tego problemu jest umieszczenie znacznika script
na dole strony, tuż przed zamykającym znacznikiem </body>
.
W ten sposób skrypt jest ładowany i wykonywany po tym, jak cała strona jest już sparsowana i załadowana, co jest ogromną poprawą w stosunku do alternatywy head
.
Jest to najlepsza rzecz, jaką możesz zrobić, jeśli musisz obsługiwać starsze przeglądarki, które nie obsługują dwóch stosunkowo niedawnych cech HTML: async
i defer
.
Async i Defer
Zarówno async, jak i defer są atrybutami typu boolean. Ich użycie jest podobne:
<script async src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
jeśli określisz oba, async
ma pierwszeństwo w nowoczesnych przeglądarkach, podczas gdy starsze przeglądarki, które obsługują defer
, ale nie async
, będą miały pierwszeństwo defer
.
Te atrybuty mają sens tylko wtedy, gdy używasz skryptu w head
części strony, i są bezużyteczne, jeśli umieścisz skrypt w body
stopce, jak widzieliśmy powyżej.
Porównanie wydajności
Bez defer lub async, w nagłówku
Oto jak strona ładuje skrypt bez defer lub async, umieszczony w head
części strony:
Parsowanie jest wstrzymywane aż do pobrania skryptu i wykonania go. Gdy to się stanie, parsowanie zostanie wznowione.
Bez defer lub async, w ciele
Oto jak strona ładuje skrypt bez defer lub async, umieszczony na końcu znacznika body
, tuż przed zamknięciem:
Parsowanie odbywa się bez żadnych przerw, a gdy się skończy, skrypt jest pobierany i wykonywany. Parsowanie jest wykonywane zanim jeszcze skrypt zostanie pobrany, więc strona pojawia się użytkownikowi dużo wcześniej niż w poprzednim przykładzie.
With async, in the head
Oto jak strona ładuje skrypt z async
, umieszczony w znaczniku head
:
Skrypt jest pobierany asynchronicznie, a gdy jest gotowy, parsowanie HTML jest wstrzymywane w celu wykonania skryptu, po czym jest wznawiane.
Z defer, w head
Oto jak strona ładuje skrypt z defer
, umieszczony w znaczniku head
:
Skrypt jest pobierany asynchronicznie, a jego wykonanie następuje dopiero po zakończeniu parsowania HTML.
Parsowanie kończy się tak samo jak wtedy, gdy umieścimy skrypt na końcu znacznika body
, ale ogólnie wykonanie skryptu kończy się dużo wcześniej, ponieważ skrypt został pobrany równolegle z parsowaniem HTML.
Więc to jest zwycięskie rozwiązanie pod względem szybkości 🏆
Blokowanie parsowania
async
blokuje parsowanie strony, podczas gdy defer
nie.
Blokowanie renderowania
Ani async
ani defer
nie gwarantują niczego w kwestii blokowania renderowania. To zależy od ciebie i twojego skryptu (na przykład, upewniając się, że twoje skrypty są uruchamiane po zdarzeniu onLoad
).
domInteractive
Skrypty oznaczone defer
są wykonywane zaraz po zdarzeniu domInteractive
, które ma miejsce po załadowaniu HTML, parsowaniu i zbudowaniu DOM.
CSS i obrazy w tym momencie nadal muszą być parsowane i ładowane.
Gdy to zostanie zrobione, przeglądarka wyemituje zdarzenie domComplete
, a następnie onLoad
.
domInteractive
jest ważne, ponieważ jego czas jest uznawany za miarę postrzeganej szybkości ładowania. Zobacz MDN, aby dowiedzieć się więcej.
Utrzymywanie rzeczy w porządku
Inny przypadek pro defer
: skrypty oznaczone async
są wykonywane w przypadkowej kolejności, gdy stają się dostępne. Skrypty oznaczone defer
są wykonywane (po zakończeniu parsowania) w kolejności, w jakiej zostały zdefiniowane w narzędziu.
Powiedz mi tylko najlepszy sposób
Najlepszą rzeczą do zrobienia, aby przyspieszyć ładowanie strony, gdy używasz skryptów, jest umieszczenie ich w head
i dodanie atrybutu defer
do twojego znacznika script
:
<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
To jest scenariusz, który wywołuje szybsze zdarzenie domInteractive
.
Rozważając zalety defer
, wydaje się lepszym wyborem niż async
w różnych scenariuszach.
Jeśli nie jesteś zadowolony z opóźnienia pierwszego renderowania strony, upewnij się, że gdy strona jest parsowana, JavaScript, który chcesz wykonać, jest już wykonany.
Ściągnij mój darmowy podręcznik JavaScript dla początkujących
Więcej poradników dotyczących przeglądarek:stronę opartą na CMS działającą w trybie offline
.
.