Html5-boilerplate: solution de chargement de scripts

Créé le 10 août 2010  ·  132Commentaires  ·  Source: h5bp/html5-boilerplate




Ce fil de discussion est maintenant fermé.

C'était amusant, mais les conversations se sont déplacées ailleurs pour le moment. Merci

En remerciement des bons moments que nous avons eus, @rmurphey nous a fait un joyeux nuage de mots du fil.

Prendre plaisir.





via labjs ou require.

mon fichier load.js "boilerplate" contient LABjs, puis l'utilise pour charger jquery, GA et un fichier js de site. si ça peut aider, j'ai un RequireJS+jQuery intégré dans un seul fichier : http://bit.ly/dAiqEG ;)

aussi comment cela joue-t-il dans l'attente d'un script de construction qui concatène et minimise tous les scripts ? le chargement de script devrait-il être une option ?

javascript

Tous les 132 commentaires

kyle: " @paul_irish je ne suis pas d'accord. http://bit.ly/9IfMMN cacheability (CDN externes), téléchargement parallèle, script change-volatility..."

james burke : " @paul_irish @fearphage @getify RequireJS a un outil de build pour faire le regroupement/minification de scripts, donc peut avoir le meilleur des deux : dynamique et pré-construit"

Le moyen le plus simple pour les développeurs de démarrer avec le chargement de script serait probablement d'utiliser $ Lab.js, car il utilise déjà une syntaxe de chaînage avec laquelle de nombreux utilisateurs de jQuery sont familiers.

S'ils créent des applications de grande entreprise, ils peuvent toujours migrer vers require.js si nécessaire.

il existe actuellement trois principales techniques de chargement de script :

  1. HeadJS
  2. ContrôleJS
  3. LABjs

utilisez-le ou non, lequel utiliser est un peu discutable : http://blog.getify.com/2010/12/on-script-loaders/

Il y a aussi requireJS et EnhanceJS juste pour vous faire connaître les alternatives à HeadJS ControlJS et LabJS . Même Yahoo et Google proposent quelque chose de similaire.

Avec la sortie de jQuery 1.5 et des différés -- http://www.erichynds.com/jquery/using-deferreds-in-jquery/ , Boris Moore les utilise dans DeferJS, un nouveau projet de chargeur de script : https://github. fr/BorisMoore/DeferJS

Par défaut, le chargement du script arrête tous les autres téléchargements, donc le téléchargement de modernizr dans l'en-tête est mauvais. Inlining loader a du sens, car les loaders peuvent télécharger le script en parallèle et en mode non bloquant. Par exemple, si vous n'avez pas besoin de toutes les fonctionnalités de modernizr, vous pouvez insérer head.min.js qui ne fait que 6 Ko ou une version personnalisée de modernizr (http://modernizr.github.com/Modernizr/2.0-beta/). L'incorporation de CSS a parfois du sens aussi. Google utilise l'inline, ils inline css, js et vident les gifs 1x1 via datauri.

LabJS est de plus en plus largement utilisé et constitue une bonne solution - il peut également être inclus de manière asynchrone et n'a donc pas besoin de se bloquer.

http://blog.getify.com/2010/12/on-script-loaders/ est de l'auteur

http://yepnopejs.com/ vient de passer à la version 1.0 et ne se bloque pas dans le nouveau kit Web, contrairement à LAB et head.js. Le chargement du script est difficile.

yepnope est également intégré à Modernizr en tant que Modernizr.load .. http://modernizr.github.com/Modernizr/2.0-beta/

Nous aurons donc probablement un script loader dans h5bp via Modernizr.load très bientôt.

Je ne pense pas que cela fera 1.0, mais une fois que je mettrai Modernizr à 1.8, nous le jetterons dans h5bp 1.1. Ouais

salut Paul

J'ai porté un site existant pour utiliser votre H5BP et je souhaite utiliser le chargeur de script yepnope.js. C'est vraiment agréable de voir tous les bits et les robots assemblés comme vous l'avez fait.

Que recommanderiez-vous d'utiliser en ce moment?

  1. Incluez yepnope.js avec modernizer.js en haut de la page
  2. Incluez-le au bas de la page, pour le charger une fois le chargement du code HTML terminé.
  3. Utilisez la version bêta de modernizer.js
  4. Je pourrais concaténer yepnope.js avec modernizer.js en une seule inclusion.

Quelle que soit la meilleure façon de l'inclure, comment recommandez-vous de charger les scripts avec yepnope,js ?

Je suppose que nous devrions le faire ici : https://github.com/paulirish/html5-boilerplate/blob/master/index.html#L52 et utiliser yepnope pour charger la copie CDN/locale de jQuery et nos autres scripts.

Mais pensez-vous qu'il est préférable d'utiliser un script externe pour inclure ou afficher un bloc de script dans le code HTML, qui charge ensuite les scripts via yepnope.js ?

Merci beaucoup.

Andy

Ah et autre chose.

Comme yepnope peut charger le CSS via, je dirais qu'il est préférable d'inclure le CSS principal comme vous le feriez normalement et d'utiliser yepnope pour n'inclure que le CSS pour des correctifs spécifiques.

Par exemple, inclure des css qui ne s'appliquent qu'aux anciennes versions d'IE.

hokapoka,

Utilisez la version bêta de modernizr.. incluez simplement ce dont vous avez besoin (et incluez Modernizr.load() ), puis placez-le en haut de la page.

le code réel pour le repli jquery avec yepnope est sur http://yepnopejs.com/

Et oui, j'aime votre idée de la charge conditionnelle d'IE css.

tbh il y a trop de foi aveugle autour des performances des chargeurs de script et je ne pense pas que nous soyons prêts à dire que C'EST LA BONNE FAÇON.

nous avons besoin de plus de recherches sur la taille des fichiers, la bande passante et les conditions du réseau qui indiquent des recommandations intelligentes sur le chargement de script, mais pour le moment, le domaine est naissant et nous serions naïfs de recommander une solution globale de chargement de script.

donc.

fermer ce ticket et demander à toute personne intéressée de faire les recherches et la publication complètes nécessaires pour permettre aux développeurs de faire plus facilement un choix intelligent à propos de celui-ci

J'ai fait pas mal de recherches sur concat vs charge parallèle. Je recommande toujours, sans réserve, de combiner d'abord tous les js en un seul fichier, puis de le diviser en 2-3 ~ morceaux de taille égale et de les charger en parallèle.

J'aimerais pouvoir utiliser mes recherches et les diffuser largement et à grande échelle, afin qu'elles soient viables en tant que « faits » dans ce domaine. Le problème est que j'ai essayé et essayé de trouver de la bande passante d'hébergement où cela ne me coûtera pas beaucoup de $$ pour exécuter les tests à grande échelle, et je n'ai pas encore trouvé cette disposition d'hébergement.

Si je/nous pouvons résoudre le problème de bande passante pour les tests, j'ai les tests qui peuvent être exécutés pour savoir si la théorie du chargement parallèle est en fait viable (comme je le pense).

@getify de quoi avez-vous besoin comme

Je peux faire environ 1,5 To de données de plus sur mon serveur personnel que ce que j'utilise actuellement. J'ai installé Nginx et cela peut gérer environ 4 000 milliards de milliards de coups par microseconde. Je n'ai pas l'impression que la technologie est la barrière ici.

Si nous sommes préoccupés par les emplacements, nous pouvons usurper une latence plus élevée et/ou trouver quelques autres personnes avec un peu d'espace supplémentaire sur leurs boîtes.

BTW, je prends un petit problème avec la "foi aveugle".

Il est facile, prouvable et presque sans aucun doute vrai que si vous avez un site existant chargeant de nombreux scripts avec des balises de script, l'utilisation d'un chargeur de script parallèle (sans autre modification) améliore les performances. C'est vrai parce que même les navigateurs les plus récents ne peuvent pas (et ne le feront jamais, je ne pense pas) détacher le chargement du script du blocage de DOM-ready. Ainsi, même dans le meilleur des cas, le chargement du navigateur, s'il n'y a pas d'autre avantage, accélérer considérablement la compatibilité DOM sur un site est presque toujours une victoire (pour les utilisateurs et l'UX).

Votre déclaration est un peu fausse car elle suppose que nous essayons de comparer, pour chaque site, le chargement parallèle à script-concat. La plupart des sites sur le Web n'utilisent pas/ne peuvent pas réellement utiliser de script-concat, donc vraiment la comparaison (pour eux, la majorité) n'est pas aussi nuancée et compliquée que vous le supposez. S'ils n'utilisent pas/ne peuvent pas utiliser script-concat (pour une raison quelconque), la comparaison est simple : le chargement parallèle est presque toujours une victoire sur les balises de script.

S'ils sont ouverts au script-concat (ou l'utilisent déjà), alors oui, cela devient un peu plus nuancé/compliqué de décider si le chargement parallèle peut aider ou non. Mais script-concat n'est pas non plus une solution miracle pour tous, il existe donc de nombreux sites pour lesquels le chargement parallèle restera l'approche préférée et la meilleure.

Ce n'est pas parce que certains sites traitent des nuances/complexités du choix entre le chargement parallèle et le script-concat que la discussion plus importante (plus percutante) du chargement parallèle contre les balises de script devrait être perdue dans le mélange. Le premier est difficile à prouver, mais le second est presque acquis à ce stade.


Tout cela pour dire que, tout bien considéré, à mon humble avis, un passe-partout devrait encourager un modèle qui a le plus grand impact dans une direction positive. Si 80 % des sites sur Internet utilisent aujourd'hui des balises de script, dont la plupart gagneraient à passer des balises de script au chargement parallèle, alors le chargement parallèle est une chose très saine à suggérer comme point de départ pour le passe-partout.

C'est une sous-section beaucoup plus petite (mais importante) de ces sites qui peut potentiellement tirer encore plus d'avantages de l'exploration de script-concat par rapport au chargement parallèle. Mais un cas d'utilisation minoritaire n'est pas ce qui devrait être optimisé dans un passe-partout.

Juste mes quelques centimes.

@paulirish @slexaxton --

En ce qui concerne les besoins en bande passante, j'ai estimé que pour amener 10 000 personnes (ce qui me semblait nécessaire pour être un échantillonnage précis) à exécuter le test une fois (et de nombreuses personnes l'exécuteraient plusieurs fois, j'en suis sûr), il faudrait environ 200 Go de bande passante dépensés. Pour certaines personnes, c'est une goutte dans le seau. Pour moi, 200 Go de bande passante en quelques jours seraient écrasants pour les coûts d'hébergement de mon serveur. Donc, je n'ai pas poursuivi la mise à l'échelle des tests pour cette seule raison.

De plus, j'ai plus d'une douzaine de variantes de ce test que je pense que nous devons explorer. Ainsi, des dizaines de fois d'utilisation de 100 à 200 Go de bande passante chacune serait assez prohibitif pour moi pour payer la facture. Je ne voulais pas m'engager dans cette voie à moins d'être sûr d'avoir suffisamment de bande passante pour terminer la tâche.

Ce ne sont que des fichiers statiques et les tests ne nécessitent pas beaucoup d'utilisateurs simultanés, il n'y a donc pas de réelles inquiétudes concernant les problèmes de mise à l'échelle traditionnels comme le processeur, etc. Juste la bande passante, c'est tout.

Nous pouvons prendre le reste de la discussion sur les tests hors ligne et la poursuivre par e-mail ou messagerie instantanée. J'aimerais beaucoup étendre enfin les tests et "régler" ce problème. Il traîne à l'arrière de mon cerveau depuis près d'un an maintenant.

Je peux faire un TB illimité sur mon Dreamhost VPS donc ce ne sera pas un problème. en ce moment, je fais 72 Go/jour et je peux gérer bien plus. :)

Je suis d'accord avec Paul, et je pense qu'il y a pas mal d'informations erronées sur comment et quand les chargeurs de scripts seront utiles à quiconque.

Votre premier paragraphe dit qu'il est "facile", "prouvable" et "sans aucun doute" que les chargeurs de script améliorent les performances.

J'ai fait une postulation similaire à @jashkenas il y a quelque temps, et lui et moi avons rassemblé du mieux que nous pouvions des pages identiques pour essayer de mesurer les performances de nos _meilleures_ techniques. C'est un fan de 100% concat, et j'ai essayé 2 techniques de chargement de script différentes.

https://github.com/SlexAxton/AssetRace

Le code est là. De toute évidence, il n'y avait pas un public de test énorme, mais les résultats ont au mieux montré que ce script-loader était à peu près à la même vitesse que la méthode concat (avec vos directives de chargement parallèle de 3 fichiers de taille similaire suivies), et au pire a montré que le script- les chargeurs variaient beaucoup plus et étaient généralement plus lents avec une marge d'erreur. N'hésitez pas à chercher et à trouver une solution qui surpasse la nôtre ou les deux, même si ce n'est que sur votre machine dans un seul navigateur.

Quant à la "fausse prémisse" car h5bp suppose que les gens concatènent leurs js. Cet argument est totalement invalide car h5bp propose un outil de création de script, complet avec concat et minification. Ainsi, l'argument selon lequel le chargement parallèle est presque toujours une victoire sur plusieurs balises de script peut être vrai, mais ce n'est pas mieux que ce que h5bp propose actuellement. C'est le contexte de cette discussion.

Je pense que le pire des cas est que les gens prennent quelque chose comme yepnope ou lab.js et l'utilisent comme polyfill de balise de script. Cela va absolument entraîner un chargement plus lent (de leurs 19 fichiers JS et 34 CSS), ainsi qu'introduire une multitude de problèmes de compatibilité ascendante et descendante dont ils ne seront absolument pas conscients.

Je pense que dans l'esprit de donner aux gens la valeur par défaut la plus sensée, la plus performante et la plus compatible pour un _boilerplate_, un outil de construction va beaucoup plus loin pour garantir les trois.

@slexaxton

... les résultats ont au mieux montré que ce script-loader était à peu près à la même vitesse que la méthode concat (avec vos directives de chargement parallèle de 3 fichiers de taille similaire suivies) ...

Je me ferai un plaisir de trouver un peu de temps pour jeter un œil aux tests que vous avez mis en place. Je suis sûr que vous savez ce que vous faites, donc je suis sûr que vos tests sont valides et corrects.

OTOH, j'ai beaucoup de preuves contradictoires. Si j'avais déjà vu quelque chose de convaincant suggérant que le chargement de scripts parallèles était un gaspillage ou inutile pour la majorité des sites, j'aurais depuis longtemps abandonné le puits de temps fou qu'est LABjs.

Je peux dire avec une certitude à 100% que je n'ai jamais, en 2 ans d'aide à la diffusion de LABjs pour les gens, trouvé une situation où LABjs était plus lent que l'alternative de balise de script. Zéro fois cela ne m'est jamais arrivé. Il y a eu quelques fois que les gens ont dit qu'ils n'y voyaient pas beaucoup d'avantages. Il y a eu quelques fois où les gens chargeaient plus de 100 fichiers et donc la surcharge folle de ces nombreuses connexions a anéanti tous les avantages qu'ils auraient pu voir autrement. Mais personne ne m'a jamais dit que LABjs ralentissait leur site.

J'ai littéralement moi-même aidé plus de 50 sites différents à passer des balises de script aux LABjs, et les sites ont sans aucun doute vu leurs performances s'améliorer dès le départ. Au début des efforts, j'ai pris un échantillon de peut-être 7 ou 8 sites que j'avais aidés, et ils avaient collectivement constaté une amélioration moyenne d'environ 15 % de la vitesse de chargement. Pour les 4 ou 5 sites que je gère, j'ai bien sûr implémenté des LABjs, et j'ai tout de suite vu jusqu'à 3x la vitesse de chargement.

