ページ読み込みを高速化するためのJavaScript優先度の最適化

スクリプトの優先順位を効果的に設定してCore Web Vitalsを向上させる方法を学びましょう。

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2024-12-12

ウェブパフォーマンス向上のためのJavaScript優先度管理

一つだけ常に明確なことがあります:すべてのJavaScriptが同じように作られているわけではありません。「メニュー操作」や「カートに追加」のような重要なインタラクションを処理するスクリプトもあれば、はるかに重要度の低いスクリプトもあります。例えば、サイトを離れようとしている訪問者にアンケートへの回答を促す「離脱意図」ポップアップスクリプトを考えてみてください。後者がなくても問題ありませんが、前者がなければウェブサイトのナビゲーションは非常に困難になります。

しかし、「一般的なウェブサイト」では技術的なレベルでこの区別がほとんどされていません。すべてのJavaScriptが「ただ追加」され、ブラウザに判断が委ねられています。これは問題です。なぜなら、ブラウザには何が重要で何が重要でないかが分からないからです。開発者である私たちには分かります。それでは修正しましょう!

JavaScriptの優先度がCore Web Vitalsに与える影響

適切な配慮なしにスクリプトをページに追加すると、3つのCore Web Vitalsすべてに影響を与える可能性があります。Largest Contentful Paint、Interaction to Next Paint、そしてCumulative Layout Shiftです。 

javascript lcp impact example

例:LCPネットワークリソースがレンダーブロッキングJavaScriptによって遅延している

Largest contentful Paintは帯域幅とCPUの競合の影響を受けやすいです。多くのスクリプトが早期のネットワークリソースを奪い合うと、Largest Contentful Paintのネットワークリソースが遅延し、早期のCPU処理がメインスレッドをブロックしてLCPを遅延させます。

Interaction to Next Paintは、インタラクションの直前に実行されるスクリプトの影響を受ける可能性があります。スクリプトが実行されるとメインスレッドがブロックされ、その実行時間中のすべてのインタラクションが遅延します。

スクリプトは、ページの見た目を「変更」する場合、Cumulative Layout Shift を引き起こすこともあります。ページにバナーを挿入する広告スクリプトやスライダーは、これを引き起こすことで有名です。

5種類のJavaScript優先度

私はJavaScriptの優先度を5種類に分けて考えています。詳しく見る前に、それぞれを簡単に説明しましょう。

  • レンダークリティカル:これらのスクリプトは最も問題になりやすいものです。ページのレイアウトを変更し、これらのスクリプトを読み込まないとレイアウトが完全に異なるものになります。例:一部のスライダースクリプトやA/Bテスト。
  • クリティカルスクリプト:これらのスクリプトはページの重要な機能を処理し、これらのスクリプトなしではカートへの商品追加、サイト検索、ナビゲーションなどの重要なタスクが実行できません。
  • 重要なスクリプト:これらのスクリプトは重要な(ビジネス)ロジックを処理し、サイトはこれらに依存しています。例:アナリティクス
  • あると便利なスクリプト:これらのスクリプトはあると便利ですが、どうしても必要というわけではなく、ページの機能に不可欠ではありません。例:チャットウィジェットや離脱意図ポップアップ
  • 将来のスクリプト:これらのスクリプトはクリティカルかもしれませんし、あると便利なものかもしれませんが、実際に使用する前に「他のステップ」が必要なため、今すぐは必要ありません。例:多段階チェックアウトスクリプト。
スクリプトの優先度について理解できたところで、詳しく見ていきましょう!

1. レンダークリティカルスクリプト

これらは最も影響の大きいスクリプトで、ページの表示に直接影響します。これらがないと、レイアウトが崩れたり、意図したデザインと大きく異なって表示される可能性があります。例として、読み込みプロセスの早い段階でレイアウトを変更するスライダーやA/Bテストフレームワークのスクリプトがあります。 

この種のスクリプトの問題は、遅延させたり延期させたりできないことです。いかなる遅延もウェブサイトのレイアウトシフトを引き起こし、UXの低下とCore Web Vitalsの悪化につながります。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Page Title</title>
    <link href="styles.css" rel="stylesheet" />
    <script src="render-critical.js"></script>
  </head>
  <body></body>
</html>

ベストプラクティス:

  • 可能な限りこのようなレンダークリティカルスクリプトを避けてください。この種のスクリプトへの依存を避けるようにコードを書き直しましょう。
  • どうしても避けられない場合は、これらのスクリプトの絶対に必要な部分のみをインライン化または読み込みましょう。 
  • これらのスクリプトにdeferやasyncを付けず、「できるだけ早く」ダウンロードを開始するためにheadの上部に配置してください。

2. クリティカルスクリプト

これらのスクリプトは基本的なインタラクションを可能にします。これらがないと、サイトナビゲーション、カートへの商品追加、Cookie通知、検索の実行などの重要なタスクが不可能になります。サイトのコア機能に不可欠です。

これらのスクリプトは、asyncまたはdefer属性を付けてページのheadに配置すべきです。

<script defer src="critical.js"></script>
<script async src="critical.js"></script>

ベストプラクティス:

  • このようなスクリプトは最小限に抑え、この機能を他の重要度の低い機能と組み合わせないでください。
  • 依存関係に応じて、asyncまたはdeferを使用してこれらのスクリプトを早期に読み込みましょう。
  • CoreDashなどのReal User Monitoring(RUM)ツールを使用して、実行のボトルネックを特定し、パフォーマンスがユーザーのニーズに合致していることを確認しましょう。

