高速化への挑戦: フロントエンドエンジニアのパフォーマンス最適化テクニック

# この記事について
こんにちは、秋本です。
主にフロントをやっているエンジニアです。

今回は巷で話題（もはや社会現象？）のChat-GPT（GPT-4）を使ってフロントエンドのパフォーマンス最適化テクについて語ってもらおうという内容です。

下記記事は9割GPTくんに書かせたものになります。
フロントの勉強がてらへ〜こんなことできるんだ〜ぐらいの感じで見てもらえると幸いです。

:::note warn
Chat-GPTはまだ生まれたばかりです。
一部間違いをさも正解のように語っていますので注意してください。
また、説明口調なのもご了承いただきたいです（自分の設定したプロンプトがイケてなかったです🙏）
:::

# はじめに
ウェブサイトやウェブアプリケーションのパフォーマンスは、ユーザーエクスペリエンスに大きな影響を与えます。パフォーマンスが遅いと、ユーザーはストレスを感じ、サイトの利用を中断する可能性が高くなります。さらに、パフォーマンスの悪さはSEOにも影響を与え、検索エンジンのランキングに悪影響を与えることがあります。

## 記事の目的とパフォーマンス最適化の重要性
フロントエンドエンジニアは、パフォーマンスの最適化に重点を置くことが重要です。パフォーマンスの最適化には、レンダリング、ネットワーク、コードの最適化、パフォーマンス監視と測定、ウェブアクセシビリティといった多くの側面があります。これらの側面に焦点を合わせ、パフォーマンスを最大化するためのテクニックやベストプラクティスについて探求しましょう。

この記事では、フロントエンドエンジニアがウェブサイトやウェブアプリケーションのパフォーマンスを最適化するための方法を紹介します。パフォーマンスの最適化には多くの側面がありますが、本記事では主に以下の点にフォーカスします。

- レンダリングパフォーマンスの最適化
- ネットワークパフォーマンスの最適化
- コード最適化とバンドルサイズの削減
- パフォーマンス監視と測定
- ウェブアクセシビリティとパフォーマンスの関連性

この記事を通じて、フロントエンドエンジニアがパフォーマンス最適化に注力し、ユーザーエクスペリエンスを向上させ、SEOにもプラスの影響を与える方法を学んでいただけると幸いです。

# レンダリングパフォーマンスの最適化
ウェブページの表示速度は、ユーザーエクスペリエンスに大きく影響を与えます。特に、初期表示にかかる時間は非常に重要です。ウェブページの表示速度を向上させるには、レンダリングパフォーマンスの最適化が必要です。レンダリングパフォーマンスとは、ウェブページの描画処理の速度を指します。以下では、レンダリングパフォーマンスの最適化について紹介します。

## クリティカルレンダリングパスの理解
クリティカルレンダリングパスとは、ウェブページを描画するために必要なリソースのことです。クリティカルレンダリングパスには、HTML、CSS、JavaScript、画像などが含まれます。クリティカルレンダリングパスに関係するファイルのサイズや読み込み時間を最小化することで、ウェブページの表示速度を向上させることができます。

クリティカルレンダリングパスの最適化には、以下の方法があります。

### HTMLの最適化
HTMLの最適化は、ウェブページの読み込み速度を向上させるために非常に重要です。以下の方法でHTMLの最適化を行うことができます。

- 不要なコメントやスペース、改行を削除する
- HTMLファイル内で同じスタイルを重複して定義しない
- HTMLファイル内でのJavaScriptコードの最小化

### CSSの最適化
CSSは、ウェブページのデザインに欠かせない要素ですが、ファイルサイズが大きくなると読み込み時間が長くなり、レンダリングパフォーマンスが低下することがあります。以下の方法でCSSの最適化を行うことができます。

- 不要なCSSを削除する
- CSSファイル内での同じスタイルの重複を避ける
- CSSファイルを圧縮する
- CSSのインライン化を検討する

### JavaScriptの最適化
JavaScriptは、ウェブページの動的な操作に欠かせない言語ですが、大きなファイルサイズのJavaScriptコードは読み込み時間を遅延させ、レンダリングパフォーマンスを低下させることがあります。以下の方法でJavaScriptの最適化を行うことができます

