Maison  >  Article  >  interface Web  >  Une explication détaillée de l'optimisation des performances en JavaScript

Une explication détaillée de l'optimisation des performances en JavaScript

亚连
亚连original
2018-06-21 16:10:081256parcourir

Je vais maintenant partager avec vous un article sur les techniques d'optimisation des performances basées sur JavaScript. Il a une bonne valeur de référence et j'espère qu'il sera utile à tout le monde. Suivons l'éditeur et jetons un coup d'œil.

En tant que langage de script littéral le plus courant actuellement, JavaScript a été largement utilisé dans le développement d'applications Web. Afin d'améliorer les performances des applications Web, ce serait un bon choix de commencer par l'optimisation des performances JavaScript.

Cet article explique les techniques d'optimisation des performances JavaScript sous plusieurs aspects tels que le chargement, le contexte, l'analyse, la compilation, l'exécution et le regroupement, afin qu'un plus grand nombre de développeurs front-end puissent maîtriser ces connaissances.

Qu'est-ce que le code JavaScript haute performance ?

Bien qu'il n'existe actuellement pas de définition absolue du code haute performance, il existe un modèle de performance centré sur l'utilisateur qui peut servir de référence : le modèle RAIL.

Réponse

Si votre application peut répondre à l'opération de l'utilisateur dans les 100 millisecondes, l'utilisateur considérera la réponse comme réelle temps. Cela s'applique aux éléments cliquables, et non aux opérations de défilement ou de glissement.

Animation

Sur un moniteur 60Hz on aimerait avoir 60 images par seconde pour l'animation et le défilement, dans ce cas chaque image ferait environ 16ms. Sur ces 16 ms, il n'y a en réalité que 8 à 10 ms pour faire tout le travail, le reste du temps est occupé par les composants internes du navigateur et d'autres différences.

Travail inactif

Si vous avez une tâche qui prend beaucoup de temps et doit s'exécuter en continu, assurez-vous de la diviser en petits morceaux pour permettre au thread principal de Réagissez aux opérations de saisie de l’utilisateur. Aucune tâche ne devrait retarder la saisie de l'utilisateur de plus de 50 ms.

Chargement

Le chargement de la page devrait être terminé dans un délai de 1 000 ms. Sur mobile, c'est un objectif difficile à atteindre car il implique une interaction avec la page plutôt que simplement un rendu et un défilement sur l'écran.

Meilleures pratiques de chargement modernes (Chrome Dev Summit 2017)

53 % des utilisateurs abandonnent un site mobile si le chargement prend plus de trois secondes. Visite

50 % des utilisateurs s'attendent à ce que les pages se chargent en moins de 2 secondes

77 % des sites mobiles mettent plus de 10 secondes à se charger sur les réseaux 3G

19 secondes est la moyenne temps de chargement des sites mobiles sur les réseaux 3G

Contenu du code

Vous avez peut-être remarqué que le plus gros goulot d'étranglement est le temps de chargement du site Web requis. Plus précisément, il s'agit du temps de téléchargement, d'analyse, de compilation et d'exécution de JavaScript. Il ne semble y avoir d'autre moyen que de charger moins de fichiers JavaScript ou de les charger de manière plus flexible.

En plus du lancement du site Web, comment fonctionne réellement le code JavaScript ?

Avant d'optimiser votre code, réfléchissez à ce que vous construisez actuellement. Construisez-vous un framework ou une bibliothèque VDOM ? Votre code doit-il effectuer des milliers d’opérations par seconde ? Créez-vous une bibliothèque urgente qui gère les entrées et/ou les animations des utilisateurs ? Sinon, vous devez rediriger votre temps et votre énergie vers des domaines ayant plus d’impact.

Écrire du code performant n'est pas si important car cela a généralement peu d'impact sur le grand schéma des choses. 50 000 opérations/s semblent mieux que 1 000 opérations/s, mais dans la plupart des cas, le temps global ne changera pas.

