Script Tag-async & defer

Mam kilka pytań odnośnie atrybutów async & defer dla tagu <script>, który według mnie działa tylko w przeglądarkach HTML5.

Jedna z moich stron ma dwa zewnętrzne pliki JavaScript, które obecnie znajdują się tuż nad tagiem </body>; pierwszy to jquery pochodzące z google, a drugi to lokalny skrypt zewnętrzny.

W odniesieniu do prędkości ładowania strony

  1. Czy jest jakaś zaleta w dodaniu async do dwóch skryptów I masz na dole strony?

  2. Czy jest jakaś zaleta w dodaniu opcji async do dwóch skryptów i umieszczeniu ich na górze strony w <head>?

  3. Czy to oznacza, że pobierają się podczas ładowania strony?

  4. Zakładam, że spowoduje to Opóźnienia dla przeglądarek HTML4, ale czy przyspieszy to ładowanie strony dla przeglądarek HTML5?

Używanie <script defer src=...

  1. ładuje dwa skrypty wewnątrz <head> z atrybutem defer taki sam wpływ jak posiadanie skryptów przed </body>?
  2. po raz kolejny zakładam, że spowolni to przeglądarki HTML4.

Użycie <script async src=...

Jeśli mam dwa skrypty z async włączone

  1. czy pobierają w tym samym czasie?
  2. czy pojedynczo z resztą strony?
  3. czy kolejność skryptów staje się problemem? Na przykład jeden skrypt zależy od drugiego, więc jeśli jeden pobierze się szybciej, drugi może niepoprawne wykonanie itp.

Wreszcie czy najlepiej zostawić rzeczy takie, jakie są, dopóki HTML5 nie będzie częściej używany?

Author: Community, 2012-05-29

10 answers

Zachowaj swoje skrypty tuż przed </body>. Async może być używany ze skryptami znajdującymi się tam w kilku okolicznościach(patrz dyskusja poniżej). Defer nie zrobi dużej różnicy dla skryptów znajdujących się tam, ponieważ praca parsowania DOM i tak już została wykonana.

Oto artykuł, który wyjaśnia różnicę między async i defer: http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/.

Twój HTML wyświetli się szybciej w starszych przeglądarkach skrypty są przechowywane na końcu ciała tuż przed </body>. Tak więc, aby zachować prędkość ładowania w starszych przeglądarkach, nie chcesz umieszczać ich nigdzie indziej.

Jeśli twój drugi skrypt zależy od pierwszego skryptu( np. twój drugi skrypt używa jQuery załadowanego w pierwszym skrypcie), to nie możesz uczynić ich asynchronicznymi bez dodatkowego kodu do kontrolowania kolejności wykonania, ale możesz je odroczyć, ponieważ skrypty odroczenia będą nadal wykonywane w kolejności, tylko dopiero po tym, jak dokument został przetworzony. Jeśli masz ten kod i nie potrzebujesz skryptów do uruchomienia od razu, możesz je asynchronizować lub odroczyć.

Możesz umieścić skrypty w znaczniku <head> i ustawić je na defer, A ładowanie skryptów zostanie odroczone do momentu parsowania DOM, co spowoduje szybkie wyświetlanie strony w nowych przeglądarkach, które obsługują defer, ale nie pomoże Ci to w ogóle w starszych przeglądarkach i nie jest tak naprawdę szybsze niż umieszczenie skryptów tuż przed </body>, które działa we wszystkich przeglądarkach. Więc możesz zobaczyć, dlaczego po prostu najlepiej umieścić je tuż przed </body>.

Asynchronizacja jest bardziej przydatna, gdy naprawdę nie obchodzi cię, kiedy skrypt się ładuje i nic innego, co jest zależne od użytkownika, nie zależy od ładowania tego skryptu. Najczęściej cytowanym przykładem korzystania z async jest skrypt analityczny, taki jak Google Analytics, na który nie chcesz nic czekać i nie jest pilne, aby szybko uruchomić i stoi sam, więc nic innego nie zależy od niego.

Zwykle jQuery biblioteka nie jest dobrym kandydatem do asynchronizacji, ponieważ Inne skrypty zależą od niej i chcesz zainstalować programy obsługi zdarzeń, aby Twoja Strona mogła zacząć odpowiadać na zdarzenia użytkownika i może być konieczne uruchomienie kodu inicjującego opartego na jQuery, aby ustalić początkowy stan strony. Może być używany asynchronicznie, ale Inne skrypty będą musiały być zakodowane, aby nie wykonać dopóki jQuery nie zostanie załadowany.

 429
Author: jfriend00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-09 05:04:24

Ten obrazek wyjaśnia tag zwykłego skryptu, async i defer

