Chargement de script facile avec yepnope.js

Publié officiellement par Alex Sexton et Ralph Holzmann à la fin du mois de février 2011, le chargeur de ressources yepnope.js propose un chargement conditionnel asynchrone et un préchargement de ressources JavaScript et CSS. Cela facilite grandement la gestion du code conditionnel dépendant.

Tutoriel republié

Toutes les quelques semaines, nous revoyons certains des articles préférés de nos lecteurs tout au long de l'histoire du site. Ce tutoriel a été publié pour la première fois en mars 2011..

Ce chargeur de ressources astucieux, qui ne contient que 1,6 Ko de fichiers chiffrés et compressés, est désormais fourni avec Modernizer et est idéal pour charger des polyfills, précharger ou "amorcer" le cache des utilisateurs, ou comme simple chargeur / filtre de ressources asynchrones!

Pour ceux d'entre vous qui ne sont pas familiers avec les polyfill, ce sont essentiellement des plug-ins, ou des shims, qui permettent l'utilisation de technologies nouvelles ou futures dans des navigateurs plus anciens, par exemple. bases de données web sql, transformations CSS3, etc..

Yepnope prend désormais également en charge un certain nombre de préfixes et de filtres qui, lorsqu'ils sont ajoutés à l'URL de la ressource, ajoutent une couche d'optimisation supplémentaire à sa fonctionnalité principale. Comme si ce n'était pas déjà génial, yepnope vous fournit également un mécanisme pour définir vos propres préfixes et filtres. Jetons un coup d'oeil à ce que yepnope.js peut faire!


Arrière-plan - Chargement de script asynchrone

Avant de nous intéresser à yepnope et à ses fonctionnalités, il est important de comprendre un peu le fonctionnement du chargement de script asynchrone, son utilité et sa différence avec le chargement de script vanilla..

Les chargeurs asynchrones suppriment la nature intrinsèque de blocage d'un script.

En règle générale, les fichiers JavaScript chargés avec le > tag, bloque le téléchargement des ressources ainsi que le rendu des éléments dans la page Web. Ainsi, même si la plupart des navigateurs modernes ont tendance à prendre en charge le téléchargement parallèle de fichiers JavaScript, le téléchargement des images et le rendu des pages doivent encore attendre le chargement des scripts. À son tour, la durée pendant laquelle un utilisateur doit attendre que la page s’affiche augmente..

C'est ici que les chargeurs asynchrones entrent en jeu. En utilisant l'une des différentes techniques de chargement, ils suppriment la nature de blocage inhérente d'un script, ce qui permet le téléchargement en parallèle des scripts JavaScripts et des ressources sans interférer avec le rendu de la page. Dans de nombreux cas, cela peut réduire - parfois considérablement - les temps de chargement des pages.

La plupart des chargeurs conservent l'ordre dans lequel les scripts sont exécutés tout en fournissant un rappel lorsque le script est chargé et prêt..

Le chargement asynchrone ne vient pas sans ses mises en garde. Lorsque les scripts sont chargés de manière traditionnelle, le code en ligne n'est pas analysé ni exécuté tant que les scripts externes ne sont pas complètement chargés, de manière séquentielle. Ce n'est pas le cas avec le chargement asynchrone. En fait, les scripts en ligne analysent / exécutent généralement tandis que les scripts sont toujours en cours de téléchargement. De la même manière, le navigateur télécharge également des ressources et affiche la page au fur et à mesure du chargement des scripts. Ainsi, nous pouvons arriver à des situations où du code en ligne, qui dépend peut-être d'un script / d'une bibliothèque en cours de chargement, est exécuté avant que sa dépendance ne soit prête ou avant / après que le DOM lui-même soit prêt. En tant que tels, la plupart des chargeurs conservent l'ordre dans lequel les scripts sont exécutés tout en fournissant un rappel pour le moment où le script est chargé et prêt. Cela nous permet d'exécuter n'importe quel code en ligne dépendant en tant que rappel, éventuellement dans un wrapper DOM ready, le cas échéant..