- JavaScriptのファイルサイズを減らす
- JavaScriptの非同期読み込みを検討する
- JavaScriptの圧縮を行う
- JavaScriptのインライン化を検討する

### 画像の最適化
画像は、ウェブページを読み込むために必要なリソースですが、大きなファイルサイズの画像は読み込み時間を遅延させ、レンダリングパフォーマンスを低下させることがあります。以下の方法で画像の最適化を行うことができます。

- 画像の圧縮を行う
- 画像の遅延読み込みを検討する
- 画像のサイズを適切に設定する

### CSSとJavaScriptの最適化
CSSとJavaScriptは、ウェブページを装飾するための重要な役割を果たします。しかし、大きなファイルサイズのCSSやJavaScriptは読み込み時間を遅延させ、レンダリングパフォーマンスを低下させることがあります。以下の方法でCSSとJavaScriptの最適化を行うことができます。

- CSSとJavaScriptを外部ファイルとして分離する
- CSSとJavaScriptの圧縮を行う
- JavaScriptの非同期読み込みを検討する
- JavaScriptのインライン化を検討する
- CSSとJavaScriptのバンドルを行う

### 画像圧縮と遅延読み込み
画像は、ウェブページを読み込むために必要なリソースですが、大きなファイルサイズの画像は読み込み時間を遅延させ、レンダリングパフォーマンスを低下させることがあります。以下の方法で画像の最適化を行うことができます。

#### 画像圧縮
画像の圧縮を行うことで、画像のファイルサイズを小さくすることができます。画像の圧縮には、以下の方法があります。

- JPEG形式で保存する
- 画像のサイズを適切に設定する
- 画像ファイルの品質を下げる

#### 遅延読み込み
遅延読み込みは、ページの読み込みが完了してから画像を読み込むことで、ページの初期表示速度を向上させることができます。以下の方法で遅延読み込みを行うことができます。

- HTML5の loading="lazy" 属性を用いた遅延読み込み

#### 画像フォーマットの選択
画像のフォーマットは、読み込み時間や画質に影響を与えます。以下の方法で画像フォーマットの選択を行うことができます。

- JPEG: 写真やグラデーションが多い画像に適しています。
- PNG: 透過性を必要とする画像に適しています。
- GIF: アニメーションに適しています。
- WebP: JPEGやPNGよりも高い圧縮率を誇り、Webページの読み込み速度を向上させることができます。ただし、一部のブラウザでは対応していない場合があります。

以上が、レンダリングパフォーマンスの最適化についての紹介です。ウェブページの読み込み速度を向上させるためには、クリティカルレンダリングパスの最適化やCSSやJavaScriptの最適化、画像圧縮や遅延読み込みなどの方法を用いて、レンダリングパフォーマンスを向上させることが重要です。また、最適化手法の選択には、ユーザー体験の改善や目的に合わせたフォーマットの選択が含まれますので、注意が必要です。

# ネットワークパフォーマンスの最適化
ウェブページの表示速度を向上させるためには、ネットワークパフォーマンスの最適化が必要です。以下では、ネットワークパフォーマンスの最適化について紹介します。

## リソースのキャッシュ設定
ブラウザは、ウェブページに必要なリソースをダウンロードして表示します。リソースをキャッシュに保存することで、次回以降のアクセス時にリソースをダウンロードする必要がなくなり、読み込み時間を短縮することができます。以下の方法でリソースのキャッシュ設定を行うことができます。

- キャッシュ可能なリソースには、適切なキャッシュ期間を設定する
- リソースのバージョン管理を行うことで、古いキャッシュが残らないようにする

## HTTP/2やHTTP/3の利用
HTTP/2やHTTP/3は、ウェブページの表示速度を向上させるために開発されたプロトコルです。以下のような機能を提供しています。

- マルチプレックス化による、複数のリクエストを同時に処理することができる
- ヘッダーの圧縮による、ネットワーク帯域を節約することができる
- サーバープッシュによる、クライアントがリクエストする前に必要なリソースをプッシュすることができる

HTTP/2やHTTP/3を利用することで、ウェブページの表示速度を向上させることができます。