Tutaj wpisz opis obrazka

  • Skrypty asynchroniczne są wykonywane zaraz po załadowaniu skryptu, więc nie gwarantuje kolejności wykonania (skrypt zawarty w koniec może zostać wykonany przed pierwszym plikiem skryptu)

  • Defer Skrypty gwarantuje kolejność wykonania w jakiej się pojawiają na stronie.

Ref this link : http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

 945
Author: Prasanth Bendra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-27 08:51:01

HTML5: async, defer

W HTML5, można powiedzieć przeglądarce, kiedy uruchomić kod JavaScript. Są 3 możliwości:

<script       src="myscript.js"></script>

<script async src="myscript.js"></script>

<script defer src="myscript.js"></script>
  1. Bez async lub defer, przeglądarka uruchomi skrypt natychmiast, przed renderowaniem elementów znajdujących się pod znacznikiem skryptu.

  2. Za pomocą async (asynchronicznego) przeglądarka będzie nadal ładować stronę HTML i renderować ją, podczas gdy przeglądarka będzie ładować i wykonywać skrypt w tym samym czasie.

  3. Z defer, przeglądarka uruchomi skrypt po zakończeniu parsowania strony. (nie jest konieczne kończenie pobierania wszystkich plików graficznych. To jest dobre.)

 227
Author: Dinesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-19 15:26:42

Zarówno Skrypty async, jak i defer zaczynają pobierać się natychmiast, bez zatrzymywania parsera i oba obsługują opcjonalną obsługę onload, aby zaspokoić powszechną potrzebę inicjalizacji, która zależy od skryptu.

Różnica pomiędzy async i defer skupia się wokół momentu wykonania skryptu. Każdy skrypt async jest wykonywany przy pierwszej okazji po zakończeniu pobierania i przed wydarzeniem load okna. Oznacza to, że jest możliwe (i prawdopodobne), że async skrypty nie są wykonane w kolejności, w jakiej występują na stronie. Natomiast Skrypty defer mają gwarancję wykonania w kolejności, w jakiej występują na stronie. Wykonanie rozpoczyna się po całkowitym zakończeniu analizy, ale przed zdarzeniem DOMContentLoaded dokumentu.

Źródło i dalsze szczegóły: tutaj .

 38
Author: Zameer Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-18 11:02:03

W obliczu tego samego rodzaju problemu i teraz wyraźnie zrozumiał, jak działa oba will.Mam nadzieję, że ten link referencyjny będzie pomocny...

Async

Po dodaniu atrybutu async do znacznika script, nastąpią następujące czynności.

<script src="myfile1.js" async></script>
<script src="myfile2.js" async></script>
  1. wykonaj równoległe żądania pobierania plików.
  2. Kontynuuj przetwarzanie dokumentu tak, jakby nigdy nie został przerwany.
  3. wykonywanie poszczególnych skryptów w momencie, gdy pliki są ściągnięty.

Defer

Defer jest bardzo podobny do asynchronicznego z jedną główną różnicą. Oto, co się dzieje, gdy przeglądarka napotka skrypt z atrybutem defer.

<script src="myfile1.js" defer></script>
<script src="myfile2.js" defer></script>
  1. wykonuj równoległe żądania, aby pobrać poszczególne pliki.
  2. Kontynuuj przetwarzanie dokumentu tak, jakby nigdy nie został przerwany.
  3. Zakończ analizowanie dokumentu, nawet jeśli pliki skryptów zostały pobrane.
  4. wykonaj każdy skrypt w kolejność ich napotkania w dokumencie.

Odniesienie: różnica między Asynchronią a Defer

 36
Author: kamesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-12 07:16:14

async i defer pobierze plik podczas parsowania HTML. Oba nie przerwą parsera.

  • Skrypt z atrybutem async zostanie wykonany po jego pobraniu. Podczas gdy skrypt z atrybutem defer zostanie wykonany po zakończeniu parsowania DOM.

  • Skrypty załadowane async nie gwarantują żadnego porządku. Podczas gdy Skrypty załadowane atrybutem defer zachowują kolejność w jakiej pojawiają się na DOM.

Użyj <script async>, gdy skrypt na niczym nie polega. gdy skrypt zależy używać <script defer>.

Najlepszym rozwiązaniem byłoby dodanie <script> na dole ciała. Nie będzie problemu z blokowaniem lub renderowaniem.

 13
Author: NavyaKumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-11 18:50:02

Myślę, że Jake Archibald przedstawił nam kilka spostrzeżeń w 2013 roku, które mogą dodać jeszcze więcej pozytywności do tematu:]}

Https://www.html5rocks.com/en/tutorials/speed/script-loading/