Bien sûr, lorsque LABjs a été lancé pour la première fois, les navigateurs étaient à la pointe de la technologie pour charger des scripts en parallèle (seuls quelques-uns le faisaient). Les gains étaient donc énormes et visibles à l'époque. Maintenant, nous avons presque tous les navigateurs qui effectuent un chargement parallèle, donc les gains ne sont plus aussi drastiques.

Mais la seule chose qui est indéniable est que les navigateurs bloquent tous l'événement DOM-ready pour le chargement des balises de script. Ils _doivent_ en raison de la possibilité de trouver document.write() . Le chargement de script parallèle dit essentiellement "navigateur, je vous promets que vous n'aurez pas à vous occuper de document.write, alors allez-y et avancez avec la page".

Jetez un œil aux deux diagrammes de la diapositive 10 de ce jeu :

http://www.slideshare.net/shadedecho/the-once-and-future-script-loader-v2

Comparez l'emplacement de la ligne bleue (compatible DOM). Il s'agit d'une amélioration drastique des performances perçues (UX), même si le temps global de chargement de la page (ou le temps nécessaire pour terminer le chargement de tous les actifs) n'est pas meilleur.

...h5bp propose un outil de création de scripts...

L'hypothèse erronée ici est que, simplement parce que h5bp propose cet outil, tous (ou même la plupart) les utilisateurs de h5bp peuvent l'utiliser. Même si 100% des utilisateurs de h5bp l'utilisent, cela ne signifie pas que si h5bp était déployé sur la longue traîne d'Internet, tous utiliseraient cet outil de concat. Il y a un tas d'autres facteurs qui peuvent facilement empêcher quelqu'un d'utiliser cela. Il y a _très peu_ de raisons pour lesquelles quelqu'un ne peut pas passer de l'utilisation de balises de script à l'utilisation d'un chargeur de script parallèle.

En tant que tel, le chargement de scripts parallèles offre toujours un attrait plus large pour la longue traîne d'Internet. Il est toujours plus facile pour la majorité des sites qui n'utilisent pas d'optimisations de chargement de script, de passer de rien à quelque chose, et que quelque chose leur offre des performances gagnantes. Peu de ces sites à longue traîne consacreront des efforts (ou auront les compétences nécessaires pour expérimenter) à des outils de création de scripts automatisés dans leurs environnements d'hébergement Web non CDN bon marché à 6 $/mois, d'hébergement de masse partagé.

Je pense que le pire des cas est que les gens prennent quelque chose comme yepnope ou lab.js et l'utilisent comme polyfill de balise de script. Cela va certainement entraîner un chargement plus lent ...

Je ne pourrais pas être plus en désaccord avec cette déclaration. LABjs est spécifiquement conçu comme un polyfill de balise de script. Et les améliorations de LABjs par rapport aux balises de script classiques (ignorer le script concat pour le moment) sont bien établies et n'ont jamais été sérieusement réfutées. Si vous avez la preuve que la plupart (ou même beaucoup) de sites utilisant LABjs feraient mieux de revenir aux balises de script, partagez-les.

Il n'y a absolument aucune raison pour que le chargement de script parallèle entraîne un chargement plus lent que ce que le navigateur pourrait accomplir avec des balises de script. Ça n'a aucun sens. Et comme je l'ai établi ci-dessus, les balises de script bloqueront toujours le DOM prêt, là où le chargement de script parallèle ne le sera pas.

introduire une multitude de problèmes de compatibilité ascendante et descendante dont ils seront complètement inconscients.

De quels problèmes de compatibilité parlez-vous ? La matrice de prise en charge des navigateurs de LABjs couvre absolument la grande majorité de tous les navigateurs Web de la planète. Le petit éclat fou de navigateurs dans lequel il s'introduit est largement compensé par le grand nombre de navigateurs dans lesquels il présente des avantages évidents.

LABjs 1.x contenait un tas de hacks fous, comme le préchargement du cache, qui étaient en effet des problèmes majeurs de rupture avec les navigateurs. LABjs 2.x a complètement renversé cela et utilise désormais des approches fiables et standardisées pour le chargement parallèle dans tous les cas, ne revenant qu'au hack de l'ancien navigateur Webkit. De plus, LABjs 2.x contient déjà des vérifications pour les tests de fonctionnalités des techniques de chargement de script à venir (espérons-le bientôt standardisées) comme le « vrai préchargement ».

Je ne peux parler définitivement pour aucun autre chargeur de script - je sais que beaucoup utilisent encore des hacks - mais en ce qui concerne LABjs, je suis déconcerté par l'affirmation selon laquelle il introduit des problèmes de compatibilité ascendante ou descendante, car je pense que c'est manifestement trompeur Réclamer.

pour expliquer légèrement pourquoi j'ai l'intention que LABjs soit en fait un polyfill de balise de script ...

  1. les navigateurs plus anciens sont clairement BEAUCOUP inférieurs pour gérer le chargement des balises de script que le chargement parallèle peut gérer. c'est dans ces "anciens navigateurs" (qui étaient les plus récents/les meilleurs lorsque LABjs a été lancé il y a 2 ans) que nous avons vu les améliorations du temps de chargement des pages d'environ 3 fois. presque par définition, cela fait de LABjs un meilleur polyfill de balise de script, car il apporte une fonctionnalité (c'est-à-dire des performances de chargement parallèle) aux navigateurs qui ne le prennent pas eux-mêmes en charge.
  2. les navigateurs les plus récents sont évidemment bien meilleurs. mais ils n'ont pas complètement supprimé les avantages des chargeurs de scripts. Chrome aussi récemment que la v12 (je suppose qu'ils ont finalement été corrigés dans la v13, semble-t-il) bloquait toujours le chargement des images pendant que les balises de script finissaient de se charger. même avec les dernières nouveautés d'IE, Firefox et Chrome, ils bloquent toujours le DOM-ready pendant le chargement dynamique des scripts, car ils doivent tous supposer pessimiste que document.write() peut se cacher.

Ainsi, pour les navigateurs les plus récents, LABjs est un "polyfill" dans le sens où il apporte au navigateur un "chargement de script non prêt pour le DOM" d'une manière que les balises de script ne peuvent pas faire. La seule façon possible de faire cela dans les navigateurs modernes sans chargeur de script parallèle serait d'utiliser des balises de script avec defer ( async ne fonctionnera évidemment pas car cela ne préserve pas l'ordre) . Cependant, defer a un certain nombre de bizarreries, et son support n'est pas assez répandu pour être une solution viable (la solution de repli pour le non-diffusion est de mauvaises performances). On pourrait donc dire que, dans le cas le plus basique, LABjs est un polyfill pour les caractéristiques de performance de la balise de script defer (bien que pas exactement).

Honnêtement, je pense toujours que nous devrions demander des normes pour un objet de chargement de script. Devoir créer une balise de script d'un type différent de text/javascript pour déclencher le cache (ou pire, utiliser une balise d'objet ou un objet image ou tout ce qu'une nouvelle version d'un navigateur populaire nécessitera) saute beaucoup de cerceaux pour rien et les performances varieront en fonction de trop de variables. Je peux comprendre que nous chargeons toujours des feuilles de style en utilisant l'insertion de nœud dom (mais c'est uniquement à cause de l'ordre) mais en ce qui concerne le script, je pense que cela n'a plus de sens du tout (j'aimerais que google arrête d'utiliser document.write dans la plupart des leurs scripts mais c'est une toute autre histoire).

De plus, je pense que nous manquons le plus gros point concernant les chargeurs de script ici : pouvoir charger du code js à la demande plutôt que de tout charger à l'avance (même avec tout dans le cache, l'analyse et l'initialisation prennent du temps et cela peut devenir assez moche avec une quantité non négligeable de scripts concaténés). Avoir un peu de temps d'attente après une interaction avec l'interface utilisateur est beaucoup moins un problème que d'avoir le navigateur « suspendu » même un peu au démarrage (DOM peut être tout à fait prêt, mais à quoi bon si le code pour améliorer la page et add iteraction n'a pas encore été exécuté : avez-vous déjà remarqué comment certains sites se chargent immédiatement puis que quelque chose de maladroit se produit ?).

Donc, une mesure de performance stricte est très bien, mais je pense toujours que la performance perçue est l'objectif ultime... et est malheureusement beaucoup moins facile à estimer/optimiser/calculer.

C'est intense.

@jaubourg--

Honnêtement, je pense toujours que nous devrions demander des normes pour un objet de chargement de script.

Il y a beaucoup de pétitions en cours sur la façon dont les normes/spécifications et les navigateurs peuvent nous donner une meilleure technologie de chargement de scripts. La première grande victoire dans cette catégorie depuis des années a été le " asynchrone ordonné " ( async=false ) qui a été adopté en février et est maintenant dans tous les principaux navigateurs de la version actuelle (exception : Opera à venir très bientôt, et IE10p2 l'a ).

Le prochain débat, sur lequel je suis actuellement en discussion avec Ian Hickson, est ce que j'appelle le "vrai préchargement". À mon avis, le "vrai préchargement" (que IE prend déjà en charge depuis la v4, btw) serait la chose la plus proche d'une "solution miracle" qui résoudrait presque tous les scénarios de chargement de script de manière assez triviale. Je suis toujours assez optimiste que nous verrons quelque chose comme ça standardisé.

Voir ce wiki pour plus d'informations : http://wiki.whatwg.org/wiki/Script_Execution_Control

Devoir créer une balise de script d'un type différent de text/javascript pour déclencher le cache (ou pire, utiliser une balise d'objet ou un objet image ou tout ce qu'une nouvelle version d'un navigateur populaire nécessitera)

C'est ce qu'on appelle le "préchargement du cache", et c'est un hack moche et horrible reconnu. La manière de LABjs désaccentue cela maintenant à partir de la v2 (l'utilise uniquement comme solution de secours pour les anciens kits Web). Malheureusement, d'autres chargeurs de scripts l'utilisent toujours comme mécanisme de chargement principal. Mais 90% du besoin de "préchargement de cache" peut être résolu avec "async ordonné", qui est standardisé et n'est pas un hack, donc les chargeurs de scripts bien comportés devraient préférer cela au "préchargement de cache" maintenant.

Donc, je suis d'accord que le "préchargement du cache" est nul, mais il existe de bien meilleures façons d'utiliser document.createElement("script") qui n'impliquent pas de tels hacks, donc je ne suis pas d'accord pour dire que c'est un argument contre le fait de continuer à s'appuyer sur l'élément Script du navigateur pour chargement du script. Si nous pouvons obtenir un "vrai préchargement", l'élément Script sera tout ce dont nous avons besoin. Je le crois sincèrement.

Je pense que nous manquons le plus gros point concernant les chargeurs de script ici : pouvoir charger du code js à la demande

Je suis tout à fait d'accord pour dire qu'il s'agit d'un avantage important apporté par les chargeurs de scripts. Mais c'est une sorte d'argument discutable dans _this_ thread, car les personnes "concat de script" ne peuvent tout simplement pas, sans chargement de script, résoudre le cas d'utilisation, donc cela n'a aucun sens de "comparer" les deux. Vous pouvez dire en tant que partisan de "script concat" "bien, nous ne nous soucions pas de ce cas d'utilisation", mais vous ne pouvez pas dire "nous pouvons mieux servir ce cas d'utilisation en utilisant XYZ".

La performance perçue _est_ énorme et importante, j'en conviens. Le chargement à la demande est un élément essentiel pour y parvenir. Le chargement à la demande améliorera également les performances réelles (pas seulement la perception) car il a tendance à réduire le nombre de téléchargements si vous ne téléchargez que ce qui est nécessaire (peu de visites de pages nécessitent 100 % du code que vous avez écrit).

La performance perçue est également la raison pour laquelle je préconise l'argument prêt pour DOM ci-dessus. Parce que la rapidité avec laquelle un utilisateur "se sent" comme s'il pouvait interagir avec une page est _très_ importante pour la vitesse à laquelle il pense que la page est (indépendamment de la vitesse à laquelle elle s'est réellement chargée). C'est un fait établi par de nombreuses recherches sur les utilisateurs.

Je dois aimer les longs commentaires passionnés de @getify
Kyle...

Si je peux contribuer de quelque façon que ce soit à la recherche, j'y serais ravi.
La bande passante (coûts) ne semble pas être le problème, alors @getify , que proposez-vous pour aller de l'avant ?
N'hésitez pas à me contacter par email (aaron [at] aaronpeters [dot] ou twitter (@aaronpeters)

@kyle

Oui, j'ai suivi la discussion sur les "améliorations" de la balise de script concernant le préchargement et je n'accepte tout simplement pas l'approche "ajouter un autre attribut sur la balise de script" comme une approche viable. J'ai vu ce que cela a fait à la spécification xhr : beaucoup de complexité par rapport au peu d'avantages que nous obtenons au final.

Ce qui est clair, c'est que nous n'avons besoin que du comportement de préchargement lors de l'insertion dynamique (c'est-à-dire déjà en javascript), alors pourquoi devrions-nous continuer à utiliser l'injection de balises de script ? Ce n'est pas comme si nous gardions la balise là ou que nous l'utilisions comme un nœud DOM : c'est juste un moyen d'atteindre une fin qui n'a rien à voir avec la structure du document.

Je serais beaucoup plus à l'aise avec quelque chose du genre :

window.loadScript( url, function( scriptObject ) {
    if ( !scriptObject.error ) {
        scriptObject.run();
    }
});

Cela ferait des merveilles. Il est assez facile de "rejoindre" plusieurs événements de chargement de scripts, puis d'exécuter ces scripts dans l'ordre nécessaire. Cela n'implique pas non plus la présence d'un DOM, ce qui le rend encore plus générique. Je souhaite que nous nous éloignerions complètement de l'injection de balises de script dès que possible. De plus, il est assez facile de polyfiller cela en utilisant les astuces que nous connaissons tous. C'est également beaucoup moins lourd qu'un système de demande complet (mais peut être une brique de construction pour un système de demande qui n'est alors pas limité aux navigateurs).

Ceci dit, je suis d'accord à 100% avec toi sur les performances perçues, je voulais juste le souligner car le mantra « compactons tout ensemble » devient rapidement une sorte de croyance qui brouille beaucoup trop les choses à mon goût ;)

fwiw, defer est pris en charge dans IE4+, Chrome, Safari et FF 3.5+. Non pris en charge dans Opera.

Cela signifie donc que... 98,5% des utilisateurs ont déjà un support script@defer .

@getify

Cependant, defer a un certain nombre de bizarreries,

détails svp ? je n'ai rien vu à ce sujet

Les scripts avec defer s'exécutent-ils avant ou après le déclenchement de l'événement DOM ready ?

L'ordre d'exécution est-il conservé dans tous les navigateurs ?

Qu'en est-il de l'ordre d'exécution et du couplage externe avec des scripts en ligne ?

@paulirish--

...98,5% des utilisateurs ont déjà pris en charge script@defer .

le support peut être présent dans autant de navigateurs, mais cela ne signifie pas qu'il est fiable dans autant de navigateurs. c'est ce que je voulais dire. (voir ci-dessous)

Cependant, le report a un certain nombre de bizarreries,

détails svp ? je n'ai rien vu à ce sujet

