メインコンテンツへスキップ
ブログ一覧に戻る
web

JavaScript/CSS最適化完全ガイド:パフォーマンスを劇的に改善する実践手法

2025年11月17日
11分で読めます
JavaScript/CSS最適化完全ガイド:パフォーマンスを劇的に改善する実践手法

JavaScript/CSS最適化完全ガイド:パフォーマンスを劇的に改善する実践手法

「JavaScriptが重くて読み込みが遅い」「FIDが改善しない」「バンドルサイズが大きすぎる」と感じたことはありませんか?

JavaScript/CSS最適化は、Webサイトのパフォーマンスを改善する重要な方法です。JavaScriptとCSSは、ページの読み込み時間、FID(First Input Delay)、TBT(Total Blocking Time)に直接影響します。

この記事では、JavaScript/CSS最適化の基礎から実践まで、コード分割、ミニファイ、Tree Shaking、バンドル最適化、Critical CSSの実装方法を、具体的なコード例とベストプラクティスを交えて網羅的に解説します。

この記事を読む前に

この記事では、Webサイト制作とパフォーマンスの基礎知識があることを前提としています。以下の記事を事前に読んでおくと、より深く理解できます:

この記事でわかること

  • JavaScript/CSS最適化とは何か、なぜ重要なのか
  • コード分割の実装方法
  • ミニファイと圧縮の最適化
  • Tree Shakingの活用
  • バンドルサイズの最適化
  • Critical CSSの実装
  • 非同期読み込みの最適化
  • 具体的な最適化事例

1. JavaScript/CSS最適化とは何か?

1.1 基本的な定義

JavaScript/CSS最適化とは、JavaScriptとCSSファイルのサイズを削減し、読み込み速度と実行速度を向上させるプロセスです。

JavaScript/CSS最適化が重要な理由

JavaScriptとCSSは、ページのパフォーマンスに直接影響します。ファイルサイズが大きいと、読み込み時間が長くなります。例えば、500KBのJavaScriptファイルを100KBに削減することで、読み込み時間を80%短縮できます。JavaScriptの実行が長いと、FID(First Input Delay)が悪化します。例えば、メインスレッドをブロックする処理を削減することで、FIDを改善できます。メインスレッドのブロック時間が長いと、TBT(Total Blocking Time)が悪化します。CSSの読み込みが遅いと、LCP(Largest Contentful Paint)が悪化します。例えば、クリティカルCSSをインライン化することで、LCPを改善できます。

1.2 最適化の種類

コード分割

  • コードを小さなチャンクに分割
  • 必要なコードだけを読み込む

ミニファイと圧縮

  • コードを最小化
  • Gzip/Brotli圧縮

Tree Shaking

  • 使用されていないコードを削除

バンドル最適化

  • バンドルサイズを最適化
  • 重複コードの削除

これらの最適化により、Webサイトのパフォーマンスを大幅に向上させられます。コード分割により、初期読み込み時のJavaScriptの量を削減できます。例えば、100KBのJavaScriptファイルを20KBのチャンクに分割することで、初期読み込み時間を80%削減できます。ミニファイと圧縮により、ファイルサイズを30-50%削減できます。例えば、100KBのJavaScriptファイルをミニファイと圧縮することで、50KBに削減できます。Tree Shakingにより、使用されていないコードを削除し、バンドルサイズをさらに削減できます。例えば、ライブラリから必要な関数だけをインポートすることで、バンドルサイズをさらに削減できます。

2. コード分割

2.1 動的インポート

基本的な実装

// ❌ 悪い例:全てのコードを一度に読み込む
import HeavyComponent from './HeavyComponent';

// ✅ 良い例:動的インポート
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>Loading...</p>,
});

動的インポートにより、必要なコードだけを読み込むことができます。これにより、初期読み込み時のJavaScriptの量を削減し、パフォーマンスを向上させます。例えば、モーダルウィンドウのコンポーネントを動的インポートすることで、モーダルが開かれるまでコンポーネントを読み込まないため、初期読み込み時間を短縮できます。

2.2 ルートベースのコード分割

Next.jsでの実装

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割

ルートベースのコード分割により、各ページに必要なコードだけを読み込むことができます。これにより、初期読み込み時のJavaScriptの量を削減し、パフォーマンスを向上させます。例えば、トップページに必要なコードだけを読み込むことで、他のページのコードを読み込む必要がなくなり、初期読み込み時間を短縮できます。

2.3 コンポーネントベースのコード分割

Reactでの実装

import { lazy, Suspense } from 'react';

// 遅延読み込み
const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

コンポーネントベースのコード分割により、必要なコンポーネントだけを読み込むことができます。これにより、初期読み込み時のJavaScriptの量を削減し、パフォーマンスを向上させます。例えば、重いチャートコンポーネントを遅延読み込みすることで、初期読み込み時間を短縮できます。

3. ミニファイと圧縮

3.1 ミニファイ

ツール

  • Terser:JavaScriptのミニファイツール
  • cssnano:CSSのミニファイツール
  • webpack:ビルドツール(自動ミニファイ)

実装例(webpack)

// webpack.config.js
module.exports = {
  mode: 'production', // 自動的にミニファイ
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // console.logを削除
          },
        },
      }),
      new CssMinimizerPlugin(),
    ],
  },
};