Święty Graal wymaga natychmiastowego pobrania zestawu skryptów bez blokowania renderowania i jak najszybszego wykonania w kolejności, w jakiej zostały dodane. Niestety HTML cię nienawidzi i nie pozwoli Ci na to.

(...)

Odpowiedź jest rzeczywiście w Specyfikacja HTML5, chociaż jest ukryta na dole sekcji ładowania skryptów. "atrybut asynchroniczny IDL kontroluje, czy element będzie działał asynchronicznie, czy nie. Jeśli ustawiony jest znacznik "force-async", to przy pobieraniu atrybut async IDL musi zwracać true, a przy ustawieniu znacznik "force-async" musi być najpierw unset...".

(...)

Skrypty dynamicznie tworzone i dodawane do dokumentu są domyślnie asynchroniczne , nie Zablokuj renderowanie i wykonaj natychmiast po pobraniu, co oznacza, że mogą wyjść w złej kolejności. Jednak możemy je wyraźnie oznaczyć jako nie asynchroniczne:

[
    '//other-domain.com/1.js',
    '2.js'
].forEach(function(src) {
    var script = document.createElement('script');
    script.src = src;
    script.async = false;
    document.head.appendChild(script);
});

Daje to naszym skryptom mieszankę zachowań, których nie można osiągnąć za pomocą zwykłego HTML. Jako jawnie nie asynchroniczne, skrypty są dodawane do kolejki wykonywania, tej samej kolejki, do której są dodawane w naszym pierwszym przykładzie zwykłego HTML. Jednak poprzez dynamiczne tworzenie, są one wykonywane poza parsowaniem dokumentów, więc renderowanie nie jest blokowane podczas pobierania (nie myl ładowania skryptów nie asynchronicznych z sync XHR, co nigdy nie jest dobre).

Powyższy skrypt powinien być umieszczony w nagłówku strony, w kolejce do pobrania skryptu tak szybko, jak to możliwe, bez zakłócania progresywnego renderowania, i wykonywany tak szybko, jak to możliwe w podanej kolejności. "2.js " można pobrać za darmo przed "1.js", ale zostanie wykonana dopiero " 1.js" został pomyślnie pobrany i wykonany, lub nie robi ani jednego, ani drugiego. Hurra! asynchroniczne pobieranie, ale zlecone wykonanie !

Mimo to może to nie być najszybszy sposób na wczytanie skryptów:

(...) W powyższym przykładzie przeglądarka musi przeanalizować i wykonać skrypt, aby dowiedzieć się, które Skrypty należy pobrać. Spowoduje to ukrycie skryptów przed skanerami do ładowania wstępnego. Przeglądarki używają tych skanerów do odkrywania zasobów na stronach, które prawdopodobnie odwiedzisz obok, lub odkrywania zasobów Strony, gdy parser jest zablokowany przez inny zasoby.

Możemy dodać wykrywalność z powrotem, umieszczając to w nagłówku dokumentu:

<link rel="subresource" href="//other-domain.com/1.js">
<link rel="subresource" href="2.js">

To mówi przeglądarce, że strona potrzebuje 1.js i 2.js. link [rel=subresource] jest podobny do link [rel=prefetch], ale z inną semantyką. Niestety jest on obecnie obsługiwany tylko w Chrome i musisz zadeklarować, które Skrypty ładować dwa razy, raz za pomocą elementów łącza i ponownie w swoim skrypcie.

Korekta: zostały wychwycone przez skaner, nie są, są wychwycone przez zwykły parser. Jednak skaner preload może je odebrać, po prostu jeszcze tego nie robi, podczas gdy Skrypty zawarte w kodzie wykonywalnym nigdy nie mogą być wstępnie załadowane. Dzięki Yoavowi Weissowi, który poprawił mnie w komentarzach.

 5
Author: mjfneto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-13 21:51:05

Wydaje się, że zachowanie defer i async jest zależne od przeglądarki, przynajmniej od fazy wykonania. Uwaga, defer dotyczy tylko zewnętrznych skryptów. Zakładam, że asynchronizacja przebiega według tego samego schematu.

W IE 11 i poniżej kolejność wygląda następująco:

  • async (może częściowo wykonać podczas ładowania strony)
  • none (można wykonać podczas ładowania strony)
  • defer (wykonuje po załadowaniu strony, wszystkie defer w kolejności umieszczenia w pliku)

In Edge, Webkit, etc, atrybut async wydaje się być ignorowany lub umieszczony na końcu:

    Data-pagespeed-no-defer (uruchamia się przed innymi skryptami, podczas ładowania strony)
  • none (można wykonać podczas ładowania strony)
  • defer (czeka aż DOM załadowany, wszystkie defer w kolejności umieszczenia w pliku)
  • async (wydaje się czekać, aż DOM załadowany)

