基本的なウェブページパフォーマンス最適化ルールの簡単な概要

基本的なウェブページパフォーマンス最適化ルールの簡単な概要

ブラウザのウェブページを最適化するためのいくつかのルール

ページの最適化

静的リソース圧縮

ビルド ツール (webpack、gulp) を使用して、画像、スクリプト、スタイルなどの Web ページの静的リソースを適切に圧縮します。

CSS スプライト、base64 インライン画像

サイト上の小さなアイコンを 1 つの画像に結合し、CSS を使用して対応するアイコンを見つけてキャプチャし、インライン画像を適切に使用します。

スタイルは上部に配置され、スクリプトは下部に配置されます

ページは段階的に表示されます。スタイルを先頭に配置すると、ページをユーザーにすばやく表示できます。<script> タグを先頭に配置すると、ページの背後にあるリソースのダウンロードがブロックされます。

外部の CSS と JS を使用する

複数のページが共通の静的リソースを参照し、リソースを再利用することで追加の HTTP リクエストが削減されます。

空のsrcを持つ画像を避ける

不要な http リクエストを避けてください。

<!-- src が空の画像でも http リクエストが開始されます -->
<img src="" alt="画像" />

HTMLで画像の拡大縮小を避ける

大きな画像を読み込んでから縮小するのではなく、必要に応じて指定されたサイズの画像を使用するようにしてください。

<!-- 実際の画像サイズは 600x300 で、HTML では 200x100 に拡大されます -->
<img src="/static/images/a.png" width="200" height="100" alt="画像" />

プリロード

リンク タグの rel に preload 属性を設定すると、メインのレンダリング メカニズムが介入する前にブラウザーがリソースをプリロードできるようになります。このメカニズムにより、リソースをより早く取得でき、ページの初期化がブロックされません。

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
  <メタ文字セット="UTF-8">
  <title>ドキュメント</title>
  <link ref="preload" href="style.css" as="style">
  <link ref="preload" href="main.js" as="script">
  
  <link ref="スタイルシート" href="style.css">
</head>
<本文>
  
  <script src="main.js"></script>
</本文>
</html>

この例では、css ファイルと js ファイルが事前にロードされ、後続のページ レンダリングで使用されるとすぐに呼び出されます。

異なるタイプのリソースをロードするには、 as タイプを指定できます。

  1. スタイル
  2. スクリプト
  3. ビデオ
  4. オーディオ
  5. 画像
  6. フォント
  7. 書類
  8. ...

このメソッドは、crossorigin 属性を設定することで、ドメイン間でリソースをプリロードすることもできます。

<link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">

CS

セレクタ

セレクターの優先順位は最高から最低の順に次のようになります。

  1. IDセレクター
  2. クラスセレクター
  3. タグセレクター
  4. 隣接セレクター
h1 + p{ 上マージン: 15px; }

h1 要素の直後に表示される段落を選択します。h1 要素と p 要素には共通の親要素があります。

子セレクター

h1 > 強い {color:red;}

子孫セレクター

h1 em {色:赤;}

ワイルドカードセレクター

属性セレクタ

*[タイトル] {色:赤;}
img[alt] {境界線: 5px 赤一色;}

擬似クラスセレクタ

セレクターの使用経験:

  1. マルチレイヤータグセレクターを置き換えることができるクラスセレクターを優先します。
  2. ID セレクターは注意して使用してください。効率的ではありますが、ページ上で一意であるため、チームのコラボレーションやメンテナンスには役立ちません。
  3. セレクタの継承を適切に使用します。
  4. CSS 式は避けてください。

セレクターのレベルを下げる

前のセレクターの優先度に基づいて、複数レベルのセレクターのネストを避けるようにしてください。できれば 3 レベル以下にしてください。

.container .text .logo{ 色: 赤; }

/*変更*/
.container .text-logo{ 色: 赤; }

ページスタイルファイルを合理化し、未使用のスタイルを削除する

ブラウザは不要なスタイルマッチングを実行するため、レンダリング時間に影響します。また、スタイルファイルが大きすぎると、読み込み速度にも影響します。

CSS継承を使用してコード量を削減する