## CDN（コンテンツデリバリーネットワーク）の活用
CDN（コンテンツデリバリーネットワーク）は、世界中に配備されたキャッシュサーバーを用いて、コンテンツの配信を高速化するための仕組みです。以下のようなメリットがあります。

- キャッシュサーバーによる、リクエストの転送時間の短縮
- キャッシュサーバーによる、帯域幅の節約

CDNを利用することで、ウェブページの表示速度を向上させることができます。ただし、CDNの選択や設定には注意が必要です。

以上が、ネットワークパフォーマンスの最適化についての紹介です。ウェブページの表示速度を向上させるためには、リソースのキャッシュ設定やHTTP/2やHTTP/3の利用、CDNの活用などの方法を用いて、ネットワークパフォーマンスを向上させることが重要です。

また、ウェブページの表示速度を向上させるためには、レンダリングパフォーマンスの最適化と同様に、ユーザー体験の改善にも配慮する必要があります。例えば、レスポンシブデザインによるスマートフォンへの対応や、ウェブページの読み込み中にユーザーに対して進捗状況を示すプログレスバーの表示などが挙げられます。

以上のように、ウェブページの表示速度を向上させるためには、レンダリングパフォーマンスとネットワークパフォーマンスの最適化が必要です。また、ユーザー体験の改善にも配慮することが重要です。

# コード最適化とバンドルサイズの削減
ウェブアプリケーションを開発する上で、コード最適化とバンドルサイズの削減は非常に重要な課題です。ここでは、コード最適化とバンドルサイズの削減について説明します。

## コードスプリッティングと遅延読み込み
コードスプリッティングは、アプリケーションのコードを複数のファイルに分割することで、ページの読み込み速度を向上させることができます。また、遅延読み込みを使用することで、ページの初期表示速度を向上させることができます。

コードスプリッティングを行うには、WebpackやParcelなどのビルドツールを使用することができます。また、遅延読み込みには、import()構文を使用することができます。

Webpackを使用したコードスプリッティングと遅延読み込みのサンプルコードを示します。以下の例では、lodashというライブラリを使用していると仮定します。

```javascript
// app.js

import _ from 'lodash';

// heavy code block
_.map([1, 2, 3], n => {
  console.log(n);
});
```

```javascript
// webpack.config.js

const path = require('path');

module.exports = {
  mode: 'production',
  entry: './src/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
};
```

```html
<body>
  <script src="dist/bundle.js"></script>
</body>

```
Webpackのoptimization.splitChunks.chunksプロパティをallに設定することで、コードスプリッティングが行われます。また、import()構文を使用することで、遅延読み込みを行うことができます。以下は、lodashを遅延読み込みするサンプルコードです。

```javascript
// app.js

function heavyCodeBlock() {
  import(/* webpackChunkName: "lodash" */ 'lodash')
    .then(({ default: _ }) => {
      _.map([1, 2, 3], n => {
        console.log(n);
      });
    });
}

heavyCodeBlock();
```


## 未使用コードの削除 (Tree shaking)
未使用のコードが含まれている場合、バンドルサイズが大きくなり、ページの読み込み速度が遅くなる可能性があります。未使用コードの削除を行うことで、バンドルサイズを削減し、ページの読み込み速度を向上させることができます。

未使用コードの削除には、WebpackやRollupなどのビルドツールが標準でサポートしているTree shakingを使用することができます。Tree shakingを使用することで、アプリケーションのコードから未使用のコードを自動的に削除することができます。
```javascript
// app.js

import { add } from './math';

console.log(add(1, 2));
```

```javascript
// math.js

export function add(a, b) {
  return a + b;
}

export function sub(a, b) {
  return a - b;
}
```

```javascript
// rollup.config.js

import { terser } from 'rollup-plugin-terser';

export default {
  input: 'src/app.js',
  output: {
    file: 'dist/bundle.js',
    format: 'esm',
  },
  plugins: [
    terser(),
  ],
};
```

Rollupのterser()プラグインを使用することで、Tree shakingを自動的に行うことができます。未使用のsub関数は、最終的なバンドルファイルに含まれません。

