Que dois - defer
et async
moyenne?
Par défaut, un <script src=...></script>
balise est mal! Le navigateur doit mettre un terme à l'analyse du HTML jusqu'à ce que le script téléchargé et exécuté (depuis le script pourrait appeler document.write(...)
, ou de définir des variables globales qui, plus tard, des scripts dépendent). Cela signifie que toutes les images et feuilles de style qui sont après la balise de script de ne pas commencer le téléchargement jusqu'à ce que, une fois le script terminé le téléchargement et l'exécution. Des scripts externes généralement à rendre le Web se chargent beaucoup plus lentement, ce qui est pourquoi NoScript est devenu si populaire.
Microsoft a lancé defer
pour résoudre le problème. Si vous utilisez <script defer src=...></script>
, vous promets de ne pas appeler document.write(...)
. Un defer
script externe va commencer à télécharger immédiatement, mais ne s'exécute qu'après que la page est affichée. Après que la page a rendu, toutes defer
scripts sont exécutés dans le même ordre qu'ils ont été déclarés. Tous les navigateurs n'implémentent defer
encore.
HTML5 introduit l' async
attribut qui peut exécuter tout le temps-peut-être avant que la page a fini de l'analyse ou même avant les autres defer
/async
scripts qui sont encore en téléchargement. Mais il est plus difficile d'utiliser plusieurs async
scripts parce que leur ordre d'exécution n'est pas garanti. Comme defer
, tous les navigateurs n'implémentent async
encore.
Après tout, defer
et async
scripts ont exécuté, l' DOMContentLoaded
et load
événements feu.
Une brève histoire de l' defer
et async
- 1997 IE 4 introduit
defer
.
- 1998 spécification HTML 4 mentionne
defer
, mais malheureusement, il ne dit pas exactement quand defer
exécution des scripts (Tous dans l'ordre? Avant d' onload
?). Donc, pas d'autres navigateurs defer
parce que personne ne veut l'ingénierie inverse sur IE comportement ou briser des scripts qui peut dépendre d'IE particularités. (Voir la Mozilla demande de fonctionnalité, par exemple).
- 2006 HTML5 projet, enfin, décrit les détails nécessaires pour mettre en oeuvre
defer
: defer
scripts doivent toutes être exécutées dans l'ordre après le reste de la page est analysée, et avant d' onload
. Il introduit également async
pour spécifier les scripts qui peut s'exécuter à chaque fois qu'ils sont téléchargés sans avoir à attendre les uns des autres. Malheureusement, HTML5 contredit IE en ne permettant pas inline defer
scripts. Cela rompt l'invariant que tous defer
scripts sont exécutés dans l'ordre (si certains defer
scripts ont src
et certains ont du contenu en ligne).
- 2009 Gecko 1.9.1 (Firefox 3.5) soutient
defer
.
- 2010-01 Gecko 1.9.2 (Firefox 3.6) soutient
async
.
- 2010-09
defer
et async
sont enregistrés dans Webkit. Vous devriez le voir dans Chrome et Safari très bientôt (elle est déjà dans le Chrome dev canal, mais il est un peu buggé).
- Nous sommes toujours en attente pour l'Opéra de mettre en œuvre
defer
et async
et pour IE à mettre en oeuvre async
.
Alors, que devez-un développeur web utiliser?
Il n'y a pas une seule règle à suivre en ce moment. Vous avez à choisir la solution la mieux des soldes de la simplicité, de la page de rendu de la latence et de l'exécution du script de latence pour l'ensemble des navigateurs qui accèdent à votre site web.
- Le moyen le plus simple pour avoir la page de rendu avant l'exécution des scripts, comme d'autres l'ont souligné, est de mettre vos scripts en bas de la page. Mais si les scripts sont essentiels, ou la page web contient beaucoup de code HTML, alors vous devriez mettre vos scripts plus haut sur la page.
- Si votre script est autonome et de vos clients à utiliser IE ou de nouvelles versions de Firefox, utilisez
<script async defer src=...></script>
: Cela permet de rendu de continuer en parallèle à écrire le script de téléchargement pour IE et les derniers navigateurs HTML5, mais des causes pré-HTML5 dans les navigateurs (y compris toutes les versions de l'Opéra) à bloc.
- Si un script externe dépend d'un autre, de les marquer à la fois
defer
(mais pas async
) et ils seront exécutés dans l'ordre où ils ont été déclarés. Encore une fois, cela permet de rendu de continuer en parallèle à un script de téléchargement en IE et HTML5-conscient Gecko/Webkit, mais les anciens navigateurs et de l'Opéra en souffrira. C'est une bonne idée d'utiliser defer
même si les scripts sont au bas de la page afin qu'ils téléchargent en parallèle les uns avec les autres.
- N'utilisez jamais d'
defer
pour les scripts parce que le HTML5, le projet a pris de l'ordonnance d'exécution de la garantie.
- Si votre auditoire comprend de nombreux Opéra ou vieux Firefox/les utilisateurs de Safari, le fragment de code suivant va exécuter le script après l'analyse du document sur la plupart des navigateurs HTML5 (c'est à dire, Webkit, besoin de tester vieux Firefox), tandis que le nouveau HTML5-connaissance des navigateurs commencer à télécharger immédiatement, mais ne les empêcheront pas d'exécuter le script en raison de l'
async
d'attribut. En d'autres termes, la plupart des navigateurs plus anciens, c'est un script en bas de la page, et les navigateurs les plus récents reconnaître l' async
. Mais les utilisateurs de Opera obtenir le pire des deux mondes, parce que l'Opéra commence l'exécution immédiatement et de ne pas comprendre async
. C'est le modèle recommandé par Google Analytics pour l'oursin sur de nombreuses pages web.
extrait:
<script>
(function() {
var script = document.createElement('script');
script.src = '...';
script.async = true;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(script, s);
})();
</script>
- Si un autre script dépend du premier script à charger, alors vous pouvez utiliser le même modèle que ci-dessus, mais d'écouter l'événement onload de la premier élément de script avant l'exécution de la deuxième script. Voir la LABjs exemple de comment attendre pour un autre script à charger.
- Si vous avez plusieurs scripts avec dépendances complexes, l'utilisation LAB.js ou le YUI Chargeur pour rendre le téléchargement en parallèle et de les exécuter dans certains de commande valide.
- Si vous utilisez une bibliothèque populaire tels que jQuery, pensez à utiliser Google copie plutôt que sur votre propre afin d'augmenter la probabilité que le navigateur a déjà mises en cache.
Mise à jour: Si vous avez des scripts divisé en modules et souhaitez améliorer les performances, je recommande le "Couplage Asynchrone Scripts" de Même plus Rapide des Sites Web par Steve Souder. Il contient des conseils/astuces pour non seulement le contrôle de l'exécution de l'ordre, mais aussi de retarder l'analyse de scripts pour améliorer les performances.