Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Mozilla, Cloudflare, Facebook et d'autres proposent BinaryAST
Pour des temps de chargement JavaScript plus rapides

Le , par Stéphane le calme

149PARTAGES

12  0 
Les performances des applications sur la plateforme Web sont de plus en plus gênées par le temps de démarrage (chargement). De grandes quantités de code JavaScript sont nécessaires pour créer des expériences Web enrichies auxquelles nous nous sommes habitués.

Octet par octet, JavaScript reste la ressource la plus chère que nous envoyions aux téléphones mobiles, car il peut retarder considérablement l’interactivité.

Selon Cloudfare, si nous examinons la taille totale de JavaScript demandée sur les appareils mobiles par HTTPArchive, nous constatons qu'une page moyenne charge 350 Ko de JavaScript, alors que 10% des pages dépassent le seuil de 1 Mo. La montée d'applications plus complexes peut pousser ces chiffres encore plus haut.

Bien que la mise en cache aide, les sites Web populaires publient régulièrement un nouveau code, ce qui rend les temps de démarrage à froid (premier chargement) particulièrement importants. Tandis que les navigateurs séparent les caches de différents domaines afin de prévenir les fuites entre sites, l'importance des démarrages à froid augmente, même pour les sous-ressources populaires servies à partir de CDN, car elles ne peuvent plus être partagées en toute sécurité.


Une brève enquête de juillet 2017 sur la taille de la charge utile JS non compressée pour certaines applications Web populaires sur les ordinateurs de bureau et mobiles

Habituellement, lorsque l’on parle de la performance de démarrage à froid, le facteur principal considéré est une vitesse de téléchargement brute. Cependant, sur les pages interactives modernes, l'un des autres contributeurs importants aux démarrages à froid est le temps d'analyse JavaScript. Cela peut paraître surprenant au début, mais cela a du sens - avant de commencer à exécuter le code, le moteur doit d’abord analyser le code JavaScript récupéré, s’assurer qu’il ne contient aucune erreur de syntaxe, puis le compiler dans le bytecode initial. À mesure que les réseaux deviennent plus rapides, l'analyse et la compilation de JavaScript pourraient devenir le facteur dominant.

La capacité du périphérique (performances de la CPU ou de la mémoire) est le facteur le plus important dans la variation des temps d'analyse JavaScript et, conséquemment, du temps nécessaire au démarrage de l'application. Un fichier JavaScript de 1 Mo nécessite un temps de l'ordre de 100 ms pour une analyse sur un ordinateur de bureau moderne ou un appareil mobile haut de gamme, mais peut prendre plus d'une seconde sur un téléphone moyen (Moto G4 par exemple).


Alors que les moteurs améliorent continuellement les performances d'analyse brute, qui ont été doublé l’année dernière avec V8, ainsi que le déplacement de tâches plus importantes du thread principal, les analyseurs syntaxiques doivent encore effectuer beaucoup de travail potentiellement inutile qui consomme de la mémoire, de la batterie et peut retarder le traitement des ressources utiles.

Goulots d'étranglement d'analyse repérés par le groupe de travail

Information non disponible en cas de besoin

Un problème fondamental qui ralentit l'analyse syntaxique est que les informations nécessaires pour prendre des décisions lors de l'analyse syntaxique ne sont souvent pas encore disponibles au point du flux d'entrée auquel elles sont nécessaires. Cela se produit lorsque l’analyseur a besoin d’informations provenant de code qu’il n’a pas encore analysé (hoisting de variable par exemple) ou de code qu’il ne souhaite pas analyser (comme les fonctions internes).

Un exemple concret est le problème de la représentation efficace des liaisons. Afin de prendre des décisions sur la manière de représenter ou d'allouer une variable, l'analyseur doit savoir si la variable est fermée, il devient donc nécessaire d'analyser les fonctions imbriquées. La spécification indique uniquement où une déclaration telle que var x doit être accessible, et non comment l'allouer - les informations nécessaires à la décision d'allocation ne sont pas codées là où la variable est déclarée, ni à l'endroit où elle doit être allouée.

Dans l'exemple suivant, à cause du hoisting de variable, use_x se ferme sur x, qui n'a pas été déclaré dans f au moment de l'analyse syntaxique de la fonction interne. Un moteur ne peut pas émettre des accès optimisés à x dans use_x jusqu'à ce que l'intégralité de f soit analysée.