Analyser, compiler et exécuter

Fondamentalement parlant, la plupart des problèmes de performances JavaScript ne résident pas dans l'exécution du code lui-même, mais dans une série de étapes à suivre avant que le code puisse commencer à s'exécuter.

Nous discutons ici du niveau d’abstraction. La plupart du code exécuté sur un ordinateur est au format binaire compilé. Cela signifie que, à l'exception de toutes les abstractions au niveau du système d'exploitation, le code peut s'exécuter de manière native sur le matériel sans aucune préparation requise.

Le code JavaScript n'est pas précompilé, il est lisible sur le navigateur.

Le code JavaScript est d'abord analysé, c'est-à-dire lu et converti en une structure qui peut être utilisée pour la compilation d'index informatiques, puis compilé en bytecode et enfin compilé en code machine pour l'exécution du périphérique/processeur de navigation.

Autre aspect très important : JavaScript est monothread et s'exécute sur le thread principal du navigateur. Cela signifie qu'un seul processus peut être exécuté à la fois. Si la chronologie des performances de DevTools est remplie de pics jaunes et que l'utilisation du processeur atteint 100 %, vous rencontrerez des pertes d'images. Il s'agit d'une situation courante et ennuyeuse lors du défilement.

Toutes ces analyses, compilations et exécutions doivent être effectuées avant que le code JavaScript puisse s'exécuter. Dans le moteur ChromeV8, l'analyse et la compilation représentent environ 50 % du temps d'exécution total de JavaScript.

Donc, dans cette partie, vous devez savoir deux choses :

1 Bien que JavaScript analyse Le. la durée n'est pas complètement linéaire avec la taille du bundle, mais moins il y a de JavaScript à traiter, moins cela prend de temps.

2. Chaque framework JavaScript que vous utilisez (React, Vue, Angular, Preact...) est un autre niveau d'abstraction (sauf s'il est précompilé). Non seulement cela augmentera la taille de votre bundle, mais cela ralentira également votre code puisque vous ne parlez pas directement au navigateur.

Il existe des moyens d'atténuer ce problème, par exemple en utilisant des service Workers pour effectuer une partie du travail dans un autre thread en arrière-plan, ou en utilisant asm.js pour écrire du code qui se compile plus facilement en instructions machine.

Tout ce que nous pouvons faire est d'éviter d'utiliser les bibliothèques d'animation JavaScript. N'utilisez ces bibliothèques que lorsque l'utilisation de transitions et d'animations CSS régulières est totalement impossible.

Même si ces bibliothèques d'animation JavaScript utilisent des transformations CSS, des propriétés de composition et requestAnimationFrame( ), elles s'exécutent toujours sur le thread principal de JavaScript. Fondamentalement, ces bibliothèques accèdent au DOM toutes les 16 ms en utilisant des styles en ligne. Vous devez vous assurer que tout le JavaScript est terminé dans les 8 ms suivant chaque image pour maintenir la fluidité de l'animation.

D'un autre côté, les animations et transitions CSS s'exécuteront dans le thread principal, et si elles peuvent être exécutées efficacement, elles peuvent éviter les situations de relayage/redistribution.

Étant donné que la plupart des animations s'exécutent pendant le chargement ou l'interaction de l'utilisateur, cela peut apporter à votre application Web des ajustements très importants.

L'API Web Animations est un ensemble de fonctionnalités à venir qui permet d'exécuter des animations JavaScript hautes performances à partir du thread principal. Mais pour l’instant, les technologies telles que les transitions CSS devront continuer à être utilisées.

La taille du bundle est très importante

Il n'est plus nécessaire d'inclure plusieurs balises 3f1c4e4b6b16bbbd69b2ee476dc4f83a .ère. Une grande variété de boîtes à outils peuvent désormais être trouvées sur npm, et celles-ci peuvent être regroupées avec Webpack dans un seul fichier JavaScript de 1 Mo, alertant le navigateur de l'utilisateur de l'explorer lorsque le plan de données est terminé.