## 適切なライブラリやフレームワークの選択
ウェブアプリケーションを開発する際には、適切なライブラリやフレームワークの選択が非常に重要です。ここでは、ライブラリやフレームワークの選択について、考慮すべき要素を紹介します。

### ライブラリとフレームワークの違い
ライブラリとフレームワークは、どちらも開発に必要なコードを提供しますが、その使用方法には違いがあります。ライブラリは、必要に応じて呼び出すことができるコードの集合体であり、フレームワークは、特定の方法でアプリケーションを構築するための構造を提供します。

フレームワークは、構造やルールが明確に定義されているため、アプリケーションの開発には時間がかかることがありますが、一方で、開発効率を向上させることができます。一方、ライブラリは、必要な時に必要な部分だけを使用することができ、フレームワークよりも柔軟性があります。

### 考慮すべき要素
適切なライブラリやフレームワークを選択する際には、以下の要素を考慮することが重要です。

#### 機能の必要性
ライブラリやフレームワークには、様々な機能が提供されています。開発に必要な機能を把握し、それらの機能を提供するライブラリやフレームワークを選択することが重要です。不要な機能を含むライブラリやフレームワークを使用すると、バンドルサイズが大きくなり、ページの読み込み速度が遅くなる可能性があるため、注意が必要です。

#### パフォーマンス
ウェブアプリケーションのパフォーマンスは、ユーザー体験に大きく影響します。開発に必要な機能を提供するライブラリやフレームワークを選択する際には、パフォーマンスも重要な要素の一つとして考慮することが必要です。

#### サポートとドキュメンテーション
ライブラリやフレームワークは、開発コミュニティによってサポートされています。開発に必要なライブラリやフレームワークを選択する際には、サポートの品質も考慮することが重要です。また、ドキュメンテーションの充実度も、開発効率を大きく左右する要素の一つとなります。

#### コミュニティ
ライブラリやフレームワークの使用は、開発者コミュニティによって支えられています。適切なライブラリやフレームワークを選択する際には、そのコミュニティがどの程度活発であるか、また、問題に対する解決策を提供するレスポンスタイムがどの程度かを考慮することが必要です。

### 適切なライブラリやフレームワークの例
以下に、ウェブアプリケーション開発において適切なライブラリやフレームワークの例をいくつか紹介します。

#### React
Reactは、Facebookが開発したJavaScriptライブラリです。Reactは、仮想DOM（Virtual DOM）を使用して、ページの再描画を最小限に抑えることができます。また、Reactは、高度なコンポーネントベースのアーキテクチャを提供するため、開発効率を向上させることができます。