W nowszych przeglądarkach atrybut data-pagespeed-no-defer działa przed innymi zewnętrznymi skryptami. To jest dla skryptów, które nie zależy od DOM.

Uwaga: użyj defer, gdy potrzebujesz wyraźnej kolejności wykonywania zewnętrznych skryptów. To mówi przeglądarce, aby wykonała wszystkie odroczone skrypty w kolejności umieszczenia w pliku.

Na bok: rozmiar zewnętrznych skryptów JavaScript miał znaczenie podczas ładowania...ale nie miało to wpływu na kolejność egzekucji.

Jeśli martwisz się o wydajność swoich skryptów, możesz rozważyć minifikację lub po prostu załadować je dynamicznie za pomocą XMLHttpRequest.

 1
Author: Charles Owen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-28 02:01:05

Silnik renderujący przechodzi kilka kroków, aż maluje cokolwiek na ekranie.

Wygląda tak:

  1. Konwersja bajtów HTML na znaki w zależności od kodowania ustawionego na dokument;
  2. tokeny są tworzone według znaków. Tokeny oznaczają analizowanie znaków i określanie Tang otwierających i zagnieżdżonych znaczników;
  3. z tokenów tworzone są oddzielne węzły. są obiektami i zgodnie z informacjami dostarczonymi z procesu tokenizacji, engine tworzy obiekty który zawiera wszystkie niezbędne informacje o każdym węźle;
  4. Po tym DOM jest tworzony. DOM jest strukturą danych drzewa i reprezentuje całą hierarchię oraz informacje o relacjach i specyfikacji znaczników;

Ten sam proces przechodzi do CSS. dla CSS rendering engine tworzy inną / oddzieloną strukturę danych dla CSS, ale nazywa się CSSOM (CSS Object Model)

Przeglądarka działa tylko z modelami obiektowymi, więc musi znać wszystkie informacje o DOM i CSSDOM.

The następnym krokiem jest połączenie jakoś DOM i CSSOM. ponieważ bez CSSOM browser Nie wiem, jak stylizować każdy element podczas procesu renderowania.

Wszystkie powyższe informacje oznaczają, że wszystko, co podasz w swojej przeglądarce html (javascript, css), wstrzyma proces budowy DOM. Jeśli znasz pętlę zdarzeń, istnieje prosta zasada jak pętla zdarzeń wykonuje zadania:

  1. wykonywanie zadań makro;
  2. wykonuj mikro zadania;
  3. Rendering;

Więc kiedy podasz Plik Javascript, przeglądarka nie wie, co zrobi kod JS i zatrzymuje cały proces budowy DOM i Javascript interptreter rozpoczyna parsowanie i wykonywanie kodu Javascript.

Nawet jeśli podasz Javascript na końcu tagu body, przeglądarka przejdzie wszystkie powyższe kroki do HTML i CSS, ale z wyjątkiem renderowania. znajdzie znacznik skryptu i zatrzyma się, dopóki JS nie zostanie zakończony.

Ale HTML dostarczył dwie dodatkowe opcje dla znacznika script: async i defer.

Async-oznacza wykonanie kodu po pobraniu i nie blokuj budowy DOM podczas procesu pobierania.

Defer-oznacza wykonanie kodu po jego pobraniu i zakończeniu budowy i renderowania przez przeglądarkę DOM.

 0
Author: Alexander Gharibashvili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-06 09:16:53

Async jest odpowiedni, jeśli twój skrypt nie zawiera manipulacji DOM I Inne skrypty nie zależą od tego. Np: Bootstrap cdn, jquery

Defer jest odpowiedni, jeśli twój skrypt zawiera manipulację DOM i od tego zależą Inne skrypty.

Eg: <script src=”createfirst.js”> //let this will create element <script src=”showfirst.js”> //after createfirst create element it will show that.

W ten sposób zrobić: Eg: <script defer src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will

Spowoduje to wykonanie skryptów w kolejności.

Ale jeśli zrobiłem: Eg: <script async src=”createfirst.js”> //let this will create element <script defer src=”showfirst.js”> //after createfirst create element it will

Wtedy ten kod może przynieść nieoczekiwane rezultaty. Coz: jeśli dostęp do parsera html createfirst script.It nie zatrzyma tworzenia DOM i rozpoczyna pobieranie kodu z src .Gdy src został rozwiązany / kod został pobrany, będzie działać natychmiast równolegle z DOM.

Co jeśli pokażesz pierwszy.js wykonać pierwszy niż createfirst.js.Może to być możliwe, jeśli createfirst zajmuje dużo czasu (Załóżmy po zakończeniu parsowania DOM).Następnie showfirst uruchomi się natychmiast.

 0
Author: Sundar Gautam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-28 11:30:10