CSS の継承可能なプロパティを使用すると、親要素がスタイルを設定し、子要素が再度設定する必要がなくなります。

一般的な継承プロパティには、color、font-size、font-family などがあり、非継承プロパティには、position、display、float などがあります。

属性値が0の場合、単位は追加されません

CSS 属性値が 0 の場合、コード量を削減するために単位は必要ありません。

.text{ 幅: 0px; 高さ: 0px; }

/*変更*/
.text{ 幅: 0; 高さ: 0; }

JavaScript

イベント委任の使用

イベント委任を使用して、イベントを複数の類似した DOM 要素にバインドします。

<ul id="コンテナ">
  <li class="list">1</li>
  <li class="list">2</li>
  <li class="list">3</li>
</ul>
// 不合理な方法: 各要素にクリックイベントをバインドする $('#container .list').on('click', function() {
  var テキスト = $(this).text();
  console.log(テキスト);
});

// イベント委譲方法: イベントバブリングメカニズムを使用して、親要素にイベントを委譲します$('#container').on('click', '.list', function() {
  var テキスト = $(this).text();
  console.log(テキスト);    
});

注意すべき点は、イベント委譲を使用する場合、イベントをドキュメントに委譲できるが、これは無理があるということである。一つには、イベントの誤判定を起こしやすいということ、もう一つは、スコープチェーンの検索効率が低いということである。最も近い親要素をデリゲート オブジェクトとして選択する必要があります。

パフォーマンスが向上するだけでなく、イベント委任により、動的に作成された DOM 要素にイベントをバインドする必要もなくなります。

DOMコンテンツが読み込まれました

すべての画像リソースがダウンロードされるまで待つことなく、DOM 要素が読み込まれた後 (DOMContentLoaded) に DOM ツリーの処理を開始できます。

// ネイティブ JavaScript
document.addEventListener("DOMContentLoaded", 関数(イベント) {
  console.log("DOMが完全に読み込まれ解析されました");
}、 間違い);

// jQuery
$(ドキュメント).ready(関数() {
  console.log("準備完了!");
});

// $(document).ready()$(function() の簡略版 {
  console.log("準備完了!");
});

プリロードと遅延ロード

プリロード

ブラウザのアイドル時間を利用して、画像、スタイル、スクリプトなど、将来使用される可能性のあるリソースをプリロードします。

無条件プリロード

onload がトリガーされると、将来必要になるリソースをすぐに取得します。

画像リソースをプリロードします。 (画像のプリロードを実装する 3 つの方法)。

ユーザーの行動に基づいたプリロード

ユーザーの動作の可能な操作を決定し、将来必要になる可能性のあるリソースをプリロードします。

  1. ユーザーが検索入力ボックスに入力すると、検索結果ページで使用される可能性のあるリソースが事前に読み込まれます。
  2. ユーザーがタブを操作すると、デフォルトでそのうちの 1 つが表示されます。ユーザーが他のオプションをクリックすると、マウスをその上に置いたときに、将来使用されるリソースが読み込まれます。

遅延読み込み

ページの初期化に必要なコンテンツやコンポーネントを除き、画像を切り取るための JS ライブラリや、可視範囲外にある画像など、その他はすべて遅延読み込みが可能です。

画像の遅延読み込み。 (画像が可視領域内にあるかどうかを判断します。可視領域内にある場合は、画像に実際のパスを割り当てます)

グローバル検索の回避

関数内で複数回使用される非ローカル変数は、ローカル変数にする必要があります。

関数 updateUI(){
  var imgs = document.getElementsByTagName("img");
  (var i=0, len=imgs.length; i < len; i++){
    imgs[i].title = document.title + "画像" + i;
  }
  var msg = document.getElementById("msg");
  msg.innerHTML = "更新が完了しました。";
}

上記の関数、特に for ループでは、ドキュメント グローバル変数が何度も使用されます。したがって、ドキュメントのグローバル変数をローカル変数として保存して使用するのがより良い解決策です。

関数 updateUI(){
  var doc = ドキュメント;
  var imgs = doc.getElementsByTagName("img");
  (var i=0, len=imgs.length; i < len; i++){
    imgs[i].title = doc.title + " 画像 " + i;
  }
  var msg = doc.getElementById("msg");
  msg.innerHTML = "更新が完了しました。";
}