De plus, lorsqu'il s'agit d'une petite page ou d'une page bien optimisée, le DOM peut être prêt ou même chargé avant que le chargement des scripts ne soit terminé! Ainsi, si la page en question n'est pas progressivement améliorée, en ce sens qu'elle s'appuie fortement sur JavaScript pour le style, il peut y avoir un FOUC ou un flash de contenu non stylé. De même, les utilisateurs peuvent même rencontrer un bref FUBC ou un flash de contenu non comportementé. Il est important de garder ces éléments à l'esprit lorsque vous utilisez un chargeur de scripts / ressources..


Étape 1 - Le yepnope Objet de test

le yepnope L'objet de test possède sept propriétés de base, toutes optionnelles. Cet objet inclut le test réel, les ressources qui seront chargées à la suite du test, les ressources qui seront chargées quel que soit le test ainsi que les rappels. Voici un aperçu des accessoires de l'objet de test yepnope:

  • tester:

    Un booléen représentant la condition que nous voulons tester.

  • oui:

    Une chaîne ou un tableau / objet de chaînes représentant les URL des ressources à charger si le test est la vérité.

  • Nan:

    Une chaîne ou un tableau / objet de chaînes représentant les URL des ressources à charger si le test est Falsey.

  • charge:

    Une chaîne ou un tableau / objet de chaînes représentant les URL des ressources à charger, quel que soit le résultat du test..

  • tous les deux:

    Une chaîne ou un tableau / objet de chaînes représentant les URL des ressources à charger, quel que soit le résultat du test. Ceci est, fondamentalement, le sucre syntaxique car sa fonction est généralement la même que celle du charge une fonction.

  • rappeler:

    Une fonction qui sera appelée pour chaque ressource comme il est chargé séquentiellement.

  • Achevée:

    Une fonction qui s'appellera une fois que quand toutes les ressources ont été chargées.

Maintenant, pour avoir une idée de la syntaxe, jetons un coup d’œil à l’utilisation la plus simple possible de yepnope: charger une seule ressource.

 yepnope ('resources / someScript.js');

… Ou peut-être charger un tableau de ressources.

 yepnope (['resources / someScript.js', 'resources / someStyleSheet.css']);

Que diriez-vous d'un littéral d'objet afin que nous puissions utiliser des rappels nommés plus tard?

 yepnope ('someScript': 'resources / someScript.js', 'someStyleSheet': 'resources / someStyleSheet.css');

Rappelez-vous que ces ressources seront chargées de manière asynchrone pendant le téléchargement et le rendu de la page..


Étape 2 - Conditions - Tester les caractéristiques de l'avenir!

Nous pouvons donc charger les ressources de manière asynchrone! C'est formidable, mais que se passe-t-il si certaines pages ne nécessitent pas une certaine ressource? Ou, que se passe-t-il si une ressource n'est nécessaire que dans un navigateur particulier qui ne prend pas en charge une nouvelle technologie de pointe??

Aucun problème! C’est là que l’objectif sous-jacent de Yepnope est mis au point. En utilisant la propriété test, nous pouvons charger des ressources de manière conditionnelle en fonction des besoins. Par exemple, supposons que la bibliothèque Modernizer soit chargée.

Pour ceux d'entre vous qui ne connaissent pas Modernizer, il s'agit d'une suite de tests astucieuse utilisée pour détecter le support des fonctionnalités HTML5 et CSS3 dans les navigateurs..

Modernizer ajoute les noms de classe appropriés aux pages html élément représentant les fonctionnalités prises en charge et non prises en charge, par ex. "js flexbox no-canvas"etc. En outre, vous pouvez accéder à chacun des tests Modernizer, qui renvoient des valeurs booléennes, individuellement, dans votre code.

Donc, en utilisant Modernizer, testons hashchange support d'événements et support d'historique de session!

Voici un aperçu de notre test:

 yepnope (test: Modernizr.hashchange && Modernizr.history);

Ce test reviendra bien sûr vrai uniquement si le navigateur prend en charge ces deux fonctionnalités.


Étape 3 - Chargement conditionnel des ressources

Avec notre ensemble de conditions de test, nous allons maintenant définir les ressources à charger en fonction du résultat de ce test. En d’autres termes, si vous ne devez charger une ressource spécifique que si le navigateur manque une fonctionnalité ou si le test échoue, vous pouvez simplement définir cette ressource dans le menu déroulant. Nan clause. Inversement, vous pouvez charger des ressources lorsque le test réussit, dans le oui clause.