Cela utilise moins de JavaScript, ce qui signifie également que votre projet n'aura peut-être plus besoin de l'intégralité de la bibliothèque Lodash. Si vous devez utiliser une bibliothèque JavaScript, envisagez d'utiliser autre chose que React, comme Preact ou HyperHTML, qui ne font que 1/20 de la taille de React.

Webpack 3 possède des fonctionnalités étonnantes appelées fractionnement de code et importations dynamiques. Il ne regroupe pas tous les modules JavaScript dans un seul package app.js, mais utilise la syntaxe import() pour diviser automatiquement le code et le charger de manière asynchrone.

Vous n'avez pas besoin d'utiliser des frameworks, des composants et un routage côté client pour bénéficier de ces avantages. Il vous suffit d'écrire ce qui suit dans le fichier JavaScript principal :

if (document.querySelector('.mega-widget')) {
 import('./mega-widget');
}

Si votre application nécessite ce widget sur la page, elle chargera dynamiquement le code de support requis.

De plus, Webpack a besoin d'un runtime pour fonctionner et l'injecter dans tous les fichiers .js qu'il génère. Si vous utilisez le plugin commonChunks, vous pouvez utiliser ce qui suit pour extraire le runtime en morceaux :

new webpack.optimize.CommonsChunkPlugin({
 name: 'runtime',
}),

Assurez-vous que Webpack a fini de se charger avant le bundle JavaScript principal, le runtime dans tous les autres morceaux sera alors dépouillé dans son propre fichier, ce cas est également appelé runtime.js. Par exemple :

<script src="runtime.js">
<script src="main-bundle.js">

Vient ensuite la partie compilation du code et des polyfills. Si vous écrivez du code JavaScript moderne (ES6+), vous pouvez utiliser Babel pour le convertir en code compatible ES5. La compilation augmente non seulement la taille du fichier, mais ajoute également de la complexité et souffre souvent d'une dégradation des performances par rapport au code ES6+ natif.

De plus, vous utiliserez très probablement le package babel-polyfill et whatwg-fetch pour corriger les fonctionnalités manquantes dans les anciens navigateurs. Donc, si vous écrivez async/await, vous devez également utiliser le package générateur régénérateur-runtime pour le compiler.

Le problème est que vous ajoutez près de 100 Ko à votre package JavaScript, ce qui est non seulement un fichier volumineux, mais représente également une énorme surcharge d'analyse et d'exécution pour pouvoir prendre en charge les anciens navigateurs.

一种方法是创建两个独立的 bundle,并根据实际条件来加载它们。Babel 转换编译器在 babel-preset-env 的帮助下,会使同时面临新旧两种浏览器的情况更加容易处理。

一个并不规范但行之有效的方法,是将以下内容放在一个内联脚本中:

(function() {
 try {
 new Function(&#39;async () => {}&#39;)();
 } catch (error) {
 // create script tag pointing to legacy-bundle.js;
 return;
 }
 // create script tag pointing to modern-bundle.js;;
})();

如果浏览器无法识别 async 函数,则会被认为是旧版本的浏览器,此时就会用到 polyfill 包。如果能识别,用户则将得到现代浏览器的处理。

结论

想要提高网站的运行速度,就需要确保网站能快速的加载 JavaScript 文件,以实现快速的互动。你的 JavaScript 代码应该被分成更小的、可管理的 bundle,同时尽可能地进行异步加载。在服务器端,请确保启用了 HTTP 2.0,以便实现更快的并行传输和 gzip/Brotli 压缩,从而大大减少了 JavaScript 的传输大小。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用JQUERY如何实现多个AJAX请求

使用js如何实现焦点图效果

在微信小程序中如何实现图片懒加载

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn