web-dev-qa-db-fra.com

document.createElement ('script') vs <script src = "">

Pourquoi des services tels que Google et Facebook utilisent-ils document.createElement('script') au lieu de <script>?

Le fragment de code Google Analytics:

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

pourrait être écrit simplement:

<script src="//www.google-analytics.com/ga.js" type="text/javascript"></script>

et le bouton "J'aime" de Facebook:

<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1&appId=xxx";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

pourrait être simplifié comme suit:

<script src="//connect.facebook.net/en_GB/all.js#xfbml=1&appId=xxx"></script>

Je sais qu'il y en a qui jouent en toute sécurité, mais à part ça, je ne vois pas pourquoi on ne devrait pas utiliser le HTML5?

26
webjay

Le <script src=...> bloque le navigateur pendant que document.createElement('script') charge le JavaScript de manière asynchrone. c'est la raison principale.


La balise <script src=...> empêche le navigateur d'afficher le reste de la page jusqu'à ce que le script soit chargé et exécuté. Cela garantit que les scripts sont exécutés dans le bon ordre et que toutes les fonctions document.write() de ce script fonctionnent comme prévu. Cependant, cela crée une expérience de navigation lente pour l'utilisateur.

Lorsque le script est chargé de manière asynchrone, le navigateur peut télécharger le script sans bloquer l'affichage de la page. Cela améliore considérablement l'expérience de navigation.

Pour charger les scripts de manière asynchrone, on peut utiliser le balisage HTML:

<script src="..." async defer></script>

L'attribut async a été introduit dans HTML5, tandis que l'attribut defer peut être ajouté comme solution de secours pour les anciennes versions d'IE. Ce document décrit le fonctionnement des attributs asynchrone et différé .

Alternativement, on peut utiliser JavaScript pour créer une balise de script:

var s = document.createElement('script');
s.src = "...";
document.getElementsByTagName("head")[0].appendChild(s);

Les balises de script générées par JavaScript fonctionnent dans la plupart des navigateurs même s'ils ne comprennent pas l'attribut async ou la propriété .async = true.


À propos des URI sans schéma (//example.com/script.js): les URI sans schéma semblent fonctionner presque partout ( voir cette question ).

À propos de l'exemple de Google Analytics: l'ancien et le nouveau code utilisent JavaScript pour détecter le protocole, puis chargez http://www. ou https://ssl., ce qui n'est pas possible avec un balisage HTML.

29
Salman A

En plus de l'excellent argument de Salman A sur le chargement différé, cette technique est utilisée lorsque la solution statique ne fonctionne pas. 

  • Je l'ai vu utilisé lorsque la mise en cache est un problème (un hachage basé sur le temps unique est ajouté à l'URL)
  • Dans le cas du lien Google indiqué ci-dessus, SSL peut être activé de manière dynamique.
  • Dans le code facebook, il vérifie si le script existe déjà (cela peut éviter les bugs où le même script est chargé deux fois).

Il peut y avoir d'autres raisons aussi. Tous ont à voir avec le besoin d'une solution dynamique. 

2
Hogan

oui, cela peut être écrit dans une balise de script, mais les exemples que vous avez cités sont ceux où le site Web fournit à l'utilisateur un bloc de code qu'il doit copier et coller dans ses sites Web.
Donc, l'injection est préférable, car de cette façon, le site Web comme Google et Facebook

Comme vous pouvez le voir dans l’exemple googles que vous avez fourni, il détecte dynamiquement http OR https

2. De cette façon, les sites Web peuvent vérifier si le même script est présent, puis choisir de ne pas le télécharger à nouveau, comme dans l'exemple de Facebook

3. avoir plus de contrôle sur ce qui est injecté. le script en cours d’injection pouvant être modifié de façon dynamique sans que les utilisateurs soient obligés de modifier l’URL du script en cours d’injection, ce qui est nécessaire car de nombreux navigateurs conservent simplement les scripts dans le cache.

4.ainsi ces sites gardent leurs codes en ordre et moins sujets aux interférences des utilisateurs

0
Parv Sharma