Donc, en supposant que le navigateur ne supporte pas l’une de ces deux fonctionnalités, nous allons charger le plugin jQuery hashchange de Ben Alman, qui permet hashchange et prise en charge de l'historique dans les anciens navigateurs qui ne prennent en charge aucune de ces fonctionnalités.

Chargeons le plugin hashchange:

 yepnope (test: Modernizr.hashchange && Modernizr.history, nope: 'resources / jquery.ba-hashchange.js');

Dans l'exemple ci-dessus, nous n'utiliserons pas le oui la propriété que nous fournissons seulement une cale en cas de besoin.

Pour illustrer le oui Cependant, testons la prise en charge de la transformation CSS3, puis chargeons une feuille de style pour les navigateurs prenant en charge les transformations et une feuille de style vanilla pour les navigateurs qui ne le font pas. De plus, nous chargerons un plugin jQuery qui imite également les transformations CSS3..

Utilisant à la fois oui et non:

 yepnope (test: Modernizr.csstransforms, yep: 'resources / cssTransform.css' nope: ['resources / noTransform.css', 'jQuery.pseudoTransforms.js']);

Notez que ces deux exemples chargeront toutes les ressources de manière asynchrone à mesure que le reste de la page sera téléchargé et rendu.!


Étape 4 - Chargement des ressources indépendamment de la condition de test

Yepnope fournit également un moyen de charger des ressources indépendamment des résultats du test par le biais de la charge propriété. le charge la fonction chargera toujours les ressources qu’elle alimentera, quel que soit le tester résultat. De même, le tous les deux prop, qui est, encore une fois, essentiellement du sucre syntaxique, charge également des ressources, quel que soit le résultat du test ou, plus précisément, sur l'un ou l'autre résultat.

Chargement par défaut:

 yepnope (test: Modernizr.hashchange && Modernizr.history, nope: 'resources / jquery.ba-hashchange.js', load: 'resources / quelquechosequi a toujoursLoaded.css',);

Chargement sur les deux conditions, sucre syntaxique:

 yepnope (test: Modernizr.hashchange && Modernizr.history, nope: 'resources / jquery.ba-hashchange.js', les deux: 'resources / quelquechosequi a toujoursLoaded.css',);

Dans les deux exemples ci-dessus, les ressources seront chargées, de manière asynchrone, quel que soit le résultat..


Étape 5 - Rappels - Code dépendant après le chargement

Comme mentionné précédemment, nous ne pouvons pas écrire le code en ligne de la manière habituelle si ce code dépend du chargement de l'un des scripts. Ainsi, nous allons utiliser la fonction de rappel de yepnope qui se déclenche une fois pour chaque ressource après le chargement est terminé. La fonction de rappel accepte trois paramètres auxquels sont attribués les éléments suivants:

  • url

    Cette chaîne représente l'URL de la ressource chargée

  • résultat

    Un booléen représentant l'état de la charge.

  • clé

    Si vous utilisez un tableau ou un objet de ressources, cela représentera l'index ou le nom de la propriété du fichier chargé

Jetons un coup d'oeil à un simple rappel avec l'exemple de plug-in hashchange du précédent. Nous allons utiliser la méthode bind de jQuery pour lier un gestionnaire à l'événement hashchange du la fenêtre:

Un simple rappel:

 yepnope (test: Modernizr.hashchange && Modernizr.history, nope: 'resources / jquery.ba-hashchange.js', rappel: fonction (url, résultat, clé) $ (fonction () $ (fenêtre) .bind ('hashchange', function () console.info (location.hash);););,));

Quel que soit l'état dans lequel se trouve le DOM, ce rappel, qui dans ce cas particulier se trouve dans un wrapper de document prêt, sera déclenché dès que la ressource est chargée..

Supposons cependant que nous chargeons plus d'un script et que nous devons déclencher un rappel pour chaque script au fur et à mesure de son chargement. Spécifier le code que nous devons exécuter de la manière ci-dessus créerait une redondance car le rappel est déclenché à chaque chargement d'une ressource. Yepnope, cependant, constitue un excellent moyen de gérer les rappels pour chaque ressource, indépendamment de tout autre rappel..

En utilisant un littéral d'objet pour définir les ressources que nous chargeons, nous pouvons référencer chaque clé de ressource, individuellement, dans le rappel..