Code JavaScript : Sélectionner tout
1
2
3
4
5
6
7
8
var x; 
function f() { 
  function use_x() { 
    use(x); // Closes over hoisted var x. 
  } 
  
  var x; 
}

Dans l'exemple suivant, l'interface d'un moteur souhaite savoir comment allouer efficacement de l'espace aux déclarations var au fur et à mesure de leur analyse. Ce n'est pas possible sans analyser le reste de la fonction.

Code JavaScript : Sélectionner tout
1
2
3
4
5
6
function g() { 
  var x; // Not closed over, should go on function frame. 
  var y; // Closed over, should go on activation object. 
  
  return (function() { use(y); }); 
}

Dans l'exemple suivant, la présence de eval au bas de la fonction est inconnue au moment où le moteur doit décider si l'accès à var x peut être effectué de manière dynamique.

Code JavaScript : Sélectionner tout
1
2
3
4
5
6
7
function h(input) { 
  var x; 
  
  (function() { 
    eval(input); 
  })(); 
}

Sémantique précoce des erreurs

La sémantique précoce des erreurs de JavaScript nécessite l’analyse complète de tous les fichiers. Les moteurs utilisent le lazy parsing (également appelée pré-analyse) qui évite de créer un AST complet en ignorant la génération de code initiale des fonctions internes jusqu'au moment de la première invocation. C'est en moyenne 50% plus rapide, et l'effort d'analyse est toujours proportionnel à la taille du fichier. Toutefois, il y a un revers à la médaille : si une fonction interne dont la génération de code a été ignorée est appelée lors du démarrage de l'application, le moteur doit alors analyser à nouveau la totalité de la fonction.

Considérez ce qui suit. Actuellement, étant donné que innerWithSyntaxError a une erreur précoce, outer doit également renvoyer l'erreur précoce.

Code JavaScript : Sélectionner tout
1
2
3
4
5
function outer() { 
  function innerWithSyntaxError() { 
    var; 
  } 
}

Le changement de comportement proposé est analogue au wrapping du corps de fonction avec eval, comme indiqué ci-dessous.

Code JavaScript : Sélectionner tout
1
2
3
4
5
function outer() { 
  function innerWithSyntaxError() { 
    eval("var"); 
  } 
}

La proposition "BinaryAST"

C'est ici qu'intervient BinaryAST. BinaryAST est un nouveau format over-the-wire pour JavaScript proposé et développé activement par Mozilla, qui vise à accélérer l'analyse tout en préservant la sémantique du code JavaScript d'origine. Pour ce faire, il utilise une représentation binaire efficace pour le code et les structures de données, ainsi que le stockage et la fourniture d'informations supplémentaires pour guider l'analyseur à l'avance.

Le nom vient du fait que le format stocke la source JavaScript au format AST encodé dans un fichier binaire.

Le groupe de travail propose à ECMAScript un codage binaire basé sur une représentation efficace par arborescence de syntaxe abstraite de la syntaxe JavaScript. Il s'agit d'un nouveau codage alternatif de la syntaxe de surface, avec un mappage bidirectionnel assez proche de la représentation textuelle.

N'oubliez pas que cette proposition en est à ses débuts et que les tests de performance et les démonstrations actuels ne sont pas représentatifs du résultat final (qui est susceptible de s’améliorer dans le temps).

Voici une vidéo qui vous donnera une idée de l'amélioration vue par un utilisateur de Firefox sur mobile (dans ce cas, affichant le temps de démarrage complet de la page):


« S'assurer que les applications Web démarrent rapidement est l'un des aspects les plus importants, mais aussi l'un des plus difficiles du développement Web. Nous savons que BinaryAST peut réduire radicalement le temps de démarrage, mais nous devons collecter des données réelles pour démontrer leur impact. Les travaux de Cloudflare sur l'activation de l'utilisation de BinaryAST avec Cloudflare Workers constituent une étape importante dans la collecte de ces données à grande échelle », a déclaré Till Schneidereit, Senior Engineering Manager, Developer Technologies chez Mozilla.

Sources : vue d'ensemble de la proposition Binary AST, Cloudfare, ingénieur Google, Mozilla (hoisting)

Et vous ?