注目すべき点の 1 つは、JavaScript コードでは、var を使用して宣言されていない変数はすべてグローバル変数になり、不適切に使用するとパフォーマンスの問題が発生するということです。

不要なプロパティクエリを避ける

オブジェクトはプロトタイプ チェーンでその名前のプロパティを検索する必要があるため、変数と配列を使用する方がオブジェクトのプロパティにアクセスするよりも効率的です。

// 配列varを使用する values ​​= [5, 10];
var 合計 = 値[0] + 値[1];
アラート(合計);

// オブジェクトの使用 var values ​​= { first: 5, second: 10};
var 合計 = values.first + values.second;
アラート(合計);

上記のコードでは、オブジェクトのプロパティが計算に使用されます。 1 つまたは 2 つのプロパティ検索ではパフォーマンス上の問題は発生しませんが、ループ内などで複数の検索が必要な場合は、パフォーマンスに影響します。

次のように複数のプロパティを検索して単一の値を取得する場合:

var クエリ = window.location.href.substring(window.location.href.indexOf("?"));

window.location.href を変数としてキャッシュすることで、不要なプロパティの検索を減らす必要があります。

var url = window.location.href;
var クエリ = url.substring(url.indexOf("?"));

関数のスロットリング

検索ボックスがあると仮定し、マウスが離されるたびにリクエストが送信されるように、onkeyup イベントを検索ボックスにバインドします。スロットル機能を使用すると、ユーザー入力中に指定された時間内に連続して複数の操作が行われても、1 つのリクエストのみがトリガーされるようにすることができます。

<input type="text" id="input" value="" />
// イベントをバインド document.getElementById('input').addEventListener('keyup', function() {
  スロットル(検索);
}、 間違い);

//論理関数関数search() {
  console.log('検索...');
}

//スロットル関数 function throttle(method, context) {
  タイムアウトをクリアします(メソッドtId);
  メソッド.tId = setTimeout(関数() {
    メソッドを呼び出します(コンテキスト);
  }, 300);
}

スロットル機能の適用シナリオは検索ボックスに限定されません。たとえば、スロットル機能は、ページのスクロール、スクロール時、サイズ変更時のウィンドウの拡大などのパフォーマンスを向上させるために使用する必要があります。

文の数を最小限に抑える

ステートメントの数も操作の実行速度に影響します。

複数の変数宣言を1つにマージする

// 複数の var 宣言を使用します var count = 5;
var color = "青";
var 値 = [1,2,3];
var now = 新しい Date();

// 改善後 var count = 5,
  色 = "青"、
  値 = [1,2,3]、
  now = 新しい日付();

改善版としては、カンマで区切られた var 宣言を 1 つだけ使用する方法が考えられます。変数が多数ある場合、各 var を個別に宣言するよりも、 var 宣言を 1 つだけ使用する方がはるかに高速です。

配列とオブジェクトリテラルの使用

ステートメントごとの割り当ての代わりに、配列リテラルとオブジェクトリテラルを使用します。

var values ​​= 新しい配列();
値[0] = 123;
値[1] = 456;
値[2] = 789;

// 改善後 var values ​​= [123, 456, 789];
var person = 新しいオブジェクト();
person.name = "ジャック";
人.年齢 = 28;
person.sayName = 関数(){
  アラート(this.name);
};

// 改善された var person = {
  名前:「ジャック」
  年齢: 28歳
  sayName: 関数(){
    アラート(this.name);
  }
};

文字列の最適化

文字列の連結

初期のブラウザでは、プラス記号を使用して文字列を連結する方法が最適化されていませんでした。文字列は不変であるため、結果を格納するために中間文字列を使用する必要があり、文字列の頻繁な作成と破棄が非効率的である理由です。

var テキスト = "こんにちは";
テキスト+ = " ";
text+= "世界!";

文字列を配列に追加し、配列の join メソッドを呼び出して文字列に変換すると、加算演算子の使用を回避できます。

var arr = [],
  私 = 0;