Laissez-moi voir... IIRC :

  1. la prise en charge du report sur les éléments de script dynamiques n'est définie ou prise en charge dans aucun navigateur... ne fonctionne que pour les balises de script dans le balisage. cela signifie qu'il est complètement inutile pour les techniques et les cas d'utilisation « à la demande » ou « de chargement paresseux ».
  2. Je pense qu'il y a eu un cas où, dans certains navigateurs, les scripts différés commençaient à s'exécuter immédiatement avant le déclenchement de DOM-ready, et dans d'autres, cela s'est produit immédiatement après le déclenchement de DOM-ready. Il faudra faire plus de recherches pour plus de détails à ce sujet.
  3. defer utilisé sur une balise de script référençant une ressource externe s'est comporté différemment de defer spécifié sur une balise de script contenant du code en ligne. C'est-à-dire qu'il ne pouvait pas être garanti de fonctionner pour différer les deux types de scripts et les faire continuer à s'exécuter dans le bon ordre.
  4. defer sur une balise de script écrite par une instruction document.write() différait d'une balise de script dans le balisage avec defer .

Je n'ai pas une tonne de détails à portée de main sur ces questions. Je me souviens il y a environ 2 ans (avant LABjs) d'avoir essayé d'utiliser defer , et d'en avoir rencontré suffisamment lors de tests multi-navigateurs pour que je l'ai essentiellement mis de côté et que je ne l'ai pas vraiment revu depuis.


Je dois également souligner que defer n'est pas vraiment la même chose que ce que fournissent LABjs (et autres chargeurs parallèles). J'ai dit cela ci-dessus avec la mise en garde que c'est seulement un peu comme ça. En fait, ce que le chargement de script parallèle fournit (au moins, pour la partie de LABjs), est "asynchrone ordonné", ce qui n'a absolument aucun moyen d'être réalisé uniquement par le biais du balisage.

La différence entre "ordered async" et "defer" est que "ordered async" commencera toujours à s'exécuter dès que le premier script demandé aura fini de charger, tandis que "defer" attendra le `DOM-ready avant de commencer les exécutions. Pour une page simple avec peu de balisage et aucun autre appel de balisage bloquant (comme d'autres balises de script), cette différence est faible. Mais pour une page avec beaucoup de ressources, le moment où les scripts sont autorisés à commencer à s'exécuter peut être radicalement différent.

Donc, honnêtement, j'aimerais ne pas trop m'éloigner de la tangente de defer , car en réalité, ce n'est pas une grande comparaison avec ce que fournit le chargement de script parallèle. C'était juste l'exemple le plus proche dans le balisage uniquement que je pouvais utiliser pour décrire le comportement ordonné d'exécution auquel je voulais en venir. Je n'aurais probablement même pas dû parler de defer -- cela vient brouiller la discussion.

Permettez-moi de reformuler ci-dessus : "Pour les navigateurs modernes, LABjs est une sorte de" polyfill "pour le comportement" asynchrone ordonné ", qu'il n'est pas possible d'opter pour le balisage uniquement dans n'importe quel navigateur."

J'aime "ordonné async", c'est une bonne phrase.

Kyle > Afaik, les scripts avec defer s'exécuteront _avant_ onload, même avant domready.
Les scripts avec l'attribut async s'exécuteront dès que possible et _always_ _before_ onload, mais pas nécessairement avant domready

@aaronpeters--
Je pense que vous êtes peut-être légèrement hors de propos. Voici comment je le comprends :

async scripts async ne devraient attendre rien (sauf la disponibilité du moteur JS lui-même). Cependant, s'ils sont demandés avant window.onload , alors dans presque tous les navigateurs, ils "retiendront" l'événement window.onload jusqu'à ce qu'ils se chargent et s'exécutent. Je pense qu'il y avait un cas documenté où les scripts async ne tenaient pas window.onload , sans se souvenir des détails exacts.

defer d'autre part signifie spécifiquement : attendre la fin du DOM-ready. De plus, il y a une "file d'attente" de tous les scripts avec defer défini dessus, de sorte que la file d'attente n'est traitée qu'après DOM-ready Cela signifie qu'ils doivent tous s'exécuter strictement après DOM-ready (ou, plutôt, après le DOM est prêt et l'analyse est terminée, pour être exact). Mais ils peuvent être encore plus retardés (si le chargement se fait lentement). Ils devraient cependant contenir window.onload . Je me souviens juste d'un vague souvenir que dans certaines versions d'IE, la pratique réelle de cette théorie était un peu floue.

@getify

Je ne voulais pas faire dérailler encore plus ce fil alors j'ai posté ma réflexion sur le préchargement de script et votre proposition sur la page WHATWG ici : http://jaubourg.net/driving-a-nail-with-a-screwdriver-the-way -la toile

async scripts async ne devraient attendre rien (sauf la disponibilité du moteur JS lui-même). Cependant, s'ils sont demandés avant window.onload , alors dans presque tous les navigateurs, ils "retiendront" l'événement window.onload jusqu'à ce qu'ils se chargent et s'exécutent.

C'est probablement plus facile à comprendre une fois que vous réalisez que JavaScript est à thread unique. (je sais que ça m'a pris du temps...)

De même, si vous utilisez setTimeout(fn, 0) pour télécharger des ressources et qu'elles entrent dans la file d'attente de téléchargement avant le déclenchement de onload , le chargement de ces ressources retardera (encore) onload .

Je pense qu'il y avait un cas documenté où les scripts async ne tenaient pas window.onload , sans se souvenir des détails exacts.

J'aimerais avoir plus d'informations à ce sujet. S'il vous plaît rappelez-vous! :)

Oui, les chargeurs de scripts !

Un problème que j'ai eu à les mettre en œuvre sur le réseau de sites d'AOL concerne les conditions de concurrence. Par exemple, charger jQuery de manière asynchrone dans la tête, puis dire un plugin jQuery à mi-chemin dans le document livré de manière asynchrone dans un article de blog.

Ainsi, j'ai lancé mon propre projet scientifique de chargeur de script (Boot.getJS) pour gérer cela. L'idée est de télécharger tous les scripts en parallèle et de les exécuter dans l'ordre quoi qu'il arrive, dès que possible. Il prend également en charge le report de prêt ou de chargement et la mise en cache des scripts. La plupart des idées sont empruntées (volées) par des personnes sur ce fil, alors merci les gars. :)

Puisque vous discutiez des benchmarks, j'ai pensé que je partagerais une page de test que j'ai créée pour comprendre les différences de performances, de syntaxe et de comportement des différents chargeurs de script, consultez-la ici :

http://artzstudio.com/files/Boot/test/benchmarks/script.html

Pour voir comment se comportent les différents chargeurs, effacez le cache et observez les requêtes réseau et l'heure finale ainsi que l'ordre dans lequel les scripts s'exécutent.

Dave (@artzstudio), txs pour partager vos réflexions et le lien vers votre page de test.

Question : pourquoi chargez-vous des LABjs sur la page '<script> tag in head' ? Cela semble faux.

@artzstudio également, vous utilisez une ancienne version de LABjs. Est-ce intentionnel ? Si oui, pourquoi?

@aaronpeters Chez AOL, nous avons des scripts comme Omniture, un code publicitaire (et plus) qui doivent aller dans la tête, c'est donc là que la bibliothèque de chargement va dans notre cas d'utilisation. De plus, lorsque les scripts sont en bas, il y a un problème FOUC dans certains de nos widgets, donc plus les dépendances se chargent tôt (comme jQuery), mieux c'est.

Ce n'était pas intentionnel, ce test date de quelques mois. Je mettrai à jour les bibliothèques quand j'en aurai l'occasion.

Pour info (j'espère que c'est quelque peu intéressant/pertinent), j'ai effectué quelques tests sur Webpagetest.org pour voir ce qui se passe dans IE8 lors du chargement de certaines des pages de test @artzstudio .
Balises de script : http://www.webpagetest.org/result/110810_C7_752b756180e132f50a3ef065e9e059ca/
Oui : http://www.webpagetest.org/result/110810_8S_a53f4ed2e16179c328fc57c572e71076/
LABjs : http://www.webpagetest.org/result/110810_ZV_1ece92044799e52ed5199aed6b407133/
RequireJS : http://www.webpagetest.org/result/110810_Z3_a1537e41a0b0570286151859973d0cfa/

Vidéo comparant Yepnope et LABjs : http://www.webpagetest.org/video/view.php?id=110810_074cb94c1b04a7ac9bd6538ec3fdd8d3c07f842d

Quelques notes:

  • Gzip est désactivé sur le serveur, donc la taille de fichier plus grande de RequireJS a un impact
  • Comme mentionné précédemment, la page des balises de script charge les LABjs dans le HEAD (cela n'a pas de sens) et cela a bien sûr un impact

Pour ces deux raisons, j'ai créé une vidéo ne montrant que Yepnope et LABjs.

Ce que je trouve intéressant, c'est que le temps de démarrage du rendu est bien meilleur pour les LABjs. Pourquoi donc? J'aimerais mieux comprendre.

Remarque de clôture : je ne publie pas ceci dans le but de favoriser les LABjs par rapport à Yepnope ou quelque chose comme ça. Juste partager des données...

Oh désolé, je vois ce que vous vouliez dire à propos des LABjs dans le test <script>. Corrigé maintenant, avec une mise à niveau vers LABjs.

@artzstudio--

Ainsi, j'ai lancé mon propre projet scientifique de chargeur de script (Boot.getJS) pour gérer cela. L'idée est de télécharger tous les scripts en parallèle et de les exécuter dans l'ordre quoi qu'il arrive, dès que possible

Alors, saviez-vous que c'est exactement ce pour quoi LABjs est conçu et qu'il fonctionne très bien (si je le dis moi-même) ? Ce que je veux dire, c'est que vous vouliez juste une API différente, ou qu'en est-il de la fonctionnalité de chargement de script parallèle qui n'était pas suffisante ?


Dans tous les cas, même si j'aime me vanter de LABjs, je ne pense pas qu'il soit efficace de ralentir ce fil avec des discussions de type "regardez, mon chargeur de script est meilleur à X". Ces discussions sont utiles, mais ailleurs.

En fin de compte, toute la technologie du chargeur de script se résume à quelques idées simples. Peu importe le type d'API sophistiquée que vous superposez ou les cas d'utilisation auxquels vous répondez, la technologie est la même. Il doit y avoir 50 chargeurs de scripts différents de nos jours, et vraiment, aucun d'entre eux ne fournit quelque chose de différent en termes de technologie, juste des API différentes. Donc, comparer les API est vraiment une discussion plutôt hors de propos à avoir.

Ce sur quoi nous devons nous concentrer est la possibilité d'utiliser la technologie de chargement de script de base actuellement disponible dans les navigateurs pour améliorer les performances des chargements de page par rapport à la simple utilisation de balises de script dans le balisage. C'est une prémisse que je tiens depuis longtemps que c'est absolument vrai, mais cette prémisse a été remise en question dans ce fil. La tâche n° 1 consiste donc à répondre à cette question.

Si nous découvrons que les balises de script sont tout simplement meilleures que le chargement de script, alors nous pouvons simplement arrêter toute cette folie et fermer tous nos projets. Je soupçonne que ce ne sera pas le cas, cependant. ;-)

La tâche n°2 consiste à découvrir une fois pour toutes si script-concat est toujours meilleur que le chargement parallèle. Encore une fois, mes prémisses (et mes tests) montrent que concaténer tous les fichiers en un seul est bon, mais vous devez ensuite diviser ce gros fichier en 2-3 morceaux à peu près égaux et charger ces morceaux en parallèle. Donc, nous devons également tester cette théorie.

Si nous découvrons que script-concat est toujours le meilleur, là encore, les chargeurs de script sont toujours utiles si l'on considère que la plupart des sites chargent des scripts à partir de plusieurs emplacements (jquery de Google CDN, google analytics de google, boutons facebook/twitter/g+ , etc). Nous aurions donc besoin, comme tâche n°3, de déterminer si la concaté est tellement meilleure que vous devriez héberger vos propres copies de tous ces fichiers, en les concaté avec votre propre code.

Kyle, pouvez-vous voir la source de mon exemple et me dire comment j'instrumenterais LabJS pour exécuter tous les scripts de la page dans l'ordre (même en dehors de la chaîne) ? J'ai très bien pu mal lire l'API (comme l'a dit Paul, les chargeurs de scripts sont difficiles, %-).

Le 10 août 2011, à 9h09 ,

@artzstudio--

Ainsi, j'ai lancé mon propre projet scientifique de chargeur de script (Boot.getJS) pour gérer cela. L'idée est de télécharger tous les scripts en parallèle et de les exécuter dans l'ordre quoi qu'il arrive, dès que possible

Alors, saviez-vous que c'est exactement ce pour quoi LABjs est conçu et qu'il fonctionne très bien (si je le dis moi-même) ? Ce que je veux dire, c'est que vous vouliez juste une API différente, ou qu'en est-il de la fonctionnalité de chargement de script parallèle qui n'était pas suffisante ?


Dans tous les cas, même si j'aime me vanter de LABjs, je ne pense pas qu'il soit efficace de ralentir ce fil avec des discussions de type "regardez, mon chargeur de script est meilleur à X". Ces discussions sont utiles, mais ailleurs.

En fin de compte, toute la technologie du chargeur de script se résume à quelques idées simples. Peu importe le type d'API sophistiquée que vous superposez ou les cas d'utilisation auxquels vous répondez, la technologie est la même. Il doit y avoir 50 chargeurs de scripts différents de nos jours, et vraiment, aucun d'entre eux ne fournit quelque chose de différent en termes de technologie, juste des API différentes. Donc, comparer les API est vraiment une discussion plutôt hors de propos à avoir.

Ce sur quoi nous devons nous concentrer est la possibilité d'utiliser la technologie de chargement de script de base actuellement disponible dans les navigateurs pour améliorer les performances des chargements de page par rapport à la simple utilisation de balises de script dans le balisage. C'est une prémisse que je tiens depuis longtemps que c'est absolument vrai, mais cette prémisse a été remise en question dans ce fil. La tâche n° 1 consiste donc à répondre à cette question.

Si nous découvrons que les balises de script sont tout simplement meilleures que le chargement de script, alors nous pouvons simplement arrêter toute cette folie et fermer tous nos projets. Je soupçonne que ce ne sera pas le cas, cependant. ;-)

La tâche n°2 consiste à découvrir une fois pour toutes si script-concat est toujours meilleur que le chargement parallèle. Encore une fois, mes prémisses (et mes tests) montrent que concaténer tous les fichiers en un seul est bon, mais vous devez ensuite diviser ce gros fichier en 2-3 morceaux à peu près égaux et charger ces morceaux en parallèle. Donc, nous devons également tester cette théorie.

Si nous découvrons que script-concat est toujours le meilleur, là encore, les chargeurs de script sont toujours utiles si l'on considère que la plupart des sites chargent des scripts à partir de plusieurs emplacements (jquery de Google CDN, google analytics de google, boutons facebook/twitter/g+ , etc). Nous aurions donc besoin, comme tâche n°3, de déterminer si la concaté est tellement meilleure que vous devriez héberger vos propres copies de tous ces fichiers, en les concaté avec votre propre code.

Répondez directement à cet e-mail ou consultez-le sur GitHub :
https://github.com/paulirish/html5-boilerplate/issues/28#issuecomment-1772315

On pourrait penser que la physique dit que le concat est le meilleur. Chaque nouvelle connexion HTTP est un autre démarrage lent + une taxe de 100 ms dans le pire des cas depuis le CDN.

Cependant, la vérité sur les documents est qu'ils peuvent être très longs. Ainsi, le chargement d'un fichier BFJS dans la tête peut ralentir inutilement l'initialisation des modules. Le charger à la fin peut provoquer un FOUC ennuyeux. Il peut y avoir des implications mobiles pour les gros fichiers : http://www.yuiblog.com/blog/2010/06/28/mobile-browser-cache-limits/