[React 公式サイト](https://react.dev/)

#### Next.js
Next.jsは、Reactをベースとしたサーバーサイドレンダリング（SSR）フレームワークです。Next.jsは、ウェブアプリケーションの初期読み込みを高速化するために、サーバーサイドでページのコンテンツをレンダリングすることができます。また、Next.jsは、TypeScriptやESLintなど、多くの便利なツールを提供することができます。

[Next.js 公式サイト](https://nextjs.org/)

#### Vue.js
Vue.jsは、Evan Youが開発したJavaScriptフレームワークです。Vue.jsは、仮想DOMを使用することで、ページの再描画を最小限に抑えることができます。また、Vue.jsは、シンプルで柔軟性が高いAPIを提供するため、開発効率を向上させることができます。

[Vue.js 公式サイト](https://vuejs.org/)

#### Nuxt.js
Nuxt.jsは、Vue.jsをベースとしたサーバーサイドレンダリングフレームワークです。Nuxt.jsは、ウェブアプリケーションの初期読み込みを高速化するために、サーバーサイドでページのコンテンツをレンダリングすることができます。また、Nuxt.jsは、Vue.jsの機能に加えて、ルーティングやWebpackの設定を簡単にする機能を提供することができます。

[Nuxt.js 公式サイト](https://nuxt.com/blog/v3)

#### Svelte
Svelteは、Rich Harrisが開発した、コンパイル時のアプローチを採用したフロントエンドフレームワークです。Svelteは、実行時に必要なJavaScriptのコードを生成するため、ページの読み込み速度を高速化することができます。また、Svelteは、データバインディングやイベント処理など、多くの機能を提供しています。

[Svelte 公式サイト](https://svelte.dev/)

以上が、適切なライブラリやフレームワークの例です。適切なライブラリやフレームワークを選択することで、ウェブアプリケーションの開発効率やパフォーマンスを向上させることができます。


# パフォーマンス監視と測定
ウェブアプリケーションのパフォーマンスを測定し、常に改善することは、ウェブアプリケーションの成功に欠かせない要素の一つです。パフォーマンス監視や測定を行うことで、ウェブアプリケーションの問題点を特定し、改善することができます。以下では、パフォーマンス監視や測定の方法について説明します。

## LighthouseやWebPageTestなどのパフォーマンス測定ツール
LighthouseやWebPageTestなどのパフォーマンス測定ツールは、ウェブアプリケーションの読み込み時間、レンダリング時間、レイアウトの安定性など、多くのパフォーマンス指標を測定することができます。

### Lighthouse
Lighthouseは、Googleが提供するオープンソースのパフォーマンス測定ツールです。Lighthouseは、ウェブアプリケーションのパフォーマンスの改善に役立つ多くのアドバイスを提供してくれます。Lighthouseは、Google ChromeのDevToolsに統合されており、また、Node.jsモジュールとしても提供されています。

```javascript
// Lighthouseを使用したパフォーマンス測定のサンプルコード
const {lighthouse, getDefaultConfig} = require('lighthouse');
const chromeLauncher = require('chrome-launcher');

(async () => {
  const chrome = await chromeLauncher.launch({chromeFlags: ['--headless']});
  const config = getDefaultConfig();
  const result = await lighthouse('https://example.com', {port: chrome.port}, config);
  console.log(result.report);
  await chrome.kill();
})();
```

### WebPageTest
WebPageTestは、オンラインで利用できるパフォーマンス測定ツールです。WebPageTestは、リアルブラウザでの読み込み時間やレンダリング時間を測定することができます。WebPageTestは、世界各地のさまざまなブラウザでのテストをサポートしており、リージョンの選択が可能です。

## Google AnalyticsやReal User Monitoring (RUM)の利用
Google AnalyticsやReal User Monitoring (RUM)を使用することで、ウェブアプリケーションのパフォーマンスをリアルタイムに監視することができます。

### Google Analytics
Google Analyticsは、ウェブサイトの分析に広く使用されている無料のWebアナリティクスサービスです。Google Analyticsでは、ページビューやユーザー数、滞在時間など、様々なデータを取得することが可能です。また、Google Analyticsでは、ページの読み込み時間やレンダリング時間など、ウェブアプリケーションのパフォーマンスに関するデータを取得することもできます。

```javascript
// Google Analyticsを使用したパフォーマンス監視のサンプルコード
ga('create', 'UA-XXXXX-Y', 'auto');
ga('set', 'transport', 'beacon');
ga('send', 'pageview', {
  'timingCategory': 'performance',
  'timingVar': 'load',
  'timingValue': loadTime // 読み込み時間
});
```

### Real User Monitoring (RUM)
Real User Monitoring (RUM)は、ウェブアプリケーションのパフォーマンスをリアルタイムに監視することができるツールです。RUMは、ユーザーのブラウザ内で実行されるJavaScriptコードを使用して、読み込み時間やレンダリング時間、ユーザーエクスペリエンスに関するデータを収集します。

```javascript
// Real User Monitoringを使用したパフォーマンス監視のサンプルコード (ES6)
const rumScript = document.createElement('script');
rumScript.type = 'text/javascript';
rumScript.async = true;
rumScript.src = 'https://rum.example.com/agent.js';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(rumScript, firstScriptTag);

const observerCallback = list => {
  const entries = list.getEntries();
  for (const entry of entries) {
    if (entry.entryType === 'paint' && entry.name === 'first-contentful-paint') {
      const fcp = Math.round(entry.startTime);
      window.rum && window.rum.mark && window.rum.mark('fcp', fcp);
    }
  }
};

if (typeof window.PerformanceObserver === 'function') {
  const observer = new PerformanceObserver(observerCallback);
  observer.observe({entryTypes: ['paint']});
}
```


# ウェブアクセシビリティとパフォーマンスの関連性
ウェブアクセシビリティとは、障害を持つ人々がウェブサイトやアプリケーションを容易に使用できるようにするための設計や開発のことです。ウェブアクセシビリティは、誰もがウェブサイトやアプリケーションを利用できるようにするだけでなく、検索エンジンによるクロールや検索結果にも影響を与えます。

一方、パフォーマンスは、ウェブサイトやアプリケーションの読み込み速度やレスポンス速度など、ユーザーエクスペリエンスに密接に関わる重要な要素です。

ここでは、ウェブアクセシビリティとパフォーマンスの関連性について解説します。

## セマンティックHTMLの利用
セマンティックHTMLとは、HTML要素を適切な意味を持つようにマークアップすることです。例えば、`<h1>`要素は見出しを表すために使用され、`<p>`要素は段落を表すために使用されます。

セマンティックHTMLを使用することで、ページの構造を明確にすることができ、ウェブアクセシビリティとパフォーマンスの両方にプラスの影響を与えます。セマンティックHTMLを使用することで、検索エンジンによるクロールや検索結果にも影響を与え、ページの読み込み速度を向上させることができます。

```html
<!-- セマンティックHTMLを使用したサンプルコード -->
<header>
  <h1>ウェブアクセシビリティとパフォーマンスの関連性</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>
<main>
  <article>
    <h2>セマンティックHTMLの利用</h2>
    <p>セマンティックHTMLとは、HTML要素を適切な意味を持つようにマークアップすることです。</p>
  </article>
</main>
```

キーボードナビゲーションとは、キーボードを使用してウェブサイトやアプリケーションを操作することです。キーボードナビゲーションは、マウスやタッチデバイスを使用できないユーザーにとって必要不可欠な機能です。

ウェブアクセシビリティを考慮したウェブサイトやアプリケーションでは、キーボードナビゲーションの利便性を高めるように設計することが求められます。キーボードナビゲーションは、Tabキーを使用してフォーカスを移動させることで実現されます。

```javascript
// キーボードナビゲーションのサンプルコード (ES6)
const navItems = document.querySelectorAll('nav ul li a');

const handleKeyPress = (event) => {
  if (event.key === 'Enter') {
    event.target.click();
  }
};

navItems.forEach((item) => {
  item.addEventListener('keypress', handleKeyPress);
});
```
## ウェブアクセシビリティの向上によるパフォーマンスへのプラス効果
ウェブアクセシビリティの向上により、ウェブサイトやアプリケーションのパフォーマンスも向上する場合があります。例えば、セマンティックHTMLを使用することで、検索エンジンによるクロールや検索結果の向上が期待できます。また、キーボードナビゲーションの最適化は、マウスやタッチデバイスを使用できないユーザーにとって必要不可欠な機能であり、操作性の向上につながります。

ウェブアクセシビリティとパフォーマンスは密接に関連しており、両方を考慮した設計や開発を行うことで、より良いユーザーエクスペリエンスを提供することができます。

# まとめ
この記事では、フロントエンドエンジニアがウェブサイトやアプリケーションのパフォーマンスを最適化するためのテクニックについて解説しました。

ウェブサイトやアプリケーションのパフォーマンス最適化は、ユーザーエクスペリエンスを向上させるために必要不可欠な要素です。特に、モバイルデバイスの普及に伴い、ウェブサイトやアプリケーションの高速化が求められるようになっています。

本記事で取り上げたテクニックとして、レンダリングパフォーマンスの最適化、ネットワークパフォーマンスの最適化、コード最適化とバンドルサイズの削減、パフォーマンス監視と測定、ウェブアクセシビリティとパフォーマンスの関連性について解説しました。

さらに、最新技術やトレンドを活用してウェブ開発のスピードを向上させることも重要であることを紹介しました。例えば、DenoやSvelteなどの新しい技術を活用することで、開発スピードを向上させることができます。

最後に、パフォーマンス最適化は一度行えば終わりではなく、継続的な改善が必要であることを強調しました。定期的なパフォーマンステストや、ユーザーフィードバックを活用することで、常に改善を行っていくことが重要です。