このチュートリアルでは、TensorFlow.js を使用してリソースの予測プリフェッチを行うサンプル Web アプリケーションを実行します。この例はAngularで構築されており、Google Merchandise Store からインスピレーションを得ていますが、データや実装の詳細は Google Merchandise Store と共有しません。
この例では、事前トレーニングされたモデルを使用して予測を行います。実際のシナリオでは、Web サイトの分析を使用してモデルをトレーニングする必要があります。 TFX を使用すると、このようなトレーニングを行うことができます。予測プリフェッチ用のカスタム モデルのトレーニングの詳細については、このブログ投稿を参照してください。
サンプルコードはGitHubで入手できます。
前提条件
このチュートリアルを完了するには、開発環境に以下がインストールされている必要があります。
サンプルをインストールする
ソース コードを取得し、依存関係をインストールします。
-
tfjs-examples
リポジトリのクローンを作成するか、ダウンロードします。 angular-predictive-prefetching/client
ディレクトリに移動し、依存関係をインストールします。cd tfjs-examples/angular-predictive-prefetching/client && yarn
angular-predictive-prefetching/server
ディレクトリに移動し、依存関係をインストールします。cd ../server && yarn
サンプルを実行する
サーバーとクライアントの両方を起動します。
サーバーを起動します。
server
ディレクトリで、yarn start
を実行します。クライアントを起動します。
- 別のターミナル ウィンドウを開きます。
-
tfjs-examples/angular-predictive-prefetching/client
に変更します。 次のコマンドを実行します。
yarn build cd dist/merch-store npx serve -s .
サーブパッケージをインストールするように求められる場合があります。その場合は、 「y」と入力してパッケージをインストールします。
ブラウザで
http://localhost:3000
に移動します。模擬の Google 商品ストアが表示されるはずです。
DevTools を使って探索する
Chrome DevTools を使用して、プリフェッチの動作を確認します。
- DevTools を開いて[コンソール]を選択します。
アプリケーション内のいくつかの異なるページに移動して、アプリケーションを準備します。次に、左側のナビゲーションで[セール]を選択します。次のようなログ出力が表示されるはずです。
Navigating from: 'sale' 'quickview' -> 0.381757915019989 'apparel-unisex' -> 0.3150934875011444 'store.html' -> 0.1957530975341797 '' -> 0.052346792072057724 'signin.html' -> 0.0007763378671370447
この出力には、あなた (ユーザー) が次にアクセスするページの予測が表示されます。アプリケーションは、これらの予測に基づいてリソースを取得します。
フェッチリクエストを表示するには、 「ネットワーク」を選択します。出力には少しノイズが含まれますが、予測されたページのリソースに対するリクエストを見つけることができるはずです。たとえば、
quickview
を予測した後、アプリケーションはhttp://localhost:8000/api/merch/quickview
にリクエストを送信します。
予測プリフェッチの仕組み
サンプルアプリでは、事前トレーニングされたモデルを使用して、ユーザーが次にアクセスするページを予測します。ユーザーが新しいページに移動すると、アプリはモデルをクエリし、予測されたページに関連付けられた画像をプリフェッチします。
アプリはService Workerで予測プリフェッチを実行するため、メインスレッドをブロックせずにモデルをクエリできます。ユーザーのナビゲーション履歴に基づいて、サービス担当者は将来のナビゲーションを予測し、関連する製品画像をプリフェッチします。
Service Worker は、Angular アプリのメイン ファイルmain.tsにロードされます。
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/prefetch.service-worker.js', { scope: '/' });
}
上記のスニペットは、 prefetch.service-worker.js
スクリプトをダウンロードし、バックグラウンドで実行します。
merch-display.component.tsでは、アプリはナビゲーション イベントを Service Worker に転送します。
this.route.params.subscribe((routeParams) => {
this.getMerch(routeParams.category);
if (this._serviceWorker) {
this._serviceWorker.postMessage({ page: routeParams.category });
}
});
上のスニペットでは、アプリは URL のパラメーターの変更を監視します。変更時に、スクリプトはページのカテゴリを Service Worker に転送します。
Service Worker スクリプトprefetch.service-worker.js は、メインスレッドからのメッセージを処理し、それらに基づいて予測を行い、関連するリソースをプリフェッチします。
Service Worker は、 loadGraphModel
を使用して事前トレーニングされたモデルをロードします。
const MODEL_URL = "/assets/model.json";
let model = null;
tf.loadGraphModel(MODEL_URL).then((m) => (model = m));
予測は次の関数式で行われます。
const predict = async (path, userId) => {
if (!model) {
return;
}
const page = pages.indexOf(path);
const pageId = tf.tensor1d([parseInt(page)], "int32");
const sessionIndex = tf.tensor1d([parseInt(userId)], "int32");
const result = model.predict({
cur_page: pageId,
session_index: sessionIndex,
});
const values = result.dataSync();
const orders = sortWithIndices(values).slice(0, 5);
return orders;
};
次に、 predict
関数がプリフェッチ関数によって呼び出されます。
const prefetch = async (path, sessionId) => {
const predictions = await predict(path, sessionId);
const formattedPredictions = predictions
.map(([a, b]) => `'${b}' -> ${a}`)
.join("\n");
console.log(`Navigating from: '${path}'`);
console.log(formattedPredictions);
const connectionSpeed = navigator.connection.effectiveType;
const threshold = connectionSpeeds[connectionSpeed];
const cache = await caches.open(ImageCache);
predictions.forEach(async ([probability, category]) => {
if (probability >= threshold) {
const merchs = (await getMerchList(category)).map(getUrl);
[...new Set(merchs)].forEach((url) => {
const request = new Request(url, {
mode: "no-cors",
});
fetch(request).then((response) => cache.put(request, response));
});
}
});
};
まず、 prefetch
、ユーザーが次にアクセスする可能性のあるページを予測します。次に、予測を繰り返します。各予測について、確率が接続速度に基づく特定のしきい値を超える場合、関数は予測されたページのリソースをフェッチします。次のページ要求の前にこれらのリソースを取得することで、アプリはコンテンツをより速く提供し、より良いユーザー エクスペリエンスを提供できる可能性があります。
次は何ですか
このチュートリアルでは、サンプル アプリは事前トレーニングされたモデルを使用して予測を行います。 TFXを使用して、予測プリフェッチ用のモデルをトレーニングできます。詳細については、 「機械学習を使用した Web ページのプリフェッチによるサイトの高速化」を参照してください。