Je pense que c'est le motif derrière la règle de « split the payload » de Souders (http://oreilly.com/server-administration/excerpts/9780596522315/splitting-the-initial-payload.html). Nous devons également faire ce qui est visiblement plus rapide.

Et malheureusement, cela se résume à une sorte de réponse "ça dépend", ce qui rend ce problème suffisamment intéressant pour nous divertir tous.

Je joue avec une approche hybride où les appels getJS sont mis en file d'attente et concaténés périodiquement à un intervalle de temps défini, ainsi que concaté sur un niveau de dépendance de module (par exemple concassage des dépendances RequireJS au lieu de charger une à la fois), tout à la volée sur le front-end.

C'est une expérience scientifique qui, comme vous le soulignez, sera bientôt inutile, espérons-le, mais néanmoins intéressante.

@getify : Je sais que c'est à peu près juste pisser sur le défilé à ce stade, mais quand même.

Si nous découvrons que les balises de script sont tout simplement meilleures que le chargement de script,
alors nous pouvons simplement arrêter toute cette folie et fermer tous nos projets.
Je soupçonne que ce ne sera pas le cas, cependant. ;-)

Je pourrais dire beaucoup de choses sur l'huile de serpent, mais une démonstration fonctionnera tout aussi bien :

http://jashkenas.s3.amazonaws.com/misc/snake-oil/labjs.html

http://jashkenas.s3.amazonaws.com/misc/snake-oil/vanilla.html

C'est une page avec 100k de texte, 10 images et 171k de JavaScript. La version vanille utilise un seul fichier minifié qui inclut jQuery, jQuery-UI, Underscore et Backbone, ainsi que le fichier timer.js qui écrit les résultats du temps de chargement. La version LABjs charge chacun des 5 fichiers JavaScript (minifiés séparément) à l'aide de LABjs.

Vous constaterez que non seulement la version LAB n'offre aucun avantage, mais que les requêtes HTTP supplémentaires ne font que nuire aux performances de charge et doivent rivaliser avec d'autres actifs de la page, comme les images. Mais tout cela a déjà été dit plusieurs fois...

LABjs

Vanilla

Je peux anticiper un contre-argument concernant le chargement de vos scripts par morceaux... mais c'est tout à fait orthogonal à la technique de chargement de script, alors s'il vous plaît, laissez-le en dehors de la discussion.

Par tous les moyens, arrêtez la folie.

@jashkenas Complet, 100% ack. Les chargeurs de scripts ajoutent simplement des frais généraux, des complications et des points de défaillance. Un seul fichier concaténé de serveur se charge rapidement (est), à la fois en termes de temps de transfert pur et en termes d'efficacité des interpréteurs JavaScript, et en prime, gzipping fonctionne mieux si vous n'avez qu'un seul fichier.

Je dois dire que la version LABjs se charge _parfois_ plus rapidement dans mon navigateur (par rapport à la page vanille), mais pas de manière cohérente. De plus, onload ne se déclenche pas toujours, ce qui semble... étrange.

Oui, gzipping vous offre encore plus de gains globaux avec moins de requêtes HTTP.

Et il ne s'agit pas d'un dogme, il n'est pas nécessaire que ce soit un fichier JS _single_ pour l'ensemble de l'application - deux ou trois avec defer sont parfaits pour une mise en cache affinée, tout comme le chargement ultérieur.

Quelques recherches de l'équipe Google Page Speed :

http://pagespeed-velocity2011.appspot.com/#8 voir les diapositives 8 à 14, ce qui rend la discussion plus peu concluante


Je suis toujours passionné par l'attribut @defer du script et je pense que c'est une valeur par défaut sage, à moins que vous ne prévoyiez de passer de nombreuses heures/jours à tester les performances de vos propres variations.

@miketaylr : Oui, s'il vous plaît,

Eh bien, labjs _always_ se charge le plus rapidement dans mon navigateur (Safari 5.1) même avec Shift-Refresh ou lorsque les éléments sont mis en cache.