arr[i++] = "こんにちは";
arr[i++] = " ";
arr[i++] = "世界!";
var テキスト = arr.join('');

最新のブラウザでは、加算演算子を使用して文字列の連結が最適化されているため、ほとんどの場合、依然として加算演算子が推奨される選択肢となります。

リフローと再塗装を削減

ブラウザのレンダリング プロセスには、パフォーマンスを消費するリフローと再描画が含まれます。スクリプト操作中にリフローと再描画をトリガーするアクションを減らすように注意する必要があります。

  1. リフロー: 要素の幾何学的プロパティが変更されたため、レンダリング ツリーを再構築する必要があります。ツリーの変更をレンダリングするプロセスはリフローと呼ばれます。
  2. 再描画: 要素の幾何学的サイズは変更されていませんが、要素の CSS スタイル (背景色または色) が変更されています。

リフローまたは再ペイントをトリガーするアクションは何ですか?

  1. ウィンドウのサイズを変更する
  2. フォントを変更する
  3. スタイルシートの追加または削除
  4. ユーザーが<input/>ボックスにテキストを入力したときなど、コンテンツが変化する
  5. クラス属性の操作
  6. DOM に対するスクリプト操作 (DOM 要素の追加、削除、変更)
  7. offsetWidth および offsetHeight プロパティの計算
  8. スタイル属性の値を設定する

リフローと再ペイントを減らして Web ページのパフォーマンスを向上させるにはどうすればよいでしょうか?

1. DOM要素に対するスクリプト操作

  1. DOM 要素を display:none に設定すると、設定プロセス中にリフローがトリガーされますが、自由に変更して変更後に表示されます。
  2. 要素をメモリに複製して操作し、変更後に要素を置き換えます。

2. 要素のスタイルを変更する

  1. 一つずつではなく、まとめて変更するようにしてください。
  2. 事前に id と class を設定してから、要素の className を設定します。

3. 要素にアニメーションを追加する場合は、要素の CSS スタイルを position:fixed または position:absolute に設定します。これにより、要素がドキュメント フローを離れた後に再フローすることがなくなります。

4. ウィンドウサイズの調整、入力ボックスへの入力、ページのスクロールなどを行うときは、スロットル機能(上記)を使用します。

ウェブ

ブラウザキャッシュ

ブラウザ キャッシュを適切に設定することは、Web ページを最適化するための重要な手段の 1 つです。

有効期限とキャッシュ制御

Expires は HTTP1.0 から来ており、Cache-Control は HTTP1.1 から来ています。両方が同時に設定されている場合、Cache-Control が Expires を上書きします。

  1. Expires は秒数ではなく実際の有効期限を指定します。しかし、Expires には、サーバーの時間が同期していなかったり不正確であったりするなどの問題があります。したがって、有効期限は絶対時間ではなく、残り秒数で表現する方が適切です。
  2. Cache-Control は、キャッシュの有効期限を指定するために、max-age 値を秒単位で設定できます。例: Cache-Control: max-age=3600。

ETag と Last-Modified

ETag と Last-Modified の両方がサーバーによって応答ヘッダーで返されますが、ETag は Last-Modified よりも優先度が高く、サーバーは ETag 値を優先することを意味します。

  1. ETag はドキュメントに添付される任意のラベルであり、ドキュメントのシリアル番号やバージョン番号、またはドキュメント コンテンツのチェックサムなどになります。ドキュメントが変更されると、ETag 値も変更されます。 ETag に関連するのは If-None-Match です。ブラウザがリクエストを開始すると、If-None-Match フィールドで ETag 値がサーバーに送信されます。
  2. Last-Modified は、ドキュメントがサーバー上で最後に変更された時刻です。 Last-Modified に関連するのは If-Modified-Since です。ブラウザがリクエストを開始すると、Last-Modified 値が If-Modified-Since フィールドでサーバーに送信されます。

強力なキャッシュとネゴシエートされたキャッシュ