ミニファイにより、コードから不要な空白、改行、コメントを削除できます。これにより、ファイルサイズを30-50%削減できます。例えば、100KBのJavaScriptファイルをミニファイすることで、50KBに削減できます。これにより、読み込み時間を大幅に短縮できます。

3.2 圧縮

Gzip圧縮

# nginx設定
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

Brotli圧縮

# nginx設定
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

Gzip/Brotli圧縮により、ファイルサイズをさらに50-70%削減できます。これにより、読み込み時間を大幅に短縮できます。例えば、100KBのJavaScriptファイルをGzip圧縮することで、30KBに削減できます。Brotli圧縮を使用することで、さらに20KBに削減できます。

4. Tree Shaking

4.1 基本的な実装

ES Modulesの使用

// ❌ 悪い例:CommonJS
const utils = require('./utils');
const result = utils.function1();

// ✅ 良い例:ES Modules
import { function1 } from './utils';
const result = function1();

Tree Shakingにより、使用されていないコードを削除できます。これにより、バンドルサイズをさらに削減できます。例えば、ライブラリから必要な関数だけをインポートすることで、使用されていない関数を削除し、バンドルサイズを削減できます。ES Modulesを使用することで、Tree Shakingが有効になります。

4.2 webpackでのTree Shaking

実装例

// webpack.config.js
module.exports = {
  mode: 'production',
  optimization: {
    usedExports: true, // Tree Shakingを有効化
    sideEffects: false, // 副作用がないことを示す
  },
};

package.json

{
  "sideEffects": false
}

5. バンドルサイズの最適化

5.1 バンドル分析

webpack-bundle-analyzer

// webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin(),
  ],
};

なぜバンドル分析が重要か?

バンドル分析により、バンドルサイズの内訳を確認できます。これにより、大きな依存関係を特定し、最適化の優先順位を決定できます。

5.2 依存関係の最適化

重複コードの削除

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
0___

依存関係を別のチャンクに分割することで、キャッシュを効率的に使用できます。また、重複コードを削除することで、バンドルサイズを削減できます。例えば、ReactやVueなどのライブラリを別のチャンクに分割することで、ライブラリが更新されても、アプリケーションコードのキャッシュが有効になります。

6. Critical CSS

6.1 基本的な実装

Critical CSSの抽出

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
1___

HTMLでの実装

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
2___

Critical CSSをインラインで読み込むことで、レンダリングブロックを回避できます。これにより、LCPが改善されます。Critical CSSは、ページの最初の表示に必要なCSSのみを含むため、レンダリングブロックを回避できます。例えば、ページの最初の表示に必要なCSSをインラインで読み込むことで、レンダリングブロックを回避し、LCPを改善できます。

6.2 Next.jsでの実装

実装例

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
3___

7. 非同期読み込み

7.1 deferとasync

defer

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
4___

async

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
5___

defer/asyncにより、スクリプトの読み込みがHTMLのパースをブロックしません。これにより、ページの読み込み時間を短縮できます。deferは、HTMLのパースが完了した後にスクリプトを実行します。asyncは、スクリプトの読み込みが完了したらすぐに実行します。どちらも、HTMLのパースをブロックしないため、ページの読み込み時間を短縮できます。

7.2 動的スクリプト読み込み

実装例

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
6___

8. 具体的な最適化事例

8.1 事例1:SPAのバンドルサイズ最適化

課題

  • バンドルサイズ:2MB
  • 読み込み時間:5秒
  • 問題:全てのコードを一度に読み込んでいる

解決策

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
7___

結果

  • バンドルサイズ:2MB → 500KB(75%削減)
  • 読み込み時間:5秒 → 1.5秒(70%改善)
  • FID:300ms → 80ms(73%改善)

8.2 事例2:CSS最適化

課題

  • CSSサイズ:200KB
  • LCP:3.5秒
  • 問題:Critical CSSが抽出されていない

解決策

___

// pages/index.js
export default function Home() {
  return <div>Home Page</div>;
}

// pages/about.js
export default function About() {
  return <div>About Page</div>;
}

// Next.jsが自動的にコード分割
8___

結果

  • LCP:3.5秒 → 1.8秒(49%改善)
  • 初期読み込み時間:40%短縮

JavaScript/CSS最適化の要点

  • JavaScript/CSS最適化は、パフォーマンスを改善する重要な方法
  • コード分割により、必要なコードだけを読み込む
  • ミニファイと圧縮により、ファイルサイズを削減
  • Tree Shakingにより、使用されていないコードを削除
  • Critical CSSにより、レンダリングブロックを回避
  • 非同期読み込みにより、HTMLのパースをブロックしない

次のステップ

  1. バンドルサイズを分析(webpack-bundle-analyzer)
  2. コード分割を実装(動的インポート、ルートベース分割)
  3. ミニファイと圧縮を設定(Terser、Gzip/Brotli)
  4. Tree Shakingを有効化(ES Modules、webpack設定)
  5. Critical CSSを抽出(critical、inline)
  6. 効果を検証(パフォーマンス測定)

次に読むおすすめの記事

JavaScript/CSS最適化について理解を深めたら、以下の記事も参考にしてください:

より深く学ぶ

実践的な活用

関連する基礎知識

参考資料・引用元


ご相談・お問い合わせはこちら

次の一手

状況に合わせて、選んでください。