3. 重要なスクリプト

サイトのユーザビリティに直接結びついているわけではありませんが、重要なスクリプトは主要なビジネス機能をサポートします。例えば、アナリティクススクリプトは不可欠なデータを提供しますが、より重要なビジュアル要素の前に読み込む必要はありません。クリティカルと重要の区別は議論の余地があるため、この優先度を設定する前にすべての関係者に確認してください!

この種のスクリプトの優先度を下げる方法は3つあります。

<html>
<head>
<!-- method 1: low fetchpriority -->
<script fetchpriority="low" defer src="important.js"></script>

<!-- method 2: inject after DOMContentLoaded -->
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var script = document.createElement('script');
    script.src = 'important.js';
    document.body.appendChild(script);
  });
</script>
</head>
<body>

<!-- method 3: place at the bottom of the page -->
<script defer src="important.js"></script>
</body>
</html>

1. Low fetchpriority 

fetchpriorityを設定するとスクリプトの相対的な優先度が下がります。他のdeferredまたはasyncedスクリプトは高い優先度でキューに入れられる可能性が高いですが、fetchprioriy="low"のスクリプトは低い優先度でキューに入れられます。ページ(またはレンダリングパス)によっては、Largest Contentful Paint画像や重要なフォントなどの他のリソースを優先するのにこれで十分かもしれません。 

2: DOMContentLoaded後にインジェクト

DOMContentLoadedイベント後にスクリプトをインジェクトすることで、HTMLが完全にパースされた直後にスクリプトのダウンロードが開始されるようにします。これにより、画像やフォントなどの発見可能なリソースが優先されます。この方法はバランスが取れています:機能の遅延を避けるのに十分早くスクリプトの読み込みが始まりますが、初期ページレンダリングに不可欠な早期リソースとは競合しません。

3: ページの下部に配置

この古典的なテクニックは、ブラウザがドキュメント全体を処理した後までスクリプトの読み込みを遅延させ、テクニック2とほぼ同じ結果を達成します。唯一の違いは、テクニック2はブラウザのプリロードスキャナーをスキップしますが、このテクニックはスキップしないことです。 プリロードスキャナーは、ブラウザが重要なリソースを素早く特定してキューに入れるために使用する軽量なクイックスキャナーです。ビューポート内に遅延読み込み画像がある可能性がある場合はプリロードスキャナーをスキップするのが良いかもしれませんが、プリロードスキャナーを使用するとこのスクリプトの読み込みが速くなります。

4. あると便利なスクリプト

これらのスクリプトはユーザー体験を向上させますが、サイトの機能に必須ではありません。例として、チャットウィジェット、顧客フィードバックポップアップ、またはオプションのアニメーションがあります。有益ではありますが、主要なユーザー体験を妨げるべきではありません。

これらのスクリプトは「lazy on load」と呼ばれるパターンで読み込むのが理想的です。これは、ページのloadイベントを待ってから、アイドル時間中にスクリプトをインジェクトすることを意味します。 loadイベントを待つことで、スクリプトがより重要な早期リソースと帯域幅やCPU を奪い合わないようにします。アイドルの瞬間を待つことで、ブラウザがユーザー入力などのより重要なタスクを処理していないことを確認します。

動作する例を示します:

window.addEventListener("load", () => {
  window.requestIdleCallback(() => {
    const script = document.createElement("script");
    script.src = "/path/to/script.js";
    document.head.appendChild(script);
  });
});

ベストプラクティス:

  • これらのスクリプトはページの読み込み後に遅延読み込みし、アイドルの瞬間を待ちましょう。
  • このパターンで読み込まれたスクリプトは高速な読み込みが保証されないことを理解しておきましょう。

5. 将来のスクリプト

将来のスクリプトは、特定の条件が満たされるまで必要とされないものです。例えば、多段階チェックアウトスクリプトは、ユーザーがカートに商品を追加した後にのみ関連性が出てきます。これらのスクリプトは、ユーザーのジャーニーのかなり後の段階まで待つことができる場合が多いです。

この例を見てください。Intersection Observerを使用して、フォームが表示可能なビューポートに入った時にのみ、サインアップスクリプトに必要なJSロジックを読み込みます。

<!DOCTYPE html>
<html>
  <head>
    <script>
      document.addEventListener("DOMContentLoaded", function () {
        const form = document.querySelector("form");
        const observer = new IntersectionObserver(function (entries) {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              const script = document.createElement("script");
              script.src = "/sign-up.js";
              document.head.appendChild(script);
              observer.unobserve(form);
            }
          });
        });
        observer.observe(form);
      });
    </script>
  </head>
  <body>
    <form action="/sign-up" method="post">
      <label for="email">Email:</label>
      <input type="email" id="email" name="email" required />
      <button type="submit">Sign Up</button>
    </form>
  </body>
</html>

ベストプラクティス:

  • これらのスクリプトはオンデマンドで、ユーザーのアクションをトリガーとして読み込みましょう。
  • コード分割テクニックを使用して、各ステップで必要な部分のみを配信しましょう。
  • ユーザーが特定のセクションまでスクロールした時など、必要な時にのみ動的にインジェクトしましょう。

Urgent Fix Required?

Google Search Console failing? I offer rapid-response auditing to identify the failure point within 48 hours.

Request Urgent Audit >>

  • 48hr Turnaround
  • Rapid Response
  • Failure Identification
ページ読み込みを高速化するためのJavaScript優先度の最適化Core Web Vitals ページ読み込みを高速化するためのJavaScript優先度の最適化