キャッシュ タイプは、強力なキャッシュとネゴシエートされたキャッシュです。 2 つの違いは、強力なキャッシュはサーバーにリクエストを送信しないのに対し、ネゴシエートされたキャッシュはリクエストを送信することです。一致が成功した場合は 304 Not Modified が返され、一致が失敗した場合は 200 が返されます。ブラウザは最初に強力なキャッシュをチェックします。強力なキャッシュがヒットしない場合は、ネゴシエートされたキャッシュ チェックを実行します。

ブラウザキャッシュの設定方法

  1. Web サーバーから返される応答に Expires と Cache-Control を追加します。
  2. nginx または apache 構成ファイルで Expires と Cache-Control を構成します。

HTTP リクエストを減らす理由は何ですか?

複数の画像リクエストの代わりに CSS スプライトを使用する、空の src を持つ画像を避ける、インライン画像を使用する、外部にリンクされた CSS と JS を使用する、キャッシュするなど、HTTP リクエストを減らす対策は、パフォーマンスの最適化の大部分を占めます。

URL を入力してからページが読み込まれるまでのプロセスは次のとおりです。

  1. DNS解決
  2. TCP接続
  3. HTTP リクエストとレスポンス
  4. ブラウザはページをレンダリングする
  5. 接続を閉じる

完全な HTTP リクエストはこれらのプロセスを経る必要があり、時間がかかり、リソースを消費するため、リクエストの数を減らすことが必要になります。

参考文献:

高性能ウェブサイト構築 vs. 高性能ウェブサイト構築上級ガイド
JavaScript 上級プログラミング (第 3 版)
HTTP 決定版ガイド
ウェブサイトを高速化するためのベストプラクティス

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

<<:  MySql マスタースレーブレプリケーションメカニズムの包括的な分析

>>:  CSS3 を使用して入力複数選択ボックスのスタイルをカスタマイズする例

推薦する

MySQL移行計画と落とし穴の実践記録

目次背景解決策1: 古いデータをバックアップするオプション2: テーブルを分割する解決策3: tid...

Vueのdiffアルゴリズムについての簡単な説明

目次概要バーチャルドム原理実装プロセスパッチ方式sameVnode関数patchVnode関数upd...

Nginxはctxを使用してデータ共有とコンテキスト変更機能を実現します。

環境: init_worker_by_lua、set_by_lua、rewrite_by_lua、a...

mysql 8.0.19 win10 クイックインストールチュートリアル

このチュートリアルでは、参考までにMySQL 8.0.19のインストールチュートリアルを共有します。...

Vue のプラグインとコンポーネントの違いと使い方のまとめ

このチュートリアルの動作環境: Windows 7 システム、vue 2.9.6 バージョン、DEL...

Linux での Nginx 監視の問題

nginxのインストール仮想マシンがインターネットにアクセスできることを確認します。 1. ルートユ...

jQueryのチェーンプログラミングスタイルの詳細な例

チェーンプログラミングの実装原理jQuery を使用すると、開発者は常にドット構文を使用して独自のメ...

MySQLはIDに適切なデータ型を選択します

目次分散IDソリューションの概要データベース自動増分IDデータベースマルチマスターモード数値セグメン...

Vue ブラウザログアウトの実装例

目次1. beforeunload イベント2. アンロードイベント3. ソースコードプロジェクトの...

フォームから Vue ElementUI を使用してログイン効果を実装する例

目次1. ElementUIで基本的なスタイルを構築する2. [送信]ボタンをクリックして、アカウン...

Docker クロスホストネットワーク (オーバーレイ) の実装

1. Dockerのホスト間通信Docker クロスホスト ネットワーク ソリューションには以下が含...

ローカルストレージにブール型の値を保存する際の落とし穴を解決する

LocalStorageはブール値を保存します今日、ブール値データを保存するために localsto...

MySQL の自己結合重複排除に関する注意事項

機能シナリオを簡単に説明しましょう。データ行フィールドは次のとおりです。名前開始日時タイプこの表では...

Linux におけるシステム入出力管理の詳細な説明

システムの入力と出力の管理1. システムの入力と出力を理解するLinuxシステムでは、1は正しい出力...

Centos7.5 は mysql5.7.24 バイナリ パッケージの展開をインストールします

1. 環境整備:オペレーティング システム: CentOS Linux リリース 7.5.1804 ...