過去にguess-webpack を使う | Monotalk当ブログに guess-js を組み込みました。

当ブログは、Jquery や、Turbolinks 等の他のJSライブラリを使い、Webpack でビルドを行なっていますが、guess-js 自体は単独でビルドして使用することもできます。

試しに guess-js を単独で使用するため、kemsakurai/guess-webpack-starter作成してみました。
作成に至る経緯、guess-js を使う際の考慮する点を記載します。


作成に至る経緯

作るに至った経緯を記載します。

個人的に良いライブラリだと思った

Google大変動影響もあるのかと思いますが、以下の理由から良いライブラリだと思いました。

  • 導入後にPageviewが増加した。
    導入後の1週間で5%-10%程度かと思いますが、Pageviewが増加しました。
    ただこれはブラウザの prefetch 動作に依存するので、先読みページの Google Analytics タグ が起動しているケースもあるかもしれません。

  • 導入が簡単
    Turbolinks との併用でしたが、特に競合することもなく、guess() function との組み合わせで先読みが実装できました。

Webアーキテクチャに左右されず、様々なサイトで使用できる

build は Webpack を使用しますが、build した JavaScript は、MPAのページでも利用可能です。
フロントエンドの 開発スタイルが古いサイトにも適用できます。

サイトの JavaScript ビルドのために、Webpack 等を使っているケースだとその Webpack に組み込めばよいですが、モジュールバンドラやビルドシステムを使っていないケースもあり、guess-js だけスタンドアローンビルドできると、それなりにユースケースがあるかと思い作成しました。


そもそも Guess-js とは何か?

gatsby-plugin-guess-js を使う | Monotalk記載していますが、改めてまとめます。

初期読み込み速度と、次ページの読み込み速度

PageSpeed Insightsページの初期読み込み速度を評価するツールです。
初期読み込みの速度は以下の手法で改善できます。

  • HTML、JS、CSS 等のリソース縮小
  • HTML、JS、CSS 等のリソース圧縮
  • JS、CSS 等のリソース結合 (HTTP接続本数を減らす)
  • サーバーサイドレスポンス速度改善
  • JS、CSS 等のリソース非同期読み込み
  • クリティカルCSS の抽出
  • Resource Hint API

次ページの読み込みの速度は、初期読み込み速度の手法も関係しますが、JS、<wbr>CSS等の<wbr>リソースが<wbr>Cacheされている<wbr>いう違いがあります。PageSpeed Insights次ページの読み込みの速度を評価するツールではありません。
次ページの読み込みの速度は以下の手法で改善できます。

  • Pjax ライブラリを使う。
  • サイトをSPAにする。
  • PWA の cache で 次ページの表示時に必要なリソースを読み込んでおく。
  • Guess-js を使う。

Guess-js は PageSpeed Insights のスコアの改善には寄与せず、次ページの読み込み速度の改善に寄与します。

Guess-js が行っている処理

Webpack でのコンパイル時と、クライアント側で行なっている処理の流れを記載します。

  • geuss-webpack で行う処理

    • Google Analytics のアクセスデータから、単純確率行列 (マルコフ連鎖) を作成する。
    • 作成した行列をJSON化して、エントリーポイントとなる JavaScript に追加する。
  • クライアント側でguess() function が行う処理

    • 引数が指定されていなければ、現在のページの次のページを 単純確率行列から取得する。
    • Network Information API を使い、ブラウザの回線を特定する。 APIが使用できないブラウザは 3g扱いにする。
    • 各回線ごとの閾値を取得、閾値以上の確率を持つページを取得する。
  • 各回線ごとの閾値
    デフォルトの閾値は以下の通りです。
    4g であれば 15% 以上の確率で遷移するページを取得します。

    export const defaultPrefetchConfig: PrefetchConfig = {
      '4g': 0.15,
      '3g': 0.3,
      '2g': 0.45,
      'slow-2g': 0.6
    };
    
    閾値は、Webpack.config.js に指定することもでき、指定する場合は以下のように記載します。
    new GuessPlugin(
        { GA: 'xxxxxxxxxx',
        debug: true,
        runtime: {
            basePath: '',
            // true > PrefetchPlugin 、false > PrefetchAotPlugin の切替を行う
            delegate: true,
            // 回線ごとの閾値の指定
            prefetchConfig: {
                '4g': 0.15,
                '3g': 0.25,
                '2g': 0.45,
                'slow-2g': 0.6
            }
        }
        })
    


guess-js を使う際の考慮する

以下、guess-js を使う際に考慮する点を思いついただけ記載します。

  • 先読みしないブラックリストページの制御が必要
    ページ表示時にデータ更新が発生するページは、ユーザーの意図しない挙動になる可能性があります。
    ログアウトページや、ログイン処理、入力フォームからの遷移先なども状態変化が何かしら起こるため先読みに適さないかと思います。
    現状、guess-js には ブラックリストを除外する機能がないため、Google Analytics で 除外対象ページを絞り込んだ VIEW を作成するか、prefetch の直前でブラックリストページを除外するのが良いかと思います。

  • Cache-Control ヘッダーとの組み合わせでの動作の検証が必要
    Cache-Control ヘッダーに、no-store付与されている場合、prefetch しても Cache が利用されず再度取得する可能性があります。

  • サーバーへのアクセスが増えるので、どの程度追加のアクセスが発生するか見積もりしておく
    通信量、サーバー負荷に影響があるかと思います。
    生成した JavaScript と 現状のアクセス数を元に程度、見積もりしてどの程度増加するのか把握する必要があります。

  • Google Analytics のアクセス数の増減
    prefetch が影響して、Google Analytics のアクセス数の増減がないか、HTTPサーバー側で区別して記録したいのか等の検討が必要になります。
    Firefox の場合、X-mozいうヘッダーが送信されるのでこれを元に区別してもいいかもしれません。

  • CrossDomain設定時のURLの調整
    Google Analytics の CrossDomain 設定を行なっている VIEW の場合、取得できるURLの形式がwww始まる場合、取得したURLでは prefetch できない可能性があります。
    guess-webpack には、routeFormatterいうオプションを指定できるので、これで URLを調整するか、reportProvider Google Analytics からのデータ取得方法を変更するかどちらかの方法で URL を変更した方が良いかと思います。

  • 定期的にJavaScript の再生成が必要
    guess-webpack は ビルド時点での Google Analytics のデータをもとにページ先読みのための行列を生成しています。
    サイト上でのアクセス傾向が変化する可能性があるので、定期的に JavaScript ファイルの再生成が必要になります。

以下、guess-webpack を使う | Monotalk記載していた内容の転載です。

  • ログイン、末ログイン 等でページの表示が切り替わるページにはなんらかの対策が必要
    prefetch で HTML の先読みを実施するのでログイン、末ログインで表示が切り替わる場合は、Cache を削除する。 そもそも prefetch させないなどの対策が必要かと思います。 ログイン、末ログインが表示に影響がないようなサイトで使うのがよさそうに思います。

guess-webpack-starter の使い方

kemsakurai/guess-webpack-starter README.md記載しました。

  • 補足
    GuessPlugin の delegate オプションは true指定し、PrefetchPlugin使用しています。PrefetchAotPlugin は、前もって予測を行うことができるようですが、ドキュメントがなくイマイチ使い方がわかりませんでした。Example 等ができたらこちらも試してみたいと思います。

参考

以下、参考にした文書です。
* Introduce AoT predictive prefetching by mgechev · Pull Request #94 · guess-js/guess

以上です。

コメント