過去に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、CSS等のリソースがCacheされている
という違いがあります。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% 以上の確率で遷移するページを取得します。
閾値は、Webpack.config.js に指定することもでき、指定する場合は以下のように記載します。export const defaultPrefetchConfig: PrefetchConfig = { '4g': 0.15, '3g': 0.3, '2g': 0.45, 'slow-2g': 0.6 };
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
-
requestIdleCallback()による協調的バックグラウンド処理の実現 / requestIdleCallback() - Speaker Deck
guess-js の内部で使っていて、気になりました。 -
Cannot read property ‘guess’ of undefined · Issue #83 · guess-js/guess
GuessPlugin
プロパティの設定方法がこのIsuue に記載してあります。 -
prefetch
in combination ofCache-Control
· Issue #21 · GoogleChromeLabs/quicklink
以上です。
コメント