これはルーチンのないフロントエンドブロガーです。彼はあらゆる種類のフロントエンド指向の操作に熱心です。彼は思いついたときにどこでもよく書きます。テクノロジーとフロントエンド効果に興味がある場合は、メッセージを残してください〜ブロガーそれを見た後、全員のためにピットを踏みます。
ホームページ:オリバー・インのホームページ
座右の銘:転んでも起き上がれ〜
目次
I.はじめに
最近、当社の小規模パートナーがプロジェクトでパフォーマンスに関連するいくつかの問題に遭遇したため、いくつかのフロントエンドのパフォーマンス最適化方法と、私たち自身の日々の学習メモについて話し合い、再構成した結果、この記事が完成しました~
辛抱強く読んでください、何かを得られるかもしれません〜
2. 本記事の内容の概要
この記事ではまず、日々の開発で遭遇する可能性のあるパフォーマンス最適化のポイントや方法を具体的に紹介します。難易度: 中。
3. パフォーマンスの最適化
3.1 読み込みパフォーマンスの最適化
最も一般的な読み込みパフォーマンスの最適化は、最初の画面の読み込み時間の最適化です。Vue/React プロジェクトなどの単一ページ プロジェクトの場合、初めて読み込まれるときにサイトの速度が遅くなります。フロントエンドプロジェクト全体が一度にブラウザに送信されます...
待ち時間が長すぎるとユーザーの忍耐力がなくなり、待ち時間中にサイトから直接離れる可能性があるため、多くの場合、最初の画面の最適化が特に重要になります。
ステーション B を例にとると、次の図に示すように、ステーション B のホームページを開くと、83 個のアイテムがリクエストされ、合計リソース サイズは 210 万であることがわかります。
ただし、画面がスクロールするにつれて、次のようにさらに多くのリソースが読み込まれます。
これは遅延読み込みテクノロジーです。
端的に言えば、表示されている領域の内容のみが表示され、非表示の場合は表示領域外の内容は読み込まれません。ページを読み込むと読み込まれます。少し遅くなりますし、最初は見たいコンテンツが見られないので、事前に金額を設定しました。要素がオフセット領域に到達したら、次は次のように考えます。ユーザーにはすぐに表示され、アクティブにロードされる必要があります~
実装方法は複雑ではありません 画像リソースを例にとります カスタム属性にはデフォルトで画像アドレスが配置されます 画像がオフセット領域に入った場合のみ、画像上の data-src の値が能動的に代入されますソース。
// 代码层面
<img data-src="图片地址" src="" />
また、Vue/Reactなどのシングルページアプリケーションの場合は以下のように操作できます。
<!DOCTYPE html>
<html lang="en" id="htmlRoot">
<head>
<title><%= title %></title>
<link rel="icon" href="/favicon.ico" />
</head>
<body>
<div id="app">
// lodaing动画效果
<div class="app-loading">
<div class="app-loading-wrap">
<img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo" />
<div class="app-loading-dots">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
</div>
<div class="app-loading-title"><%= title %></div>
</div>
</div>
</div>
</body>
</html>
最上位要素に読み込みアニメーション効果を追加します。リソースが読み込まれるときに、Vue/React が最上位要素のコンテンツをアクティブにカバーすることを知っておく必要があります。この機能を使用しても、読み込みアニメーションを維持できます。ユーザーはしばらくお待ちください~
3.2 ビルドの最適化
その前に、なぜ構築の最適化によってパフォーマンスが向上するのかを考えてみましょう。
リクエストを確立した後にリソースをリクエストするプロセス、つまりすべてのリソースをすばやくリクエストする方法は注目に値するプロセスであることはわかっています。それでは、すべてのリソースをすばやくリクエストするにはどうすればよいでしょうか? 実は、ポイントは2つあります。
- 1 つ目は、リソース圧縮です。リソースの量を削減すると、送信時間は自然に短縮されます。
- 2 つ目は、リソースのマージです。複数のリソースをマージします。1 つのリクエストは複数のリソースをリクエストするのと同等であり、送信時間を自然に短縮できます。
この 2 点を達成するために、webpack を例に挙げた構築の最適化です (vite などの新しい構築ツールがますます普及してきていますが、依然として webpack の大量使用が主流です...)。
3.2.1 JavaScriptの圧縮
Webpack には、圧縮効果を実現できる大まかにいくつかの構成があります。
(追記: 圧縮に terser-webpack-plugin を使用する場合、このプラグインは圧縮速度を向上させるためにデフォルトでマルチスレッド圧縮を実行します)
3.2.2 CSS 圧縮
ここで注意すべき点は、CSS を HTML に直接埋め込むために style-loader を使用しないでください。別の CSS ファイルにする必要があります。これは非常に重要です。理由も非常に単純です。CSS リソースは並行して読み込むことができないため、レンダリングのパフォーマンスが低下します。
min-css-extract-pluginこのプラグインは CSS コードを抽出して分離します。設定後は、大まかに次のようになります。
const CSSMinimizerPlugin = require("css-minminzer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports={
// 其他配置
optimization:{
minimize:true,
minimizer:[new CSSMinimizerPlugin()]
},
plugins:[new MiniCssExtractPlugin()]
}
3.3 レンダリングの最適化
最初の 2 つの最適化の主な部分は、http リクエスト部分にあります。この部分は、リソース リクエストの到着後にブラウザーのレンダリング プロセスで DOM にレンダリングするプロセスです。このプロセスには、大まかに次のような具体的な詳細があります。
このような一般的なプロセスを通じて、インターフェイスのレンダリングは実際には非常に面倒であることがわかりました。これらのレンダリングされた DOM ノードは移動しないのが最善ですが、実際には移動することは不可能です。ユーザーの日常業務は、単に操作することだけではないでしょうか。インターフェイス、対話が開始されると、DOM ノードは当然さまざまな変更を受けます。
3.3.1 逆流を減らす
インターフェイスの変更については、再描画 とリフローの2 つのカテゴリに分けることができます。この 2 つの点については友人もよく知っているはずだと思うので、これ以上は紹介しません。再描画と比較して、リフローの影響はより大きくなります。ページ上の多くのノードの幾何学的プロパティのため、ページ全体で上記のプロセスを再度実行する必要があり、パフォーマンスへの影響が想像できます。
したがって、この部分の最適化の目的は実際には 1 つだけです。再描画により、より多くのパフォーマンスが消費され、リフロー操作が最小限に抑えられます。大まかに言うと、次の属性の変更がリフローに影響します。
- 幅、高さ、パディング、マージン、左、右などの幾何学的プロパティの変更。
- DOM ノードの追加、変更、削除など、DOM ツリーの変更。
- offsetTop、scrollTop などの特定の属性値を取得します。
3.3.2 レイアウト数を減らす
なお、以下のような書き込みは禁止させていただきます。
const dom = document.querySelector(".dom");
dom.style.width="100px";
dom.style.height="100px";
dom.style.border="1px solid #000000";
この書き方では、DOM の幾何学的プロパティが 3 回変更されるため、インターフェースが 3 回再レイアウトされることになります。この種のことはお勧めできません。合理的な方法は、DOM にクラスを追加することです。
const dom = document.querySelector(".dom");
dom.classList.add('new-style');
.new-style{
width:100px;
height:100px;
border:1px solid #000000
}
この方法でクラスを追加すると、 再レイアウトは 1 回だけ行われます。
3.3.3 手ぶれ補正とスロットリング
そして、いくつかのイベントでは、
このようなイベントは、シェイク対策とスロットリングを行う必要があります。これらのイベントが頻繁にトリガーされると、必然的にページが震えたりフリーズしたりすることになります。本質的には、イベントのトリガーを減らすことではなく、実行数を減らすことです。コールバック関数によってトリガーされます。使用シナリオも少し異なります。
- スロットリング: スロットリングの意味は、一定の間隔で機能を実行することです。たとえば、キーボードが 1 秒以内に 10 回押された場合、スロットルによってリクエストを 1 秒あたり 1 リクエストのみに制限し、リクエストの頻度を大幅に減らすことができます。
- アンチシェイク: アンチシェイクの意味は、短期間の高頻度トリガーが最終的に 1 つに結合されることです。リクエストに進み、1 秒以内に新しいテキスト入力があると、リクエストをクリアします。イベントが発生し、トリガーされなくなりました。
インターネット上には手ぶれ補正やスロットルのコードがたくさんあります。lodash も既製でパッケージ化されているので、紹介しません~
3.4 キャッシュパフォーマンスの最適化
1 つ目は、繰り返しのリクエストに対処することです。繰り返しのリクエストはネットワーク帯域幅を消費し、ユーザー エクスペリエンスに影響を与えるため、取得したリソースを再利用する必要があります。
3.4.1 ブラウザのキャッシュ
ブラウザのキャッシュは、必須キャッシュとネゴシエーション キャッシュに分けられます。
- 必須のキャッシュ: リクエスト時にキャッシュ フィールドを確認し、有効期限が切れていない場合はブラウザのローカル キャッシュからリソースを直接返します。
- ネゴシエーション キャッシュ: ブラウザがローカル キャッシュを使用する前に、サーバーにリクエストを送信して、ローカル キャッシュの有効期限が切れているかどうかを確認します。
通常、キャッシュを優先するためにこのプロセスを使用します。
V. まとめ
この記事では、パフォーマンス最適化のさまざまなポイントを詳しく紹介します。
- 読み込みの最適化の目的は、http リクエストと遅延読み込みテクノロジを削減することで、最初の画面の読み込み時間を短縮することです。
- 構築の最適化の目的は、リソースの量と量を削減し、webpack などの主流の構築ツールを合理的に使用してリソースをマージおよび圧縮することです。
- キャッシュの最適化の目的は、リクエストの繰り返しを避けることですが、メリットとデメリットがあるため、キャッシュ戦略を慎重に検討する必要があります。
- レンダリングの最適化。その目的は、再描画とリフローの削減、合理的なコード、リソースのタイムリーなリリースなど、高パフォーマンスの操作を削減することです。