Jetons un coup d'œil à un exemple où nous chargeons jQuery ainsi que le plug-in jQuery hashchange, qui dépend du chargement de jQuery en premier. Cette fois, cependant, nous allons utiliser des littéraux d'objet!

 yepnope (test: Modernizr.hashchange && Modernizr.history, non: 'jquery': 'resources / jquery-1.5.1.min.js', 'hashch': 'resources / jquery.ba-hashchange.js' , callback: 'jquery': function (url, result, key) console.info ('Je ne déclencherai que lorsque le script jquery sera chargé');, 'hashch': function (url, result, key)  console.info ('Je ne tirerai que lorsque le script hashchange sera chargé'); // Ce code sera ajouté à la pile d'appels jQuerys DOM ready $ (function () $ (window) .bind ('hashchange', function ( ) console.info (location.hash););););

En utilisant l'exemple ci-dessus comme référence, vous pouvez implémenter vos propres rappels pour chaque charge de ressources de manière ordonnée..


Étape 6 - Terminé - Quand tout est dit et fait!

Enfin, nous avons le Achevée callback qui n'est appelé qu'une fois, une fois que toutes les ressources ont été chargées. Ainsi, par exemple, si vous "démarrez" une application Web et que le code que vous devez exécuter dépend de tous les fichiers que vous chargez, plutôt que de spécifier un fichier. rappeler pour chaque ressource, vous écrivez votre code dans le champ Achevée rappel afin qu’il ne soit déclenché qu’une fois, après le chargement de toutes ses dépendances. Contrairement à la rappeler une fonction, Achevée ne prend aucun paramètre ou avoir accès à la url, résultat ou clé les accessoires.

le Achevée rappeler:

 yepnope (test: Modernizr.hashchange && Modernizr.history, non: ['resources / jquery-1.5.1.min.js', ressources / jquery.ba-hashchange.js '], complétez: function () console .info ('Je ne déclencherai qu'une seule fois lorsque jquery et le script hashchange seront chargés'); // Ce code sera ajouté à la pile d'appels prêts pour jQuerys DOM $ (function () $ (window) .bind ('hashchange' , function () console.info (location.hash););););

Donc, essentiellement, le Achevée callback est utile pour tout ce qui doit être fait une fois que toutes les ressources sont chargées.


Étape 7 - Plug-ins Yepnope, préfixes et autres!

Yepnope nous fournit également une autre petite fonctionnalité intéressante: les préfixes et les filtres! Les préfixes par défaut fournis par yepnope, qui sont toujours ajoutés au début d'une URL de ressource, sont utilisés pour définir un fichier en tant que CSS, précharger une ressource ou cibler Internet Explorer ou l'une de ses versions, respectivement. Regardons:

  • css!

    Ce préfixe est utilisé pour forcer yepnope à traiter une ressource comme une feuille de style. Par défaut, yepnope traite les fichiers .css en tant que feuilles de style et tout le reste en tant que fichier JavaScript. Donc, si vous utilisez CSS de manière dynamique, ce préfixe forcerait yepnope à traiter cette ressource comme une feuille de style..

     yepnope ('css! styles.php? colorscheme = blue');
  • précharge!

    Ce préfixe vous permet de charger / mettre en cache une ressource sans l'exécuter.

     yepnope ('preload! userInterface.js');
  • c'est à dire!

    Dans certaines circonstances, il peut être nécessaire de charger des ressources spécifiques uniquement si vous utilisez Internet Explorer ou une version particulière d'Internet Explorer. Ainsi, le c'est à dire les préfixes vous aident à cibler le chargement des ressources sur c'est à dire ou des versions spécifiques de celui-ci. Voici une liste des pris en charge c'est à dire préfixes où gt signifie "versions supérieures à" et lt signifie "versions inférieures à".

    • Internet Explorer:
      c'est à dire!
    • Internet Explorer par numéro de version:
      ie5!, ie6!, ie7!, ie8!, ie9!
    • Les versions d'Internet Explorer supérieures à:
      iegt5!, iegt6!, iegt7!, iegt8!
    • Versions Internet Explorer inférieures à:
      ielt7!, ielt8!, ielt9!

    Tous ces filtres sont chaînables et servent comme une sorte de OU opérateur en ce que si l'un d'entre eux évalue à vrai la ressource sera chargée. Donc, si nous devions cibler ie7 et ie8, nous ajouterions simplement les filtres appropriés à l'URL de la ressource, comme suit:

     yepnope ('ie7! ie8! userInterface.js');

Créer vos propres filtres!

Si jamais vous avez besoin de, yepnope fournit également le moyen de créer vos propres filtres et préfixes par le biais de la addFilter et addPrefix méthodes. Tout filtre ou préfixe que vous créez reçoit un message resourceObject contenant un certain nombre d'accessoires utiles. Rappelez-vous, cependant, pour renvoyer le resourceObject comme yepnope le demande. Voici un coup d'oeil à la resourceObject:

  • URL:

    L'URL de la ressource en cours de chargement.

  • préfixes

    Le tableau de préfixes appliqués.

  • autoCallback

    Un rappel qui s'exécute après le chargement de chaque script, séparément des autres.

  • noexec

    Une valeur booléenne qui force le préchargement sans exécution.

  • au lieu

    Une fonction avancée qui prend les mêmes paramètres que le chargeur.

  • forceJS

    Un booléen qui oblige la ressource à être traitée comme javascript.

  • forceCSS

    Un booléen qui oblige la ressource à être traitée comme une feuille de style.

  • contourne

    Un booléen qui détermine si oui ou non charger la ressource actuelle

Supposons, par exemple, que vous souhaitiez pouvoir basculer le chargement des ressources entre votre CDN et votre serveur Web, à la volée. Pouvons-nous faire cela, cependant!? Oui! Créons deux préfixes, l'un pour le chargement à partir du CDN et l'autre pour le chargement à partir de votre serveur Web..

 yepnope.addPrefix ('local', fonction (resourceObj) resourceObj.url = 'http: // mySite / resources /' + resourceObj.url; return resourceObj;); yepnope.addPrefix ('amazon', fonction (resourceObj) resourceObj.url = 'http://pseudoRepository.s3.amazonaws.com/' + resourceObj.url; return resourceObj;);

En utilisant ces préfixes, nous pouvons maintenant basculer facilement entre notre CDN et notre serveur Web.!

 yepnope (['local! css / typography.css', 'amazon! defaultStyle.css']);

Étape 8 - Quelques mises en garde

Ainsi, tout en conservant un très faible encombrement, le chargeur conditionnel yepnope est doté de nombreuses fonctionnalités utiles! Il y a cependant quelques points à connaître avant de l'utiliser.

  • Non document.write

    Comme avec tout chargeur asynchrone, vous ne pouvez pas utiliser document.write.

  • Internet Explorer inférieur à 9 et exécution du rappel

    Les versions Internet Explorer inférieures à neuf ne garantissent pas l'exécution des rappels immédiatement après le déclenchement du script associé.

  • Attention au DOM

    Votre script peut être chargé et exécuté avant que le DOM ne soit prêt. Donc, si vous manipulez le DOM, il est conseillé d'utiliser un wrapper prêt pour le DOM..

  • Vous devriez quand même combiner où vous pouvez

    Ce n’est pas parce que vous utilisez un chargeur asynchrone que vous ne devez pas combiner vos ressources là où vous le pouvez..

  • Limites de charge asynchrone Internet Explorer

    Les anciennes versions d'Internet Explorer ne peuvent charger que deux ressources du même domaine en même temps, alors que les autres versions peuvent en charger jusqu'à six. Donc, si vous chargez plusieurs fichiers, envisagez l’utilisation d’un sous-domaine ou d’un CDN..


Conclusion - Réflexions sur yepnope.js

Dans l’ensemble, j’ai trouvé yepnope très utile! Non seulement il prend en charge le chargement asynchrone des scripts et des feuilles de style, mais il vous fournit un moyen agréable et propre de charger conditionnellement les polyfills HTML5 et CSS3. Le mécanisme de rappel est bien pensé et la possibilité d'ajouter vos propres préfixes et filtres est tout simplement géniale! En ce qui concerne les performances, j’ai trouvé que yepnope était un peu à la hauteur des autres chargeurs, tels que les LABjs de Getify Solutions et les exigences de James Burke. De toute évidence, chaque chargeur est différent et répond à un besoin différent, mais si vous ne l’avez pas encore fait, je vous encourage à essayer.!