Bien sûr, utiliser un chargeur de script sans concaténer sera plus lent qu'une balise de script concaténé. C'est pourquoi les gens (YUI, requireJS) ont créé des chargeurs de scripts qui chargent des fichiers et des services concaténés qui les concaténent sur demande (https://github.com/rgrove/combohandler).

Allez, cette discussion n'a aucun sens. Les chargeurs de scripts permettent de charger des scripts à la demande, en particulier après une interaction avec l'utilisateur, par exemple en chargeant la logique derrière la boîte de dialogue et la validation de formulaire en cliquant sur un bouton "Se connecter".

J'ai un soupçon sournois que @jashkenas et @madrobby simplifient à l'excès les choses.
Steve suggère que le téléchargement parallèle présente plusieurs avantages pour une gamme de problèmes de blocage et de navigateurs _(oui, cela signifie non WebKit)_. Il mentionne également une stratégie consistant à charger le strict minimum de JS requis pour les tâches de chargement dom, puis à charger le reste plus tard selon les besoins. Parce que les situations et les besoins de développement varient, je ne sais pas si un chargeur de script appartient à un passe-partout _(activé par défaut)_ mais je ne jetterais pas le bébé avec l'eau du bain pour l'instant.

Si ce n'était pas clair dans mon message d'origine. J'ai tendance à être d'accord (avec jdalton) pour dire que les chargeurs de script présentent de nombreux avantages dans des environnements hautement testés et spécifiques qui nécessitent une attention particulière. Je ne pense pas que ce soit une valeur par défaut appropriée.

Je suis d'accord avec @jdalton : il n'y a pas de chargeur

De plus, @getify , prétendre que tous les chargeurs de script utilisent réellement la même technologie en dessous est une déclaration très mal informée.

Pour ce que ça vaut...
cette

var script = document.createElement('script')
script.src = 'foo.js'
document.getElementsByTagName('head')[0].appendChild(script)

c'est mieux que ça

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

pour la seule raison principale qu'il n'est pas bloquant. Ainsi, les images et les fichiers CSS suivants devront attendre que ce fichier soit téléchargé avec cette dernière version. Le premier est asynchrone. Tout le monde doit le savoir, que vous décidiez ou non d'utiliser un chargeur de script.

re: " prétendre que tous les chargeurs de script utilisent en fait la même technologie en dessous est une déclaration très mal informée. "

S'ils ne le font pas de la manière ci-dessus, ils le font mal

Eh bien, pour être parfaitement juste, l'utilisation de appendChild est tombée en désuétude... :D

Cependant, j'ai ajouté ce cas de test à AssetRace

https://github.com/SlexAxton/AssetRace/blob/master/asyncconcat.html

Cela accélère le tir en charge, il pourrait donc y avoir un avantage perçu. Mais l'heure d'arrivée est à peu près la même...

@ded : Nous ne parlons pas ici de gros blocages incompétents de <script> dans <head> ... nous parlons de balises de script avec un defer ou async Attribut <body> , où il n'y a plus rien à bloquer.

@jaubourg--

De plus, @getify , prétendre que tous les chargeurs de script utilisent réellement la même technologie en dessous est une déclaration très mal informée.

C'est une fausse représentation complète de ce à quoi je voulais en venir. En fait, la plupart des chargeurs de scripts ne font PAS les choses que je pense qu'ils devraient faire (et que LABjs le fait maintenant) en termes d'utilisation de la meilleure technologie. Mon point était que, même si tous utilisaient la meilleure technologie, il y a toujours une limite finie à ce que nous pouvons faire en termes de technologie. Je suis à peu près sûr qu'il n'y a pas de chargeurs qui utilisent une solution miracle que LABjs ignore ou n'utilise pas. Vous ne pouvez pas faire en sorte que la lumière aille plus vite que la vitesse de la lumière, peu importe ce que vous faites ou la façon dont vous jouez avec les chiffres.

Argumenter sur la technologie sous-jacente (en disant "hey, regardez mon API cool et meilleure") est inutile. La meilleure technologie dans le chargement de scripts est une quantité finie connue (même si beaucoup de chargeurs sont irresponsables et ne l'utilisent pas). Nous pouvons pousser pour une meilleure technologie (ce que je suis), mais débattre de qui a la meilleure API sur son chargeur ne fait rien pour cet objectif.


Ce fil semble vraiment avoir le plus grand intérêt à essayer de déterminer si les balises de script sont assez bonnes par elles-mêmes (avec ou sans report) ou si les chargeurs de script aident à obtenir de meilleures performances. Deuxièmement, nous devons déterminer si concat est vraiment la fin de tout le chargement de script.

C'est également un point discutable (pour ce fil de discussion) que les chargeurs de scripts ont tous ces autres cas d'utilisation qu'ils peuvent faire, ce que les balises de script de balisage ne peuvent pas faire (comme le chargement à la demande/lazy-loading). Encore une fois, c'est fondamentalement une donnée à ce stade, donc essayer de rétablir ce fait est inutile.

NON

CHARGER LA RAGE !

loaders make me rage

Voir la publication originale ici.

De plus, toute personne/personne offensée par un pénis de dessin animé : bienvenue sur Internet ! Je vous recommande fortement de commencer votre voyage ici .

OK, j'ai créé 3 tests pour illustrer certains points. Tout d'abord, les balises de script manuel (comme ligne de base) :

http://labjs.com/dev/test_suite/test-script-tags.php

Notez que le DOMContentLoaded (alias "DOM-ready") arrive bien tard, une fois les scripts terminés. C'est le mal. Bien que le temps de chargement réel de la page puisse être le même que celui des tests ultérieurs, le temps de chargement perçu de la page sera toujours beaucoup plus lent si le DOM-ready est bloqué (de nombreux sites attendent le DOM-ready pour attacher des comportements de clic, appliquer des améliorations JS au contenu, etc.).

Maintenant, ce qui se passe, c'est que nous utilisons defer sur nos balises de script :

http://labjs.com/dev/test_suite/test-script-defer-tags.php

Eh bien, c'est bien, nous avons corrigé le problème de délai DOMContentLoaded, mais nous avons maintenant un autre problème. Le bloc de script en ligne ne fonctionne pas avec defer . Il s'exécute immédiatement. Oups. BTW, ce n'est pas un bug, la spécification le dicte spécifiquement.

http://labjs.com/dev/test_suite/test-LABjs.php

Le test LABjs obtient fondamentalement les mêmes (ou meilleurs) performances que le test defer , mais il ne manque pas d'exécuter le code en ligne une fois les scripts terminés.

Essayez ces tests plusieurs fois dans les navigateurs modernes (Chrome 13, FF5, etc.). Pour moi, les LABjs ont toujours obtenu des performances à peu près égales ou supérieures au test defer . Dans toutes mes tentatives, je n'ai jamais vu les LABjs fonctionner moins bien que le test defer . Essayez ces tests dans des navigateurs plus anciens (comme FF3.5 ou IE7), et vous verrez que le chargeur de script commence à surpasser les autres tests de manière notable.

Même si le test LABjs a des nombres similaires au test defer dans les navigateurs les plus récents, c'est un problème si defer ne peut pas être utilisé pour defer ALL code (fonctionne uniquement pour le code chargé via un fichier externe). BEAUCOUP de sites chargent des scripts, puis ont un code en ligne pour activer/initialiser le code qu'ils viennent de charger. defer ne nous offre aucune solution pour cela.

Par conséquent, defer ne convient pas comme technologie de « chargement général de scripts ». La meilleure option suivante est un chargeur de script.

@getify

Il ne s'agit pas seulement de micro-optimisations... et, OUI, l'API est importante et est généralement une bonne indication du type de limitations de la technologie sous-jacente, principalement à cause desdites micro (ou même macro) optimisations. Il ne s'agit pas toujours uniquement de charger des scripts. La gestion complexe des dépendances, le sandboxing approprié et la modularité réelle, réelle, ne sont pas quelque chose à éliminer simplement parce que cela ne vous intéresse pas. Devinez quoi? Ce sont en fait les choses dont les gens ont besoin et les performances de chargement des pages peuvent être atteintes à un niveau raisonnablement bon avec des balises de script statiques.

Tout se résume finalement au fait que l'injection de balises de script n'est pas l'outil approprié pour la tâche : elle ne l'a jamais été en fait. C'est juste un hack très laid. En ce sens, vous ne poussez pas réellement pour une meilleure technologie : vous poussez pour plus de la même chose avec de nouveaux types de mises en garde qu'aucun de nous ne peut encore déduire. S'il vous plaît, réfléchissez une seconde et voyez s'il clique enfin.

Ce qui est vraiment exaspérant, c'est que vous refusez de présenter un seul argument en faveur de l'injection de balises de script par opposition à une API javascript native appropriée pour le chargement de scripts. Vous ignorez tout. Je vais vous épargner la peine cependant : il n'y a aucun argument là-dedans. Mais, heh, nous pouvons tous avoir une certaine masturbation mentale sur les tenants et les aboutissants du report et de l'async et nous sentir comme les dieux du javascript, n'est-ce pas ? Ou débattre des optimisations de 50 ms comme si cela aidait réellement n'importe qui dans cette industrie.

Si vous décidez finalement que je mérite une réponse intelligente (par opposition à une autre annonce LabJS), faites-le sur mon blog et gardons ce fil seul. Merci.

@jaubourg --
J'ai lu votre message en profondeur la nuit dernière. J'avais prévu d'écrire un article de blog en réponse, en vous félicitant et en vous félicitant en grande partie pour les bonnes pensées que vous y avez présentées. Malheureusement, ce que vous suggérez a déjà été haché EN LONG par les membres du fil de discussion sur le W3C et le WHATWG. Tu es assez en retard à cette fête.

Plusieurs personnes ont pris en charge une toute nouvelle API de chargeur, et il y avait plusieurs contre-arguments importants pour expliquer pourquoi ce n'était probablement pas la meilleure voie à suivre. Encore une fois, j'avais l'intention de vous écrire une réponse dans un article de blog prudent et raisonné, pour aider à expliquer tout cela.

Dommage que vous deviez y aller et être une telle bite ici. Maintenant, j'ai l'impression que cet article de blog raisonné ne sera qu'une perte de temps. Vous pensez évidemment que je suis un idiot et n'avez jamais pensé aux choses que vous essayez d'évoquer. Parce que je n'ai pas passé la majeure partie de l'année dernière à être absolument obsédé par la technologie du chargeur de script et comment obtenir les spécifications et les navigateurs pour l'améliorer. Ouais, je suis un idiot. Je n'ai clairement jamais pensé à autre chose qu'à la balise script auparavant.


Apparemment, vous n'avez pas écouté les 15 fois où j'ai dit que _ce_ fil avait le meilleur objectif de se concentrer sur les questions spécifiques soulevées par Paul Irish et Alex Sexton : est-ce que defer assez bon ? script-concat est-il meilleur que le chargement parallèle ?

Ce sont les questions les plus importantes.

Pas quelle technologie "loader" sous-jacente est utilisée. Il existe un forum différent et meilleur pour discuter de la technologie sous-jacente du chargeur. Je comprends, vous n'aimez pas la balise script. Amende. Allez passer des dizaines d'heures sur la liste W3C/WHATWG à essayer d'amener Ian et d'autres à vous écouter. Ils vont probablement tous bâiller et dire "nous avons déjà résolu ça, va-t'en".

@getify : Créer des tests ridicules d'homme de paille ne va pas te faire gagner des points, mon pote. Nous savons tous que les balises de script séquentiel bloquent la page. Nous savons également que l'exécution de blocs de scripts en ligne avant les scripts "différés" n'est en aucun cas un problème pour les sites réels.

Si vous testez pour confirmer une idée fausse, vos tests vont toujours confirmer cette idée fausse. Le débat n'a jamais porté sur 20 balises de script contre 20 charges de script LABjs. Il s'agit de découper, de concaténer, de réduire, de compresser et de charger intelligemment votre code JavaScript en aussi peu de requêtes HTTP que possible, puis de le mettre en cache.

D'une part, nous avons une approche fiable, compatible avec le navigateur et éprouvée, qui fonctionne manifestement mieux sur les pages du monde réel ; et d'autre part, nous avons une "technologie" piratée qui, dans le passé, a en fait cassé tous les sites qui l'utilisaient après une mise à jour du navigateur, qui fonctionne manifestement moins bien en moyenne, et avec un écart de lenteur bien plus important.

C'est un choix évident.

@jashkenas--

Nous savons également que l'exécution de blocs de scripts en ligne avant les scripts "différés" n'est en aucun cas un problème pour les sites réels.

Euh... Je suppose que vous n'avez pas fait de view-source sur environ 98% de tous les sites sur Internet, qui utilisent en fait des blocs de script en ligne dans le balisage pour exécuter/initialiser le code qu'ils ont chargé auparavant (blocage) appel de balise de script.

Si @paulirish suggère que defer est assez bon et que les chargeurs de script ne sont pas nécessaires, alors je pense qu'il est important de souligner pourquoi, en fait, defer N'EST PAS assez bon.

VOUS ne vous souciez peut-être que des quelques sites de niche que vous contrôlez, que vous avez la capacité totale d'être hautement optimisés sur les processus de construction, etc. De mon côté, je me soucie d'aider à améliorer les performances sur les sites Internet à longue traîne, ceux avec une demi-douzaine de balises de script (dont certaines sont des blocs de script en ligne !), où l'utilisation d'une demi-douzaine d'appels $LAB.script() améliorerait probablement les performances. C'est ce que LABjs a toujours été. Ce n'est pas parce que ce n'est pas ce qui vous intéresse que ce n'est pas pertinent.

Le débat n'a jamais porté sur 20 balises de script contre 20 charges de script LABjs.

Le débat dans ce fil est de savoir si 3-4 balises de script (avec ou sans defer ) fonctionnent moins bien, les mêmes ou mieux que 3-4 scripts chargés dynamiquement à l'aide d'un chargeur de script parallèle. Mes "tests ridicules de l'homme de paille" sont en fait destinés à tester exactement cela.

D'après mon expérience, les chargeurs de script réduisent de plusieurs millisecondes le temps de chargement de la page. Mais je pense que nous avons tous manqué le point ici. JavaScript a de plus gros problèmes :

  • Le manque d'instructions d'importation rend difficile l'organisation de votre code de manière modulaire
  • Les variables globales entrent en collision, à moins qu'une grande attention soit accordée à l'espacement des noms de tout.
  • Aucun moyen de voir clairement quelles sont les dépendances d'un script

Je n'utilise pas RequireJS car il se charge plus rapidement, bien que ce soit un bel effet secondaire. Je l'utilise pour organiser mon application JS en petits modules, un peu comme je le ferais dans NodeJS. Chaque module répertorie clairement ses dépendances et utilise le modèle de bac à sable pour garder l'espace de noms global propre. Les modules (et leurs dépendances) peuvent être chargés à l'avance, ou chargés à la demande (sur un clic de l'utilisateur par exemple), ou paresseux. Vous pouvez vraiment affiner vos performances avec ces techniques. Et RequireJS est également livré avec un outil de génération qui combine et minimise toutes les dépendances en un seul (ou une poignée de) fichier(s) gzip-ready pour le déploiement. Résoudre ces trois problèmes est une énorme victoire pour moi.

Je peux voir pourquoi les gens débattraient de l'utilisation d'un chargeur de script qui ne résout pas ces problèmes. Si la performance est le seul point, et son discutable, alors bien sûr. Mais utilisez un chargeur de module AMD comme RequireJS et le débat devient hors de propos. Les modules sont l'avenir de JavaScript. Dave Herman de Mozilla travaille avec des membres du conseil d'administration d'Apple et de Google pour ajouter des modules natifs au langage lui-même . Mais en attendant, nous pouvons obtenir tous les avantages en utilisant un chargeur de module AMD. Il ne s'agit pas seulement de performances.

@getify

Vous ne pouvez pas vous attendre à ce que les gens vous traitent différemment des autres. La condescendance n'est pas un moyen intelligent d'obtenir une réaction décente (et dieu êtes-vous condescendante) et, comme je l'ai dit dans mon article de blog, je ne pense pas que vous soyez un idiot, je pense juste que vous êtes obsédé (ce que vous dites vous-même) et que cela altère gravement votre jugement. Comme je l'ai dit dans mon article de blog, ce n'est pas au W3C ou au WHATWG de gérer ce problème mais à EcmaScript lui-même : ce n'est pas un problème de navigateur, c'est un problème de langue. Maintenant, ne faites pas cette réponse si vous ne le voulez pas, c'est votre prérogative.

Peut-être que je suis venu aussi dur, mais je défends juste ce en quoi je crois.

Je vais me désinscrire de ce fil et le commenter plus. Désolé d'avoir fait dérailler des trucs @paulirish et @SlexAxton.

@getify

VOUS ne vous souciez peut-être que des quelques sites de niche que vous contrôlez, que vous avez
capacité totale d'être hautement optimisé sur les processus de construction, etc. I sur le
d'autre part, soucieux d'aider à améliorer les performances sur les sites à longue traîne du
internet, ceux avec une demi-douzaine de balises de script (certains script en ligne
blocs !), où l'utilisation d'une demi-douzaine d'appels $LAB.script() serait en fait probablement
améliorer les performances. C'est ce que LABjs a toujours été. Juste parce que
ce n'est pas ce qui vous intéresse ne veut pas dire que ce n'est pas pertinent.

Si LABjs a pour but d'aider les sites médiocres à se charger un peu moins mal... c'est un objectif noble, je suppose. Mais si vous êtes sérieux au sujet de prendre un site Web à chargement lent et de le faire charger aussi vite que possible - potentiellement littéralement quelques secondes plus vite que LABjs le permettrait, alors il vous incombe de garder l'esprit ouvert et de reconnaître que le plus facile et le moins fragile la technique est aussi plus performante.

Le débat dans ce fil est de savoir si 3-4 balises de script (avec ou sans report)
fonctionne moins bien, autant ou mieux que 3-4 scripts chargés dynamiquement à l'aide
un chargeur de script parallèle. Mes « tests ridicules de l'homme de paille » sont en fait destinés à
tester exactement cela.

Le débat dans ce fil porte sur la façon de créer un site Web pour charger et exécuter son JavaScript le plus rapidement possible. Vendre de l'huile de serpent aux clients et en faire la promotion auprès des développeurs Web est un mauvais service pour les deux.

La latence existe sur Internet. Concaténez, minifiez et gzipez votre JS et chargez-le en bas de la page avec le moins de requêtes HTTP possible. dit Nuff.

@jashkenas--

Si LABjs a pour but d'aider les sites médiocres à se charger un peu moins mal... c'est un objectif noble, je suppose

Il y a des centaines de sites que je connais personnellement au cours des 2 dernières années qui n'ont fait que remplacer leurs balises de script par des appels $LAB.script() , et dans l'ensemble, ils ont tous vu de meilleures performances (certains de manière drastique, d'autres seulement modestement).

Il y a eu des articles écrits (complètement indépendants et non liés à moi) visant à aider les sites de divers secteurs (comme le commerce électronique, l'immobilier, etc.) à obtenir de meilleures performances (car de meilleures performances signifient plus de conversions), où ces articles sont recommandés aux sites qui ils remplacent les balises de script par des appels $LAB, et de nombreuses personnes dans ces fils de commentaires ont répondu par l'affirmative que cela les avait aidées.

Si ces articles avaient dit "OK, ce que vous devez faire pour obtenir plus de performances est d'embaucher un administrateur de serveur qui comprend gzip et peut installer ruby ​​ou node.js afin que vous puissiez effectuer des processus de construction automatisés......." ces personnes la lecture de ces articles aurait glacé et serait parti sans y penser une autre fois. Mais j'aime croire que "Hé, remplacez <script> par script()" était un message assez facile à comprendre et à utiliser.

Ce que je voulais pour LABjs, c'est une solution simple dans laquelle quelqu'un peut facilement remplacer ses balises de script sans trop réfléchir. Je reconnais que si vous pouvez consulter personnellement un site et trouver les meilleures optimisations, vous pouvez obtenir beaucoup plus de performances sur de nombreux sites. Mais je reconnais aussi que c'est bien au-delà de ma capacité en tant que personne à faire pour la longue traîne d'Internet, et de la même manière, dire à tous ces sites maman&pop "hé, va chercher un système de construction automatisé, et assurez-vous qu'il utilise gzip" est comme leur parler une langue étrangère. OTOH, ça a été assez réussi de dire "Hé, prends ces 3 balises de script, et fais-leur 3 appels de script(). Tu vois comme c'était facile ?"

En bout de ligne, mon approche avec LABjs était de frapper le fruit à portée de main.

Rien de tout cela ne suggère que des approches d'optimisation plus sophistiquées ne sont pas possibles - elles le sont clairement, et lorsque j'ai l'occasion de consulter, je les explore définitivement. C'est juste pour dire que pour une grande partie du Web, c'est plus impliqué/compliqué qu'ils ne veulent ou ne peuvent l'obtenir. Et j'essaie juste d'aider _ces_ sites à s'améliorer d'une manière qui leur est plus facile à comprendre.

@jashkenas--

potentiellement littéralement secondes plus vite que LABjs le permettrait, alors il vous appartient de garder l'esprit ouvert et de reconnaître que la technique plus facile et moins fragile est également plus performante.

Il n'y a jamais eu de preuves établies suggérant que LABjs ralentit considérablement les sites. Il y a BEAUCOUP de preuves établies que cela aide beaucoup de sites. Donc, je n'accepte pas cela -- ce dont vous parlez est une fausse prémisse en supposant que des faits ne sont pas des preuves.

@paulirish a trouvé un article qui signale des problèmes avec l'attribut defer :
http://hacks.mozilla.org/2009/06/defer/

Du point de vue des performances mobiles - comme l' @jashkenas , il est toujours préférable de concaténer, de gzip et de l'envoyer sur la ligne en un seul paquet plutôt que d'avoir plusieurs requêtes http en raison de la latence engendrée par les connexions réseau 3g.

De nombreuses recherches sont en cours pour utiliser des techniques d'inline où vous encodez des images en base64 dans des chaînes, puis les stockez sous forme de paires clé:valeur dans localStorage juste pour réduire les requêtes http et tirer parti de la "mise en cache": http://channel9.msdn.com/Events /MIX/MIX11/RES04 est une excellente présentation de James Mickens de Microsoft Research.

Voici un très bon deck sur les performances mobiles avec les requêtes http et ses effets sur l'expérience utilisateur : http://davidbcalhoun.com/present/mobile-performance/

Je travaille sur RequireJS et je souhaite clarifier ce que RequireJS vise à faire :

1) Montrez la voie au code modulaire dans JS qui fonctionne bien partout où JS s'exécute.
2) Chargez les scripts.

La partie « charger les scripts » est une partie nécessaire pour atteindre le premier objectif. En développement, ce n'est pas une bonne idée de simplement concaténer tous vos scripts car cela rend le débogage plus difficile, les numéros de ligne ne correspondent pas. Les chargeurs de scripts facilitent également l'utilisation d'une API JS pour charger du code à la demande. Pour les applications de taille de messagerie Web, il s'agit d'une partie nécessaire de l'histoire des performances. Cependant, la concaténation des scripts en une ou un petit nombre de requêtes est généralement la meilleure option de déploiement.

Mais le but de requirejs est d'être le shim/polyfill/whatever pour montrer comment créer et référencer des unités de code modulaires qui peuvent être partagées avec d'autres d'une manière qui décourage les globals et encourage les dépendances explicites.

Il utilise l' API AMD qui a été élaborée avec d'autres personnes créant des chargeurs de scripts modulaires (y compris des tests de conformité ), dans le but d'aider à éclairer toute discussion sur un format de module en JS. Cette approche, en réalisant des implémentations dans le monde réel et en concluant un accord avec d'autres sur l'API, est la façon dont les progrès sont réalisés.

En particulier, étant donné la nature réseau de JS et sa relation avec les documents/applications Web, l' API du plug-in de chargement devrait être prise en charge d'une manière ou d'une autre avec les modules ES Harmony, et je travaille sur le prototypage des modules ES Harmony

Pour les gens de la performance :

  • Il existe quelques choix de chargeurs prenant en charge AMD ( curl , Dojo 1.7 , loadrunner , requirejs), même un très petit qui peut être utilisé pour l'optimisation "tous les scripts dans un fichier JS" effectuée pour le déploiement. Il est donc possible d'obtenir d'excellentes performances tout en encourageant les meilleures pratiques de codage - un partage de code plus facile en évitant les globals, en utilisant des dépendances explicites.
  • L' optimiseur requirejs s'exécute très rapidement dans Node et peut s'exécuter dans Rhino. C'est un outil en ligne de commande, mais le dernier code de branche maître l'exporte en tant que module utilisable dans Node, donc par exemple, il peut être exécuté via un serveur http basé sur Node qui peut faire la construction à la volée . Vous pouvez donc toujours développer en mode « un script à télécharger toujours » si vous préférez, mais choisissez ensuite de laisser de côté un ou deux modules de ce fichier optimisé, afin de pouvoir les déboguer facilement.

Dans le cadre de ce ticket : choisir un loader compatible AMD (n'a pas besoin d'être requirejs) s'inscrit dans les objectifs du passe-partout HTML : montrer la voie aux bonnes pratiques, à la fois en code et en performance. Cependant, j'apprécie qu'essayer de travailler sur un HTML passe-partout est une chose très difficile à faire, il y a des intérêts concurrents, certains stylistiques, donc j'apprécie de ne pas vouloir faire de recommandation dans ce domaine pour le moment.

Je veux juste préciser que l'objectif des requirejs et des chargeurs qui implémentent l'API AMD offrent un avantage plus important que le simple chargement de scripts qui vident les globals et obligent le développeur à élaborer l'arbre de dépendances complet, parfois implicite. Ces objectifs sont atteints avec des solutions qui ont des profils de performance solides.

Pour se recentrer sur le précédent... en comparant le test defer test LABjs... (et en ignorant le fait que defer ne fonctionne pas sur les blocs de script en ligne), est-ce que quelqu'un voit que le Le test LABjs fonctionne moins bien que le test defer ? Je l'ai essayé sur un tas de navigateurs, et même sur mon appareil mobile, et je vois toujours des nombres à peu près égaux.

http://labjs.com/dev/test_suite/test-script-defer-tags.php

http://labjs.com/dev/test_suite/test-LABjs.php

@getify

Je ne sais pas pourquoi ni comment vous pouvez optimiser cela, mais j'ai, sur ma machine MacBook de 3 ans et plus, une différence constante de 3000 entre les deux, ce qui favorise @defer .

Cependant, je n'ai testé qu'avec Firefox.

@espadrine-- assez étrange. j'adorerais aller au fond des choses. avec quelle version de Firefox testez-vous ? pouvez-vous m'envoyer une capture d'écran des résultats?

Il suffit de concaténer et de réduire tous vos JS et CSS et de les insérer directement dans votre page HTML et d'en finir. Requête HTTP unique FTW ! :P

Sérieusement, il y a tellement de problèmes plus importants sur lesquels nous devrions nous concentrer dans cette communauté que la façon dont votre application va se charger. Il y a de fortes chances que la méthode la plus simple (balises de script en bas) soit probablement assez rapide. Écrivez simplement d'excellentes applications et gérez les performances de chargement à la fin. Faire autre chose, c'est optimiser prématurément.

Y a-t-il un consensus général parmi les gens sur ce fil qu'AMD devrait être l'étalon-or pour l'organisation du code JS ? Je n'ai pas vraiment vu d'autres options, mais je suis d'accord que le Boilerplate serait un bon début pour mettre les gens en place dans l'organisation du code.

Canal de mise à jour de Firefox UX 8.0a1 (2011-08-07).

defer
LABjs

Encore une fois, aucune idée pourquoi, et c'est probablement très spécifique. LABjs est probablement très bon avec les navigateurs hérités.

Veuillez ne pas utiliser la page de test de @getify pour autre chose que pour rire. Citer:

<script defer src="http://labjs.xhr.me/dev/test_suite/testscript1.php?_=4911710&delay=5"> <script defer src="http://labjs.xhr.me/dev/test_suite /testscript2.php?_=6146431&delay=3"> <script defer src="http://labjs.xhr.me/dev/test_suite/testscript3.php?_=9499116&delay=1">

@getify , si vous voulez faire un vrai test, n'hésitez pas à forker le dépôt AssetRace de @SlexAxton et ajouter une version LABjs ...

Assurez-vous également de concaténer le JS pour une seule balise de script -- defer ou non. Le fait est que le même contenu servi sur 1 requête HTTP bat le même contenu servi sur 10 requêtes HTTP.

Il n'y a jamais eu de preuves établies suggérant que LABjs est significativement
ralentir tous les sites. Il y a BEAUCOUP de preuves établies que cela aide beaucoup
de sites. Donc je n'achète pas ça -- ce dont vous parlez est une fausse prémisse en supposant
faits non mis en évidence.

Ce qui a été démontré ci - @getify : J'aimerais voir un lien vers un site qui, selon vous, a grandement démontré sa conversion en LABjs. Peut-être pouvons-nous en télécharger une copie et l'utiliser comme cas de test que vous respecterez.

Pour mémoire, je pense qu'il serait sage d'obtenir plus d'images dans la page de test du repo AssetRace. Mais c'est certainement une bonne base de référence en ce moment.

@artzstudio organiser votre JS avec un chargeur AMD est en effet l'étalon-or, du moins jusqu'à ce que les modules d'Harmony soient terminés et largement pris en charge. Ensuite, il y aura un chemin de migration clair des modules AMD vers les modules natifs.

Les modules AMD étant l'étalon-or est certainement une opinion (une opinion que je peux partager). Cependant, il y a beaucoup de gens intelligents (je pense à Yehuda Katz et Dan Webb) qui ne l'aiment pas et proposent d'autres solutions.

Le loadrunner de @danwrong peut faire les deux, si c'est aussi votre sac : https://github.com/danwrong/loadrunner

De très bonnes choses là-dedans. Potentiellement un peu plus pratique pour les non-JS également. J'aime les modules AMD pour mes affaires, mais tout le monde ne veut pas passer du temps à convertir chaque version des bibliothèques qu'ils utilisent en modules.

Je sais que @strobecorp travaille sur sa propre solution qui ne nécessite pas beaucoup de code supplémentaire requis par les modules AMD.

Bien que j'aimerais qu'AMD soit la valeur par défaut, ce n'est probablement pas sage d'un point de vue multi-bibliothèque/newb, autant que je le souhaite.

@jashkenas--

Veuillez ne pas utiliser la page de test de @getify pour autre chose que pour rire.

Si vous ne pouvez pas être civil, je n'ai aucune envie de discuter de quoi que ce soit d'autre avec vous. J'agis de bonne foi. J'apprécierais un peu de décence commune.

@getify , si vous voulez faire un vrai test

J'aimerais bien que vous m'expliquiez pourquoi ce que je fais est si fou, risible et invalide. J'ai suivi l'approche directement de Steve Souders, qui (dans sa grande expérience et sa sagesse) a suggéré dans tous ses tests que vous utilisiez la synchronisation du serveur pour contrôler les scripts, réduisant ainsi la quantité de variance dans vos tests. C'est exactement ce que je fais.

Un test plus contrôlé est un test de base valide. C'est une pratique scientifique établie. Cela ne veut pas dire que les tests du monde réel ne sont pas aussi utiles, mais cela ne veut pas dire non plus que vous pouvez me tirer dessus et dire "rire de lui, quel idiot parce qu'il fait ses tests différemment de ce que je pense qu'ils devrait être fait."

n'hésitez pas à forker le dépôt AssetRace de @SlexAxton et à ajouter une version LABjs

Je le ferai avec plaisir. Mais pas parce que je suis d'accord que mes autres tests sont invalides. Si vous avez des arguments raisonnés et équilibrés pour expliquer pourquoi ma configuration de test n'est pas valide, veuillez les partager. Mais arrête d'être un con à ce sujet.

@jashkenas--

Le fait est que le même contenu servi sur 1 requête HTTP bat le même contenu servi sur 10 requêtes HTTP.

Je sais que vous (et d'autres) continuez à vous plaindre ici de la façon dont cette discussion devrait porter sur le concat par rapport au non-concat. Si vous avez lu beaucoup plus tôt dans le fil, j'ai admis qu'il y avait deux questions qui devaient être abordées. Les deux questions sont, en ce qui me concerne, orthogonales. Le premier est de savoir si les balises de script dans le balisage peuvent être aussi bonnes (ou meilleures) que les éléments de script dynamiques utilisés dans un chargeur de script parallèle. CETTE QUESTION est ce que j'essaie toujours d'aborder avec mes tests.

La deuxième question, à laquelle nous n'avons pas encore abordé, est de savoir si script-concat est toujours meilleur. Je sais que vous en êtes déjà convaincu, mais j'ai des contre-preuves pour suggérer que ce n'est pas si simple. Cette question doit également être soigneusement testée. Mais ce n'est pas ce que j'essaie de comprendre en ce moment dans ce fil.

En continuant à insister sur le fait que votre voie est la meilleure, vous ne faites que rendre l'ensemble du débat moins agréable. Tout ce que j'essaie de faire, c'est d'établir méthodiquement des preuves pour chacune de ces deux questions principales, afin que nous puissions arrêter de deviner et être plus informés. Pourquoi n'est-ce pas quelque chose que vous pouvez aider, au lieu d'essayer d'être un imbécile avec moi parce que vous n'êtes pas d'accord avec moi ?

En ce qui concerne le test defer rapport au test LABjs, je viens de faire une capture d'écran rapide pour tester les deux face à face dans IE9, FF8 (nuit) et Chrome15 (canari).

http://www.screenr.com/icxs

Pour répondre à la question précédente de defer , regardez comment "DOMContentLoaded" se comporte dans IE, Chrome et Firefox dans le test defer .

Dans IE9 et Chrome15, l'événement DOMContentLoaded est suspendu (bloqué) et n'est déclenché qu'après l'exécution des scripts. Dans FF, cependant, l'événement DOMContentLoaded n'est pas retardé, il se déclenche immédiatement et les scripts commencent à s'exécuter après lui. C'est une énorme incohérence entre les navigateurs modernes, et l'une des raisons pour lesquelles je ne pense pas que defer soit suffisant.

Pour autant que je sache en lisant les spécifications, je ne sais pas quel comportement est correct. Mais je sais que c'est clairement bizarre et incohérent entre les navigateurs.

@getify Je n'essaie pas d'être un imbécile. Je m'excuse sincèrement d'avoir blessé vos sentiments.

Naturellement, ce que vous voyez comme de la diatribe, je le vois comme le point de la discussion... et ce que je considère comme de l'huile de serpent, vous le voyez comme un pas en avant utile.

Les deux problèmes sont en effet orthogonaux (langage que j'ai utilisé dans mon post initial).

La première est de savoir si les balises de script dans le balisage peuvent être aussi bonnes (ou meilleures) que
éléments de script dynamiques utilisés dans un chargeur de script parallèle.

Nous sommes tout à fait d'accord sur cette question, cela n'a pas d'importance. Bien sûr, le chargement parallèle sera plus rapide que le chargement séquentiel pour plus d'un script. Et bien sûr, le faire de manière non bloquante, soit à la fin de la balise <body> , soit avec defer , soit avec un script loader, sera mieux que de bloquer dans le <head> .

Mais cela manque le point. Mettre des balises de script séquentielles est un homme de paille à comparer, car personne qui se soucie des performances de leur JavaScript n'utiliserait cette approche. Devinez ce qui est aussi plus rapide que les balises de script séquentiel ? _N'importe quoi_.

La deuxième question, à laquelle nous n'avons pas encore répondu, est de savoir si
script-concat est toujours mieux.

Nous avons « arrivé à » cette question. En fait, c'est la question de

Cette question doit également être soigneusement testée.

Pour me répéter, voici un cas de test (juste). Les mêmes 5 scripts du monde réel, se chargeant sur une page de taille moyenne avec d'autres actifs présents, l'un utilisant les meilleures pratiques de LABjs pour assurer l'ordre de chargement, et l'autre utilisant un seul script concaténé :

http://jashkenas.s3.amazonaws.com/misc/snake-oil/labjs.html

http://jashkenas.s3.amazonaws.com/misc/snake-oil/vanilla.html

Si vous avez un autre cas de test que vous aimeriez examiner, ou un site Web réel utilisant LABjs que vous aimeriez expérimenter, veuillez le partager.

@SlexAxton Merci. Je serais curieux d'entendre le point de vue de Yehuda à ce sujet et d'autres opinions bien arrêtées (à part que c'est trop difficile à refactoriser). J'ai trouvé ça mais pas le discours.

Pour clarifier le commentaire de @geddesign : à ce jour, il semble que les modules AMD puissent être convertis assez facilement en modules d'harmonie, mais cette proposition de modules d'harmonie que je considère toujours en évolution, elle pourrait changer plus tard. Il n'a pas encore fait l'objet d'un test de mise en œuvre rigoureux, mais commence à prendre des mesures. Du côté positif, les chargeurs AMD + les plugins de chargeur peuvent donner un retour solide pour essayer certaines des idées d'harmonie.

Au commentaire de

Pour loadrunner : il n'est pas clair pour moi que la syntaxe soit meilleure, juste différente. Il prend en charge AMD, donc ça marche toujours.

Pour le stroboscope : je n'ai pas encore vu le code d'eux dessus. Ils semblent assez centrés sur eux-mêmes, même si j'apprécie le travail que Yehuda a fait pour ouvrir ce développement. Alex, si vous avez des indications sur ce qu'ils pensent, j'apprécierais de les avoir.

Si l'approche doit autoriser les dépendances imbriquées (ce qui est nécessaire pour le partage de code étendu), vous avez besoin d'une syntaxe qui :

  • donne un nom à une unité de code
  • un moyen de spécifier les dépendances
  • un wrapper de fonction autour de ce code pour s'assurer qu'il ne s'exécute pas tant que les dépendances ne sont pas prêtes. Ou exigez toujours une version ou un accès XHR, qui n'est pas évolutif dans tout le spectre du développement JS.

C'est ce que fournit AMD, et la syntaxe est aussi fine que possible. Tout le reste ne fait que se battre pour les noms et peut-être certains types de ponctuation. À un moment donné, il faut juste choisir quelque chose, et jusqu'à présent, je n'ai pas entendu parler de Dan Webb ou de Yehuda sur les faiblesses structurelles qui rendent AMD intenable. Certains chargeurs AMD, comme requirejs, ne peuvent charger que des scripts normaux, ils n'ont pas besoin d'être des modules.

Il est très facile de penser à la syntaxe du code, en particulier pour les modules, et je peux comprendre que chacun a ses propres préférences personnelles. Cependant, AMD a une histoire assez profonde de travail acharné pour obtenir une sorte d'accord, et plus important encore, un code et un déploiement réels pour le sauvegarder. Je pense qu'il incombe maintenant aux autres d'être très clair et clair sur les raisons pour lesquelles AMD ne convient pas (ce ticket n'est pas l'endroit pour cela, n'hésitez pas à me contacter hors liste ou à utiliser la liste amd-implement ) .

Mais j'apprécie le point de vue de

@SlexAxton je suis avec toi. Mon propre code est AMD tout le chemin. Bien que je souhaite que tout le monde écrive des modules au lieu de scripts, heureusement, RequireJS peut charger des scripts simples ainsi que des modules.

Si vous faites référence aux modèles handlebars.js de Yehuda, ceux-ci fonctionnent extrêmement bien avec RequireJS. Surtout si vous écrivez un plugin qui compile/met en cache le modèle et renvoie sa fonction de modèle.

define(['tmpl!navigation.html'], function(nav){
   $('body').append(nav(data));
});

Je ne suis pas d'accord avec cette affirmation cependant :

Bien que j'aimerais qu'AMD soit la valeur par défaut, ce n'est probablement pas sage d'un point de vue multi-bibliothèque/newb, autant que je le souhaite.

Les débutants ont besoin de la structure propre qu'AMD fournit encore plus qu'un développeur chevronné, car ils sont plus sujets aux collisions de variables globales, à une organisation de code terrible qui conduit à d'énormes fichiers JS désordonnés que personne ne veut toucher de peur d'avoir à faire face à des conflits de fusion, etc. Les bibliothèques bénéficient énormément des modules, c'est pourquoi les prochains Dojo 1.7 et Mootools 2.0 migrent vers AMD. J'espère que jQuery va embarquer - l'une de ses plus grandes plaintes est que c'est "tout ou rien". Vous ne pouvez pas utiliser son excellente manipulation DOM sans également charger son animation, son ajax, ses événements, etc. sur la page. Alors oui, AMD est un gagnant-gagnant. Si HTML5 Boilerplate veut orienter les gens vers les meilleures pratiques, il serait dommage de laisser de côté AMD. Il résout avec élégance tant de problèmes de JavaScript.

Pour être clair. Je suis d'accord. Je souhaite qu'ils aient utilisé tout le chemin.

Je ne pense pas qu'ils le feront.

Je ne pense pas que les gens réalisent encore qu'AMD est un mot à la mode, une "chose" que tout développeur sérieux doit connaître. Une fois qu'ils l'auront fait, ils voudront dire à leurs patrons et aux futurs entretiens qu'ils le savent et l'utilisent.

Si nous faisons tous notre part et disons « voyez, c'est facile, meilleur et important » et en faisons un mot à la mode, les troupeaux suivront pour le bien de leur carrière.

@jashkenas--

Le premier est de savoir si les balises de script dans le balisage peuvent être aussi bonnes (ou meilleures) que les éléments de script dynamiques utilisés dans un chargeur de script parallèle.

Nous sommes tout à fait d'accord sur cette question, cela n'a pas d'importance.

En fait, j'ai commencé ma participation à ce fil en supposant que tout le monde était d'accord sur le fait que le chargement dynamique des éléments de script allait conduire à de meilleures performances que les balises de script. Mais @paulirish et @slexaxton ont remis en question cette hypothèse dans _ce_ fil.

@paulirish a suggéré que defer est un moyen suffisant pour rendre la balise de script simple aussi bonne (ou meilleure) que l'alternative de chargement d'élément de script dynamique. Je ne suis pas d'accord pour dire que defer est suffisant, et j'ai maintenant établi plusieurs raisons pour lesquelles.

Donc, je pense qu'il EST valable pour nous d'avoir examiné la première question et d'avoir exploré si defer était meilleur que les chargeurs de script. Il peut y avoir quelques cas limités où vous pouvez vous en sortir avec defer , mais en ce qui concerne le cas généralisé, les chargeurs de script gèrent/normalisent toutes les bizarreries, alors que defer vous expose à ces problèmes.

Je ne suis toujours pas sûr que tout le monde comprenne ou soit d'accord avec les raisons defer lesquelles

Pour me répéter, voici un cas de test (juste). Les mêmes 5 scripts du monde réel, se chargeant sur une page de taille moyenne avec d'autres actifs présents, l'un utilisant les meilleures pratiques de LABjs pour assurer l'ordre de chargement, et l'autre utilisant un seul script concaténé :

C'est votre fausse prémisse de test (et celle des autres). Je n'ai jamais prétendu que le chargement de 5 scripts au lieu de 1 serait plus rapide. Jamais. Déjà. Puis-je être plus clair ? La prémisse n'a jamais été 5 contre 1.

Le premier test consistait à tester 3 balises de script contre 3 appels script() , car c'est un test juste. Et je pense que la vidéo et les tests illustrent que le chargement de script, dans CE scénario, est bénéfique.

La deuxième question, beaucoup plus complexe à tester, est de savoir s'il existe un moyen d'améliorer les performances d'un site qui charge déjà tout son JS dans un seul fichier. La plupart des gens disent qu'il est impossible d'améliorer cela. Je ne suis pas d'accord.

REMARQUE : la raison pour laquelle cette question est orthogonale est que vous pouvez charger ce fichier concat unique soit avec une balise de script, soit en utilisant un chargement dynamique de type document.createElement("script") . Dans tous les cas, la question d'un seul fichier concat est une question valide, mais distincte de la question de savoir si les balises de script ou le chargement de script dynamique sont meilleurs.

Ce que vous m'avez entendu dire à plusieurs reprises dans ce fil, et également dans de nombreux autres contextes (y compris toutes mes conférences sur le sujet, les articles de blog, etc.), c'est que je pense qu'il est possible que vous puissiez améliorer le seul fichier JS concat approche en "chunking" (c'est-à-dire en divisant le gros fichier concat) en 2 ou 3 morceaux (au maximum). Si les morceaux sont de taille ~égale et sont chargés en parallèle, il est alors possible que la page se charge plus rapidement, même avec la surcharge HTTP supplémentaire, en raison de la connexion "Keep-Alive", de l'effet de chargement parallèle, etc.

En fait, j'écrivais sur ce sujet il y a LONGTEMPS, en novembre 2009, peu de temps après la première version de LABjs : http://blog.getify.com/2009/11/labjs-why-not-just-concat/

Dans cet article de blog, et depuis lors, j'ai dit que SI vous êtes en mesure (ce n'est pas tout le monde... en fait, la plupart du Web ne l'est pas) d'utiliser des processus de construction pour concaténer, vous devriez le faire donc. Période. Toujours. Concatez toujours les fichiers de 10 à 20 fichiers locaux à beaucoup moins.

MAIS, je dis aussi qu'une fois que vous avez ce fichier concat unique, il peut également être avantageux d'essayer de charger votre fichier unique en 2-3 morceaux, chargés en parallèle (à l'aide d'un chargeur de script).

Pourquoi cela pourrait-il être mieux? Je l'ai souligné dans cet article de blog, mais en bref :

  1. l'effet de chargement parallèle est réel. interrogez les utilisateurs de bit-torrent à ce sujet. la surcharge HTTP est également réelle et agit pour contrer et éliminer cet avantage. Mais cela ne veut pas dire qu'il est impossible d'en bénéficier. En utilisant la connexion Keep-Alive, il est possible que vous puissiez obtenir 2 ou 3 connexions simultanées (sans pénalités de frais généraux de connexion 2-3) et charger votre code dans un laps de temps plus court. Est-ce que ce sera 1/3 du temps (60-70% plus rapide) si vous le chargez en 3 morceaux ? Non. Absolument pas. Mais cela peut être 20 à 30 % plus rapide.
  2. Servir tout votre code dans un seul fichier vous empêche de créer différents en-têtes de cache pour différents codes à vie. Par exemple, jquery est très stable et n'a jamais besoin d'être retéléchargé. mais votre code centré sur l'UX sur votre site peut être très volatile (vous pouvez le modifier une fois par semaine ou plus). Faire de courts en-têtes de mise en cache sur le seul fichier concat est stupide, car cela force inutilement des re-téléchargements plus fréquents de code stable. Faire de longs en-têtes de mise en cache sur le fichier concat unique est également stupide, car cela vous oblige à invalider le fichier mis en cache (param de bust de cache, etc.) code plus volatile. Ainsi, diviser votre gros fichier concat en 2 morceaux, un pour le code stable, un pour le code volatile, vous permet d'avoir différents en-têtes de mise en cache pour chaque morceau. Cela permet une utilisation plus efficace du cache et conduit à des performances potentiellement meilleures au fil du temps, car les utilisateurs reviennent visiter votre site à plusieurs reprises.
  3. Des études ont montré qu'en moyenne, une seule page vue utilise bien moins de 100 % du JS qui est chargé sur la page (certaines estimations l'évaluent à environ 20 à 30 % du code). Charger tout votre code d'un seul coup, d'un seul coup, au début du chargement de la page, encombre inutilement la ligne pour pousser 70 à 80 % du fichier qui n'est alors pas nécessaire (et peut « jamais » être nécessaire). Si vous avez votre code en 2 morceaux (un qui est le code le plus critique et un autre qui est le code moins critique), et que vous chargez le premier morceau tout de suite, et chargez le deuxième morceau quelques secondes après le chargement de la page, vous pouvez libérer le tuyau pour les images/css et le contenu beaucoup plus importants. Essentiellement, le découpage vous permet de hiérarchiser votre code.

En bout de ligne... sur le sujet de concat vs parallèle... Je dis toujours aux gens : les deux.

@getify bien dit.

Les LABjs de Kyle ont mon soutien.
En tant que consultant aidant les sites à améliorer leurs performances, j'ai vu plusieurs fois les LABjs bien fonctionner.
Non seulement cela a considérablement amélioré les performances (pas seulement 100 ms, mais plus de 1 seconde), mais les développeurs l'ont également apprécié.
Facile à comprendre, facile à mettre en œuvre.

Et je profite de cette occasion pour dire publiquement « Merci Kyle, pour le grand soutien sur LABjs. Vous avez dépassé mes attentes plusieurs fois. »

En utilisant la connexion Keep-Alive, il est possible que vous puissiez obtenir 2 ou 3 connexions simultanées (sans frais généraux de connexion 2-3 complets)

HTTP ne multiple/entrelace pas les réponses, vous ne pouvez donc pas effectuer de téléchargements parallèles sans ouvrir d'abord plusieurs connexions. Le cas idéal d'une connexion persistante et pipeline est égal au téléchargement contigu d'un seul fichier (+ quelques en-têtes).

@pornel--

J'ai vu de première main et validé que les navigateurs peuvent ouvrir plusieurs connexions en parallèle sur un seul serveur, où avec Connection Keep-Alive en jeu, la surcharge pour les deuxième et troisième connexions est considérablement inférieure à celle de la première. C'est de cet effet dont je parle.

@getify Fantastic, je pense que nous avons atteint une sorte de consensus. Pour vous rafraîchir la mémoire :

Je peux anticiper un contre-argument sur le chargement de vos scripts par morceaux ...
mais c'est tout à fait orthogonal à la technique de chargement du script, alors s'il vous plaît, laissez-le de côté
du débat.

Oui, je suis d'accord pour dire que charger vos scripts volatiles dans un fichier JS différent de vos scripts permanents est génial. Charger le script qui n'est nécessaire que pour une page spécifique, uniquement sur cette page spécifique, est tout aussi génial.

Donc, si je suis un développeur Web et que j'ai une page avec un tas de JavaScript, que dois-je faire ? Utilisez LABjs, ou concaténez mes scripts permanents dans un fichier et mes scripts volatiles dans un autre, et chargez les deux au bas de la balise body avec <script defer="true"> ?

Pourquoi devrais-je soumettre mon application à des problèmes de mise en cache, à des incompatibilités de navigateur, à une course contre les images sur la page et au reste des problèmes qu'apporte un chargeur de script ?

Si le principe de l'utilisation d'un chargeur de script pour la performance est que c'est plus facile et plus simple que d'utiliser deux balises de script... J'ai un pont à Brooklyn à vous vendre.

@getify ayant implémenté un serveur web plus d'une fois : keep-alive n'affecte en rien les requêtes simultanées et ne fait que réduire les coûts des requêtes suivantes. Un corps divisé avec deux requêtes successives avec keep-alive est toujours plus cher qu'une seule requête. Avoir deux requêtes simultanées pour les deux parties du corps fonctionnera probablement mieux, mais gardez à l'esprit que le navigateur n'ouvrira qu'un nombre limité de requêtes simultanées (selon le navigateur et la configuration, environ 5, je pense), ce qui est bien si tout vous chargez vos trois fichiers js, mais c'est, comme @jashkenas l'a souligné plus d'une fois, un problème si vous avez d'autres actifs, comme des images ou des fichiers css.

@jashkenas-

Donc, si je suis un développeur Web et que j'ai une page avec un tas de JavaScript, que dois-je faire ? Utiliser LABjs, ou concaténer mes scripts permanents dans un fichier et mes scripts volatiles dans un autre, et charger les deux au bas de la balise body avec <script defer="true"> ?

TL ; DR : les deux

Premièrement, de nombreux sites sur le Web sont assemblés par des CMS, ce qui signifie qu'il est courant d'avoir des blocs de script en ligne éparpillés sur toute la page, et TRÈS difficile à résoudre en termes de maintenance en disant simplement " déplacez tout ce code dans un seul fichier ". Donc, je pense que la prémisse selon laquelle _la plupart_ des sites peuvent s'en sortir sans avoir de "code en ligne" à exécuter après le chargement et l'exécution d'un autre script externe est au mieux peu probable.

Deuxièmement, j'ai prouvé que defer agit différemment par rapport à DOMContentLoaded dans divers navigateurs. Dans certains navigateurs, les scripts vont avant DOM-ready, dans d'autres navigateurs, ils vont après DOM-ready. Si vous avez du code dans vos scripts qui repose sur le fait qu'il se produise avant ou après le DOM-ready, l'utilisation de defer peut être un problème. C'est d'autant plus vrai que c'est un domaine sensible avec beaucoup d'incompréhension et de confusion, donc ça devient vite "ce n'est pas une solution simple et directe". Cela demande beaucoup plus de réflexion.

Troisièmement, je pense que pour beaucoup de sites, changer leur balisage pour utiliser $LAB.script() au lieu de &lt;script> est beaucoup plus facile que de leur expliquer comment installer un processus bulid automatisé (ou manuel) sur leur serveur. Surtout si ce site est hébergé sur un hébergement partagé (la majeure partie du Web l'est) et qu'ils ne contrôlent pas vraiment une grande partie de leur serveur, leur demandant de comprendre les processus de construction afin que la maintenabilité de leur code ne soit pas perdue, c'est... eh bien. .. non trivial.

Ces choses peuvent-elles être surmontées ? Ouais. Bien sûr qu'ils le peuvent. Mais ils demandent beaucoup de travail. Dans certains cas (comme la chose prête pour DOM), ils peuvent prendre en fait un ajustement minutieux de votre code. Il faut une personne avec des efforts dévoués et beaucoup d'expertise et de passion dans ce domaine pour tout régler.

En revanche, ils peuvent obtenir un "gain rapide" dans LABjs au lieu de la balise &lt;script> . Il y a peu de choses auxquelles ils doivent penser (sauf document.write() ). La plupart du temps, "ça marche". Et la plupart du temps, ils constatent une augmentation immédiate de la vitesse de chargement des pages. Pour la plupart des sites, c'est une grande victoire.

Donc, pour répondre à votre question, je dirais, comme je l'ai déjà dit, faites les deux ... Première chute dans LABjs, voir quelques augmentations de vitesse immédiates. Maintenant, considérez fortement les avantages d'utiliser un processus de génération pour vous déplacer de 15 fichiers à 2 fichiers (1 fichier divisé en deux). Lorsque vous faites cela (si vous faites cela, ce qui, comme je l'ai dit, la plupart ne le feront pas), vous pouvez abandonner les LABjs si vous le souhaitez vraiment. Mais il n'y a pas vraiment de mal (il est petit et se cache bien, même sur mobile). Il continuera à bien charger vos deux morceaux de fichiers, ET il le fera sans les bizarreries que defer pourraient causer.

De plus, le fait d'avoir déjà LABjs là-bas rend stupidement simple l'étape 3, qui consiste à commencer à déterminer quel code vous pouvez "charger paresseux/à la demande" plus tard. Vous ne pouvez pas le faire sans un chargeur de script. Avoir LABjs déjà là et familier signifie que vous n'avez pas du tout à vous soucier de la façon de charger ce script à la demande - c'est déjà compris.

@rkh--

On m'a montré (en particulier dans Apache, en basculant le paramètre Keep-Alive) comment plusieurs requêtes parallèles étaient affectées (positivement lorsque Keep-Alive était présent). Je ne suis pas un expert dans ce domaine, donc discuter des détails exacts de son fonctionnement ou non me dépasse. Je peux dire que le timing de la demande #2 était moins que le timing de la demande #1, quand Keep-Alive était là. Comment le navigateur et le serveur ont fait cela, je ne peux que faire des suppositions partiellement informées.

Un corps divisé avec deux requêtes successives avec keep-alive est toujours plus cher qu'une seule requête.

Je n'ai jamais soutenu que la deuxième demande est gratuite. J'ai soutenu que la deuxième demande n'est pas aussi chère que la première demande. Donc, si nous supposons qu'au moins une requête doit être faite, avoir une deuxième requête en parallèle n'est PAS la même chose que d'avoir deux connexions complètement indépendantes au même serveur, en termes de frais généraux ou de temps.

À titre d'estimation, il semblait que la demande n°1 était X à desservir, et n°2 en parallèle avec le présent Keep-Alive était de 0,7X. Il m'a été expliqué que le serveur était capable d'utiliser une partie de la surcharge de connexion existante pour répondre à la deuxième demande, ce qui la rendait un peu moins chère. Avec Keep-Alive désactivé, la deuxième demande n'a pas eu une telle diminution mesurable.


Cependant, toute cette discussion est un trou de lapin très profond. Je ne suis pas un expert des serveurs. Je n'ai pas à l'être. Je peux seulement expliquer que j'ai réellement vu (et créé des tests) autour de ce sujet précis... puis-je tester ce temps de chargement de fichier unique de 100k par rapport au chargement de deux moitiés de ce même fichier en parallèle, et le deuxième test sera-t-il mesurable montant plus rapidement. Comme je l'ai dit, j'ai vu, quelque part entre 15 et 25 % plus rapide avec le test fragmenté en parallèle. Comment il a fait cela, et a réussi à dépasser d'une manière ou d'une autre le terrible effet "OMG HTTP RESPONSE OVERHEAD EST TERRIBLE" et à bénéficier toujours de deux chargements parallèles, je suppose que je ne suis pas qualifié pour le prouver scientifiquement. Mais il l'a certainement fait par observation.

Christ, vous autres, tapez vite. Je finis de lire, recharge la page, et il y a comme neuf autres commentaires.

J'ai besoin d'aide. J'ai essayé de déterminer exactement où dans ce fil nous sommes passés de la discussion sur _ce qui fonctionne le mieux pour un fichier HTML standard_ à la discussion sur _si les chargeurs de script sont, dans tous les cas, de l'huile de serpent_.

@getify , vous devriez certainement défendre les LABjs et répondre aux critiques spécifiques formulées par d'autres dans le fil, mais (à l'exception de @jashkenas) je pense que ceux qui critiquent les LABjs le font afin de démontrer que ce n'est pas la meilleure solution pour un passe-partout. Vous affirmez qu'il est plus facile de convertir des pages héritées en LABjs qu'en script[defer] , et c'est peut-être vrai, mais comment cela s'applique-t-il à un fichier HTML standard (qui, par définition, part de zéro) ?

Vous dites qu'il est conçu pour les personnes qui n'ont pas de processus de construction sophistiqués, mais vous semblez également préconiser la concaténation, la division en morceaux de taille égale et le chargement en parallèle. N'est-ce pas une tâche pour un script de construction ? Encore une fois, cela semble être le mauvais choix pour un passe-partout conçu pour donner à l'utilisateur des valeurs par défaut intelligentes. Si un utilisateur souhaite cette prétendue augmentation de vitesse de 20 à 30%, il peut choisir de mettre à niveau plus tard ce que propose le passe-partout, mais ce n'est pas une tâche triviale.

Cela dit, si vous voulez continuer avec le sujet général ("Script Loaders: Valuable Tool or Snake Oil?"), Je serai heureux de traîner et de faire du pop-corn.

@getify : Je peux convenir que les 2ème et 3ème connexions peuvent être ouvertes plus rapidement que la première - la première attend DNS et éventuellement le routage du tout premier paquet vers le serveur est un peu plus lent que le routage du reste le long du même chemin. Dans HTTPS, le cache de session SSL aide beaucoup les connexions ultérieures.

Cependant, je ne vois pas la pertinence de Keep-Alive dans cette situation. Les _requêtes_ suivantes sur la même connexion sont démarrées plus rapidement avec Keep-Alive, mais ces requêtes sont en série au sein de la connexion.

J'ai presque fini ici -- je viens d'atteindre mon moment "dingue comme l'enfer et je ne vais plus le supporter" en ce qui concerne les chargeurs de script.

Cela dit, je pense que ce fil, pour un festival de flammes, a en fait été assez productif. Si LABjs veut revendiquer les sites Web malchanceux et incompétents, et laisser les gens qui veulent réellement que leurs sites se chargent rapidement seuls, c'est un grand pas en avant.

mec, cool

@savetheclocktower--

Questions justes.

Je n'ai pas commencé ma participation à ce fil en plaidant fortement pour que LABjs (ou tout autre chargeur de script) soit inclus dans h5bp. Je pense que c'est utile (voir ci-dessous), mais ce n'était pas une préoccupation majeure pour moi que je perde le sommeil. De toute évidence, ce fil s'est transformé en une attaque totale contre tout ce qui est « chargement de script ». C'est, évidemment, quelque chose qui m'importe un peu plus.

Vous dites qu'il est conçu pour les personnes qui n'ont pas de processus de construction sophistiqués, mais vous semblez également préconiser la concaténation, la division en morceaux de taille égale et le chargement en parallèle. N'est-ce pas une tâche pour un script de construction ?

Je préconise d'abord de déplacer toutes vos dizaines de balises de script vers un chargeur de script parallèle comme LABjs. Cela ne prend rien de plus que la possibilité d'ajuster votre balisage. C'est une étape beaucoup plus facile/moins intimidante que de dire à un site mom&pop d'utiliser un système de build automatisé basé sur node.js, par exemple.

Et pour ceux qui PEUVENT faire des builds de leurs fichiers, je préconise que LABjs a toujours un avantage, car il peut vous aider à charger ces morceaux en parallèle. Si vous n'êtes pas du tout d'accord sur le fait que les morceaux sont utiles, vous ne verrez aucune raison d'utiliser LABjs sur defer . Mais si vous pouvez voir pourquoi le découpage _peut être_ utile, il s'ensuit qu'un chargeur de script _peut également aider_ dans ce processus.

Encore une fois, cela semble être le mauvais choix pour un passe-partout conçu pour donner à l'utilisateur des valeurs par défaut intelligentes.

La seule raison pour laquelle je pense qu'un chargeur de script (en particulier celui qui est conçu, comme LABjs, pour avoir un mappage un à un entre les balises de script et les appels script() ) a un avantage dans un passe-partout est que dans un passe-partout , vous voyez souvent une instance de quelque chose (comme une balise), et votre tendance dans la construction de votre page est de simplement copier-coller cela autant de fois que vous en avez besoin. Ainsi, si vous avez un modèle peu performant (balise de script) dans le passe-partout, les gens auront tendance à dupliquer la balise de script une douzaine de fois. Je pense qu'en moyenne, s'ils ont plutôt dupliqué l'appel $LAB.script() fois, il y a de bonnes chances que leurs performances ne soient pas aussi mauvaises qu'elles l'auraient été.

C'est la seule raison pour laquelle j'ai commencé à participer à ce fil. C'est la seule raison pour laquelle j'ai contesté le commentaire de "foi aveugle" de

Sooooooooooo ouais.


Je pense qu'il est clair que cette discussion a dépassé le stade de la question de savoir si un chargeur de script est approprié pour le projet h5bp. Mais c'est bien, car ce sujet mérite d'être exploré.


Quoi qu'il en soit, je suis très intéressé par les cas de test reproductibles aux côtés des résultats de test.

Il semble également que la spécification de @defer été écrite pour protéger certains des comportements erratiques que les navigateurs offrent avec elle. Ce comportement doit être documenté. Je peux aider à le migrer vers le MDC lorsqu'il est prêt.

Nous avons besoin d'une documentation directe sur ces comportements qui capture tous les navigateurs, les différents types de connexion et les effets de réseau. Je ne sais pas si un banc d'essai devrait utiliser cuzillion ou assetrace, mais cela peut être déterminé.

J'ai créé un ticket pour susciter un certain intérêt pour cela https://github.com/paulirish/lazyweb-requests/issues/42

Rejoignez-moi là-bas si vous êtes dans les tâches _superfun_ de recherche de performances Web et de documentation de preuves.

Considérons ce fil comme clos, messieurs.

Le chargement paresseux n'est pas le principal avantage des modules AMD, comme @jrburke l'a décrit dans ses commentaires. La principale raison pour laquelle j'ai choisi d'utiliser autant que possible les modules AMD est qu'ils améliorent la structure du code. Il garde les fichiers source petits et concis - plus faciles à développer et à maintenir - de la même manière que l'utilisation de css @import pendant le développement et l'exécution d'une génération automatisée pour combiner les feuilles de style est également recommandée pour les grands projets...

Je pense que cet article que j'ai écrit l'année dernière correspond au sujet : Le dogme de la performance - Il ne s'agit pas uniquement de performance et assurez-vous de ne pas _perdre votre temps_ "d'optimiser" quelque chose qui ne fait pas de _réelle_ différence...

Et je suis avec @SlexAxton , je veux AMD mais de simples balises de script suffisent probablement à la plupart des gens. Peut-être qu'une approche valable serait d'ajouter un nouveau paramètre pour choisir le projet AMD et exécuter l'optimiseur RequireJS au lieu des tâches _concat_ (

Considérons ce fil comme clos, messieurs.

@paulirish Et incluiez le support AMD ? Où devrions-nous en discuter?

@benatkin ouvre un nouveau ticket frère.

@paulirish OK, merci. @jrburke ,

Divertissant et informatif. Merci les gars.

Je pense que quelqu'un doit démarrer un nouveau projet de chargeur de script et l'appeler "Issue28". :)

Pour une compatibilité la plus large, des performances rapides peuvent être obtenues en mettant le script en bas, minify, gzip, mais ne différez pas. Du moins pas avant que la compatibilité des navigateurs ne soit constante pendant quelques années consécutives.

Les goulots d'étranglement peuvent provenir des publicités, trop de javascript, du HTML gonflé, trop de CSS, trop d'iframes, trop de requêtes, la latence du serveur, un javascript inefficace. Les applications qui utilisent beaucoup de bibliothèques tierces ont des problèmes causés non seulement par trop de javascript, mais plus que cela, elles ont également tendance à avoir de nombreux autres problèmes, principalement du HTML gonflé, du HTML invalide, trop de css et un javascript inefficace. Twitter me vient à l'esprit, avec deux versions de jQuery et deux gestionnaires de défilement qui provoquent un rebond de la colonne de droite.

Le kicker est que si vous savez ce que vous faites, vous pouvez éviter ces problèmes. Vous n'avez pas besoin de choses comme jQuery ou le soulignement, et vos scripts sont donc beaucoup plus petits. Vous écrivez du HTML et du CSS propres, simples et valides. Par conséquent, vos pages se chargent plus rapidement, l'application est plus flexible en termes de changement et le référencement s'améliore. Et ainsi, l'utilisation d'un chargeur de script ne fait qu'ajouter une complexité et une surcharge injustifiées.

https://github.com/BroDotJS/AssetRage

BOOM! Je ferme les clubs et je ferme les fils.

Quel fil... wow.

Imo, la discussion a commencé dans le contexte du h5bp, qui est destiné à être un point de départ pour les développeurs Web.
En tant que tel, vous pouvez affirmer que le webdev utilisant le h5bp aura en fait du HTML propre, du CSS propre, un bon .htaccess, etc. parce que le développeur Web qui choisit d'utiliser le h5bp hautes performances et par là est préoccupé par les performances, et fera attention aux éléments non-h5bp qui se trouvent sur la ou les pages.

A partir du fil, et dans ce contexte, je pense qu'il n'y a malheureusement pas assez de preuves pour tirer une conclusion définitive.
Je suis avec Paul pour lancer la recherche et documenter ce qui doit être documenté.
Comptez-moi dans Paul.

Note latérale. Je ne connais pas très bien AMD et à première vue, cela me semble intimidant, ou du moins pas quelque chose que je peux saisir très facilement. Je pense que la plupart des développeurs Web « ordinaires » seront d'accord.
Les éléments que vous voyez dans le h5bp doivent avoir une faible barrière à l'entrée, sinon ils ne seront pas utilisés et l'absorption de h5bp peut être plus lente qu'elle ne pourrait l'être sans lui.
Je doute que quelque chose comme AMD appartienne au h5bp.
Rester simple.

Et un autre commentaire....
« Mettre les scripts en bas » et « Concaténer les fichiers JS dans un seul fichier » figure en haut de la liste des meilleures pratiques Web Perf depuis de nombreuses années. Alors pourquoi plus de 90 % des sites moyens, construits par des développeurs internes et par les meilleures agences de marque, ont-ils encore plusieurs balises de script dans le HEAD ? Vraiment, pourquoi ?

Et les 9% restants ont un seul fichier JS concaténé... dans le HEAD.
Je vois rarement un site "normal" qui n'est _pas_ construit par un développeur de performances Web de premier plan avec un script en bas.

Les développeurs continuent de construire des sites comme ils l'ont été pendant des années.
Les propriétaires de sites se soucient le plus de la conception et des fonctionnalités, c'est donc à cela que les développeurs passent leur temps.

Changer une façon de travailler, un système de build, le code... ça doit être facile, très facile, sinon ça n'arrivera pas.

J'ai travaillé sur de nombreux sites où combiner le JS de HEAD en un seul fichier et le charger en bas de BODY a cassé les pages du site. Et maintenant quoi? Dans la plupart des cas, ce n'est pas simplement une heure de travail pour résoudre ce problème. Une refactorisation sérieuse doit avoir lieu... et cela n'arrive pas par manque de connaissances et, surtout, par manque de temps.

(ah d'accord, le fil est clos...)

Nous parlons d'une bibliothèque construite sur jQuery et Modernizr. Tout est dit, vraiment. Qui utilise ça ? Oh, merde, j'oublie, Twitter.com, qui utilise deux jQuerys et a aussi dans le code source, ce qui suit :

 Ligne 352, colonne 6 : balise de fin div vue, mais il y avait des éléments ouverts.
 Erreur ligne 350, colonne 6 : élément non fermé ul.
 Erreur ligne 330, colonne 6 : élément non fermé ul.

Et le problème quand on s'attend à ce que le navigateur corrige les erreurs, c'est que HTML4 n'a pas défini de mécanismes de correction d'erreurs et vous vous retrouverez donc avec un qui sait quoi qui sait où. Bien sûr, HTML5 définit la gestion des erreurs, mais ce n'est pas rétroactif - il existe encore de nombreux "anciens" navigateurs.

Et en parlant de merde, quelqu'un ici a jeté un œil aux cales jQuery ES5 ?

BTW, avez-vous quelque chose à ajouter à votre déclaration "que le webdev utilisant le h5bp aura en fait du HTML propre", aaronpeters ?

@GarrettS ok, ok, j'aurais dû écrire "va _probablement_ avoir du HTML propre"

:-D on peut toujours espérer !

Battre un cheval mort, je sais ... mais il s'avère qu'en même temps que nous avions cette discussion scintillante, la version actuelle de LABjs avait en fait un bogue qui faisait que JavaScript s'exécutait dans le mauvais ordre dans certains navigateurs : https : //github.com/getify/LABjs/issues/36

Oh l'ironie.

doit. résister. affectation. totalement. [inapproprié. image. pour. précédent. déclaration .... agggh! AGONIE!

Ma partie préférée était quand le mec qui a fait dhtmlkitchen.com (actuellement totalement foiré ) a commencé à parler d'erreurs de balisage.

Ce site a été transféré à Paulo Fragomeni. Oui je l'ai fait et fier de ce que j'ai écrit là-bas, comme ici. Va faire une capture d'écran de ton faible avatar, crétin.

... et une fois que vous avez terminé, essayez de vous sortir la tête du cul et de comprendre la différence entre mon ancien site Web personnel (qui n'est plus maintenu par moi) et celui qui est développé par une équipe et financé par une entreprise rentable de plusieurs millions de dollars (bien que Twitter puisse valoir des milliards AFAIK).

Heureux que nous gardions cette classe et _sur le sujet_, les gars.

jashkenas a obtenu les informations pertinentes dès le début de cette discussion.

Mais ensuite, il y a eu le contrecoup. Non! ça ne doit pas être ! Souders a dit de le faire ! Et il y avait le mauvais conseil d'utiliser le report, sans se soucier de l'échec quand il échoue.

Et puis, ironiquement, de nulle part, on a affirmé que les utilisateurs de h5bp feraient les choses correctement. Et c'est très ironique car ce commentaire est venu _après_ les commentaires de ses partisans qui produisent évidemment un balisage invalide et utilisent une charge de couches d'abstraction tierces (et terribles). Et après le commentaire sur l'utilisation de différer.

Et alors, qu'est-ce que tout cela a à voir avec la panne de dhtmlkitchen.com ? Rien du tout, évidemment. Ce n'était qu'un faible jab d'un forker h5bp qui ne supporte pas d'entendre les critiques.

Frères
Mec.
Frères

Ce fil est fermé. Rappelles toi? Vous n'êtes pas obligé de rentrer chez vous, mais vous ne pouvez pas flamber ici.

Hé, vous vous souvenez tous de cette fois où nous avons créé un fil conducteur épique où il y avait de multiples débats, des guerres de flammes personnelles, des gens qui se fâchaient partout, une image obscène ou deux, et un bon moment tout autour ? Je ne peux pas croire que c'était gratuit. On devrait le refaire un jour.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

tomasz1986 picture tomasz1986  ·  5Commentaires

roblarsen picture roblarsen  ·  5Commentaires

roblarsen picture roblarsen  ·  10Commentaires

coliff picture coliff  ·  14Commentaires

coliff picture coliff  ·  12Commentaires