Que pensez-vous de cette proposition ?
En temps que développeur web, comment optimisez-vous votre code JavaScript ?

Voir aussi :

jQuery 3.4.0 est disponible, la bibliothèque JavaScript est-elle toujours aussi utile et incontournable comme à ses débuts ?
WebStorm 2019.1 disponible : tour d'horizon des nouveautés de l'EDI de JetBrains pour les développeurs JavaScript
La Linux Foundation annonce OpenJS Foundation, issue de la fusion des fondations Node.js et JS, pour soutenir la croissance de JavaScript
CSS s'enrichit du support des fonctions trigonométriques jusqu'ici accessibles via JavaScript après l'approbation du World Wide Web Consortium

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de danielhagnoul
Rédacteur https://www.developpez.com
Le 18/05/2019 à 11:19


https://github.com/tc39/proposal-binary-ast : changement du comportement de la Function.prototype.toString

Function.prototype.toString () Cette méthode retournerait quelque chose comme "[sourceless code]".

Quel impact sur le fonctionnement normal de cette fonction qui est utilisée partout de la même manière depuis les débuts de JS ?

****

Impact non négligeable, car son usage impliquera une modification des serveurs et des navigateurs :

1  0 
Avatar de freddostar31
Candidat au Club https://www.developpez.com
Le 18/05/2019 à 17:28
Citation Envoyé par Sodium Voir le message
Si seulement JavaScript était suffisamment fonctionnel pour ne pas nécessiter 3mo de librairies tierces pour être utilisables...
Depuis es6, quand tu maîtrises ton code et ton architecture, pas besoin de 3mo de librairies ... c'est terminé le temps du jquery et compagnie ...
1  0 
Avatar de Mrsky
Membre éprouvé https://www.developpez.com
Le 19/05/2019 à 1:53
Citation Envoyé par Sodium Voir le message
Si seulement JavaScript était suffisamment fonctionnel pour ne pas nécessiter 3mo de librairies tierces pour être utilisables...
Peut être pas 3mo, mais c'est clair que le nombre de dépendances d'un projet javascript est hallucinant. ES6 ou pas d'ailleurs, quand tu fais import 'xxx' si xxx dépend de 3 sous modules c'est transparent pour le programmeur (et c'est pour ça que tout le monde s'en fout) mais pas pour ton exécutable final.
0  0 
Avatar de oduhart
Futur Membre du Club https://www.developpez.com
Le 19/05/2019 à 8:37
quelle est la différence avec WASM (web assembly ) ? ca y ressemble fort, non ?
0  0 
Avatar de Watilin
Expert éminent https://www.developpez.com
Le 19/05/2019 à 13:29
Si on arrêtait d’essayer de réinventer l’analyseur HTML, ça serait un bon départ. Aujourd’hui, les devs et les chefs de projet pensent qu’un navigateur, ce n’est pas suffisant pour faire fonctionner le Web, et qu’il faut rajouter des tartines de JS. C’est peut-être globalement accepté désormais que jQuery n’est plus indispensable, mais l’illusion de besoin s’est juste déplacée vers les frameworks « tout-en-un » comme Angular, React, etc.
Je ne sais pas à quel moment on a oublié le principe de l’amélioration progressive.
1  1 
Avatar de Sodium
Membre extrêmement actif https://www.developpez.com
Le 19/05/2019 à 13:49
Si tu veux faire une application ultra-réactive, peu gourmande niveau serveur et facilement adaptable sur mobile (je parle d'adaptation en appli native, pas de responsive design), il n'y a pas vraiment de solution à part faire du 100% front.
0  0 
Avatar de Sodium
Membre extrêmement actif https://www.developpez.com
Le 18/05/2019 à 12:17
Si seulement JavaScript était suffisamment fonctionnel pour ne pas nécessiter 3mo de librairies tierces pour être utilisables...
2  3 
Avatar de Sodium
Membre extrêmement actif https://www.developpez.com
Le 18/05/2019 à 18:51
Je ne te parle pas de jQuery mais de tout le reste qui est pratiquement devenu standard pour corriger les faiblesses du langage (rxjs par exemple) dans les applications modernes, et l'évocation d'es6 n'est pas pertinente puisque le code final sera presque systématiquement retraduit en ES5 avec un outil comme babel.
0  1