ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript におけるパフォーマンスの最適化について詳しく説明します。
ここで、JavaScript ベースのパフォーマンス最適化テクニックに関する記事を共有します。これは非常に参考になるので、皆さんのお役に立てれば幸いです。エディターをフォローして見てみましょう
JavaScript は、現在最も一般的なリテラル スクリプト言語として、Web アプリケーション開発で広く使用されています。 Web アプリケーションのパフォーマンスを向上させるには、JavaScript のパフォーマンスの最適化から始めることをお勧めします。
この記事では、より多くのフロントエンド開発者がこの知識を習得できるように、ロード、コンテキスト、解析、コンパイル、実行、バンドルなどの複数の側面から JavaScript のパフォーマンス最適化テクニックを説明します。
高パフォーマンスの JavaScript コードとは何ですか?
現時点では、高パフォーマンス コードの絶対的な定義はありませんが、参照として使用できるユーザー中心のパフォーマンス モデル、つまり RAIL モデルがあります。
Response
アプリケーションがユーザーのアクションに 100 ミリ秒以内に応答できる場合、ユーザーは応答が即時であると認識します。これは、スクロールやドラッグ操作ではなく、クリック可能な要素に適用されます。
アニメーション
60Hz モニターでは、アニメーションとスクロール時に 1 秒あたり 60 フレームが必要です。この場合、各フレームは約 16 ミリ秒です。その 16 ミリ秒のうち、すべての作業を実行できるのは実際には 8 ~ 10 ミリ秒だけで、残りの時間はブラウザの内部やその他の違いによって占められます。
アイドル作業
長時間かかり、継続的に実行する必要があるタスクがある場合は、メインスレッドがユーザー入力に反応できるように、タスクを小さなチャンクに分割してください。ユーザー入力を 50 ミリ秒以上遅らせるタスクがあってはなりません。
読み込み
ページの読み込みは 1000 ミリ秒以内に完了する必要があります。モバイルでは、画面上でのレンダリングやスクロールだけではなく、ページとの対話が必要となるため、これを達成するのは困難です。
最新の読み込みベスト プラクティス (Chrome Dev Summit 2017)
53% のユーザーは、読み込みに 3 秒以上かかるとモバイル サイトを放棄します
50% のユーザーは 2 秒以内の読み込みを望んでいます時間内にページの読み込みを完了します
モバイル Web サイトの 77% は、3G ネットワークでは読み込みに 10 秒以上かかります
3G ネットワークのモバイル サイトの平均読み込み時間は 19 秒です
コードのコンテンツ
さて、最大のボトルネックは、Web サイトの読み込みにかかる時間です。具体的には、JavaScript のダウンロード、解析、コンパイル、実行時間です。ロードするJavaScriptファイルを減らすか、より柔軟にロードする以外に方法はないようです。
Web サイトを立ち上げる以外に、JavaScript コードは実際にどのように動作するのでしょうか?
コードの最適化を行う前に、現在構築しているものを検討してください。フレームワークまたは VDOM ライブラリを構築していますか?コードは 1 秒あたり数千回の操作を実行する必要がありますか?ユーザー入力やアニメーションを処理するタイムクリティカルなライブラリを作成していますか?そうでない場合は、より影響力のある分野に時間とエネルギーを振り向ける必要があります。
パフォーマンスの高いコードを書くことは、通常、全体的な計画にはほとんど影響を与えないため、それほど重要ではありません。 50k ops/s は 1k ops/s よりも優れているように思えますが、ほとんどの場合、全体の時間は変わりません。
解析、コンパイル、実行
基本的に、JavaScript のパフォーマンスの問題のほとんどは、コード自体の実行にあるのではなく、コードの実行を開始する前に実行する必要がある一連の手順にあります。
ここでは抽象化のレベルについて議論します。コンピューター上で実行されるコードのほとんどは、コンパイルされたバイナリ形式です。これは、すべてのオペレーティング システム レベルの抽象化を除き、コードは準備を必要とせずにハードウェア上でネイティブに実行できることを意味します。
JavaScript コードはプリコンパイルされていないため、ブラウザーで読み取ることができます。
JavaScript コードは最初に解析され、コンピューターのインデックスのコンパイルに使用できる構造に読み取られて変換され、次にバイトコードにコンパイルされ、最後にデバイス/ブラウザーで実行するためのマシンコードにコンパイルされます。
もう 1 つの非常に重要な側面: JavaScript はシングルスレッドであり、ブラウザのメインスレッドで実行されます。これは、一度に 1 つのプロセスのみを実行できることを意味します。 DevTools のパフォーマンス タイムラインが黄色のスパイクでいっぱいになり、CPU 使用率が 100% に達すると、フレーム落ちが発生します。これはスクロール時によくある迷惑な状況です。
この解析、コンパイル、実行の作業はすべて、JavaScript コードを実行する前に完了する必要があります。 ChromeV8 エンジンでは、解析とコンパイルが JavaScript の合計実行時間の約 50% を占めます。
したがって、この部分では、次の 2 つのことを理解する必要があります:
1. JavaScript の解析時間の長さとパケットのサイズは完全に線形ではありませんが、処理する必要がある JavaScript は少なくなります。 、より良い時間を費やします。
2. 使用するすべての JavaScript フレームワーク (React、Vue、Angular、Preact...) は、別のレベルの抽象化です (プリコンパイルされたものでない限り)。これによりバンドルのサイズが大きくなるだけでなく、ブラウザと直接通信しないためコードが遅くなります。
これを軽減するには、Service Worker を使用してバックグラウンドの別のスレッドで作業の一部を実行するか、asm.js を使用して機械語命令にコンパイルしやすいコードを作成するなどの方法があります。
私たちにできることは、JavaScript アニメーション ライブラリの使用を避けることだけです。これらのライブラリは、通常の CSS トランジションやアニメーションを使用することが完全に不可能な場合にのみ使用してください。
これらの JavaScript アニメーション ライブラリは CSS 変換、合成プロパティ、および requestAnimationFrame() を使用しますが、依然として JavaScript のメインスレッドで実行されます。基本的に、これらのライブラリはインライン スタイルを使用して 16 ミリ秒ごとに DOM にアクセスします。アニメーションの滑らかさを維持するには、すべての JavaScript が各フレームの 8 ミリ秒以内に完了するようにする必要があります。
一方、CSS アニメーションとトランジションはメインスレッドで実行され、効率的に実行できれば、再アウト/リフローを回避できます。
ほとんどのアニメーションは読み込み中またはユーザーの操作中に実行されることを考慮すると、これにより Web アプリケーションに非常に重要な調整が加えられる可能性があります。
Web アニメーション API は、高性能 JavaScript アニメーションをメインスレッドから実行できるようにする今後の機能セットです。しかし今のところ、CSS トランジションなどのテクノロジーは引き続き使用する必要があります。
バンドルのサイズは非常に重要です
36cc49f0c466276486e50c850b7e4956 終了タグの前に複数の 3f1c4e4b6b16bbbd69b2ee476dc4f83a を置く時代は終わりました。さまざまなツールキットが npm で見つかるようになり、これらを 1 MB の JavaScript ファイルとして Webpack にバンドルして、データ プランが完了したらクロールするようユーザーのブラウザに警告することができます。
これにより、JavaScript の使用量が減り、プロジェクトに Lodash ライブラリ全体が必要なくなる可能性もあります。 JavaScript ライブラリを使用する必要がある場合は、React の 1/20 のサイズしかない Preact や HyperHTML など、React 以外のものを使用することを検討してください。
Webpack 3 には、コード分割と動的インポートと呼ばれる素晴らしい機能があります。すべての JavaScript モジュールを 1 つの app.js パッケージにバンドルするのではなく、import() 構文を使用してコードを自動的に分割し、非同期で読み込みます。
これらの利点を得るためにフレームワーク、コンポーネント、クライアント側ルーティングを使用する必要はありません。メインの JavaScript ファイルに次のように記述するだけです:
if (document.querySelector('.mega-widget')) { import('./mega-widget'); }
アプリケーションがページ上でこのウィジェットを必要とする場合、必要なサポート コードが動的にロードされます。
また、Webpack が動作し、生成するすべての .js ファイルに Webpack を挿入するにはランタイムが必要です。 commonChunks プラグインを使用する場合、次のコードを使用してランタイムをチャンクに抽出できます:
new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', }),
メインの JavaScript バンドルの前に Webpack の読み込みが完了していることを確認してください。これにより、他のすべてのチャンク内のランタイムが独自のファイルに取り除かれます。この状況は runtime.js とも呼ばれます。例:
<script src="runtime.js"> <script src="main-bundle.js">
次に、コードとポリフィルのコンパイルの部分が続きます。最新の JavaScript コード (ES6 以降) を作成している場合は、Babel を使用して ES5 互換のコードに変換できます。コンパイルによりファイル サイズが増加するだけでなく、複雑さが増し、ネイティブ ES6+ コードと比較してパフォーマンスが低下することがよくあります。
これに加えて、古いブラウザで不足している機能を修正するために、babel-polyfill パッケージと whatwg-fetch を使用する可能性が高くなります。したがって、async/await を作成している場合は、ジェネレーター パッケージ regenerator-runtime を使用してコンパイルする必要もあります。
問題は、JavaScript パッケージに約 100 KB を追加することです。これはファイルが大きいだけでなく、古いブラウザをサポートできるようにするための解析と実行に大きなオーバーヘッドがかかることになります。
一种方法是创建两个独立的 bundle,并根据实际条件来加载它们。Babel 转换编译器在 babel-preset-env 的帮助下,会使同时面临新旧两种浏览器的情况更加容易处理。
一个并不规范但行之有效的方法,是将以下内容放在一个内联脚本中:
(function() { try { new Function('async () => {}')(); } 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 的传输大小。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上がJavaScript におけるパフォーマンスの最適化について詳しく説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。