Prawdziwa odpowiedź brzmi: ponieważ nie możesz ufać odroczeniu.
W koncepcji odroczenia i asynchronizacji różnią się w następujący sposób:
async pozwala na pobranie skryptu w tle bez blokowania. Następnie, w momencie zakończenia pobierania renderowanie jest blokowane i skrypt jest wykonywany. Renderowanie zostanie wznowione po wykonaniu skryptu.
odroczenie robi to samo, z wyjątkiem roszczeń gwarantujących, że skrypty będą wykonywane w kolejności, w jakiej zostały określone na stronie, i że zostaną wykonane po zakończeniu analizy dokumentu. Dlatego niektóre skrypty mogą zakończyć pobieranie, a następnie usiąść i czekać na skrypty, które zostały pobrane później, ale pojawiły się przed nimi.
Niestety, ze względu na to, co tak naprawdę jest standardową walką kotów, definicja odroczenia różni się w zależności od specyfikacji, a nawet w najnowszych specyfikacjach nie daje użytecznej gwarancji. Jak pokazują odpowiedzi tutaj i ten problem , przeglądarki implementują odraczanie w inny sposób:
- W niektórych sytuacjach niektóre przeglądarki mają błąd, który powoduje, że
defer
skrypty nie działają.
- Niektóre przeglądarki opóźniają
DOMContentLoaded
zdarzenie do momentu defer
załadowania skryptów, a niektóre nie.
- Niektóre przeglądarki stosują
defer
się do <script>
elementów z wbudowanym kodem i bez src
atrybutu, a niektóre go ignorują.
Na szczęście specyfikacja przynajmniej określa, że asynchronizacja zastępuje odroczenie. Możesz więc traktować wszystkie skrypty jako asynchroniczne i uzyskać szeroki wachlarz obsługi przeglądarki w następujący sposób:
<script defer async src="..."></script>
98% przeglądarek używanych na całym świecie i 99% w USA uniknie blokowania przy takim podejściu.
(Jeśli musisz poczekać, aż dokument się zakończy parsowanie, wysłuchaj zdarzenia DOMContentLoaded
zdarzenia lub skorzystaj z przydatnej .ready()
funkcji jQuery . Chciałbyś to zrobić i tak, aby defer
w pełni zrezygnować z przeglądarki, która w ogóle się nie implementuje ).