使用机器学习加速网站网页预取
2021 年 5 月 18 日

作者:Minko Gechev、David Zats、Na Li、Ping Yu、Anusha Ramesh 和 Sandeep Gupta

页面加载时间是网站用户体验最重要的决定因素之一。 研究 表明,更快的页面加载时间直接导致页面浏览量、转化率和客户满意度的提高。零售巨头 Newegg 在实施网页预取以优化页面加载体验后,转化率提高了 50%。

使用 TensorFlow 工具,现在可以使用机器学习为您的网站实现强大的解决方案,以改善页面加载时间。在这篇博文中,我们展示了使用您网站的 Google Analytics 导航数据训练自定义机器学习模型的端到端工作流程,该模型可以预测用户的下一步操作。您可以将这些预测用于 Angular 应用程序,以预取候选页面,并极大地改善您网站的用户体验。图 1 将此与没有优化时的默认页面加载体验并排显示,与右侧实施了基于机器学习的预测预取的显著改进的页面加载时间进行比较。这两个示例都运行在模拟的慢速 3G 网络上。

Comparison of un-optimized and machine learning based page loading time in a sample web application
图:样本 Web 应用程序中未优化和基于机器学习的页面加载时间的比较

我们解决方案的高级示意图如下所示

Solution overview
图:解决方案概述

我们使用 Google Cloud 服务(BigQuery 和 Dataflow)存储和预处理网站的 Google Analytics 数据,然后使用 TensorFlow Extended (TFX) 训练自定义模型以运行我们的模型训练管道,生成特定于网站的模型,然后将其转换为可部署在 Web 上的 TensorFlow.js 格式。此客户端模型将在用于电子商店的样本 Angular Web 应用程序中加载,以演示如何在 Web 应用程序中部署模型。让我们更详细地看一下这些组件。

数据准备和摄取

Google Analytics 将每次页面访问存储为事件,提供页面名称、访问时间和加载时间等关键方面。此数据包含我们训练模型所需的一切。我们需要

  1. 将此数据转换为包含特征和标签的训练示例
  2. 使其可供 TFX 用于训练。

我们通过利用现有的支持将 Google Analytics 数据导出到名为 BigQuery 的大规模云数据存储库来完成第一步。我们通过创建一个 Apache Beam 管道 来完成第二步,该管道

  1. 从 BigQuery 读取数据
  2. 对会话中的事件进行排序和过滤
  3. 遍历每个会话,创建示例,将当前事件的属性作为特征,并将下一个事件中的页面访问作为标签
  4. 将这些生成的示例存储在 Google Cloud Storage 中,以便 TFX 可以使用它们进行训练。

我们在 Dataflow 中运行我们的 Beam 管道。

在下表中,每行代表一个训练示例

cur_page

session_index

label

page2

0

page3

page3

8

page1

虽然我们的训练示例只包含两个训练特征 (cur_page 和 session_index),但可以轻松添加来自 Google Analytics 的其他特征以创建更丰富的数据集,并用于训练以创建更强大的模型。为此,请扩展以下代码

def ga_session_to_tensorflow_examples(session):
  examples = []

  for i in range(len(session)-1):
    features = {‘cur_page’: [session[i][‘page’][‘pagePath’]],
                ‘label’: [session[i+1][‘page’][‘pagePath’]],
                ‘session_index’: [i],
                # Add additional features here.
                …
               }
    examples.append(create_tensorflow_example(features))
  return examples

模型训练

Tensorflow Extended (TFX) 是一个端到端的生产规模 ML 平台,用于自动化数据验证、大规模训练(使用加速器)、生成的模型的评估和验证。

要在 TFX 中创建模型,您必须提供预处理函数和运行函数。预处理函数定义在数据传递给主模型之前应执行的操作。这些操作包括涉及对数据进行完整遍历的操作,例如词汇表创建。运行函数定义主模型以及如何对其进行训练。

我们的 示例 演示了如何实现 preprocessing_fn 和 run_fn 以定义和训练模型以预测下一个页面。TFX 示例 管道 演示了如何为许多其他关键用例实现这些函数。

创建可部署在 Web 上的模型

训练完自定义模型后,我们希望在 Web 应用程序中部署此模型,以便它可以在用户访问我们的网站时用于进行实时预测。为此,我们使用 TensorFlow.js,它是 TensorFlow 用于直接在浏览器客户端运行机器学习模型的框架。通过在浏览器客户端运行此代码,我们可以减少与服务器端往返流量相关的延迟,降低服务器端成本,并且还无需将任何会话数据发送到服务器,从而保持用户数据的私密性。

TFX 使用 模型重写库 自动执行在训练后的 TensorFlow 模型和 TensorFlow.js 格式之间转换。作为此库的一部分,我们已实现 TensorFlow.js 重写器。我们只需在 run_fn 中调用此重写器即可执行所需的转换。有关更多详细信息,请参阅 示例

Angular 应用程序

获得模型后,我们可以在 Angular 应用程序中使用它。在每次导航时,我们将查询模型并预取与未来可能访问的页面相关的资源。

另一种解决方案是预取与所有可能的未来导航路径相关的资源,但这将消耗更多的带宽。使用机器学习,我们只可以预测下一个可能使用的页面,并减少误报的数量。

根据应用程序的具体情况,我们可能希望预取不同类型的资产,例如:JavaScript、图像或数据。出于演示目的,我们将预取产品的图像。

一个挑战是如何以高效的方式实现机制,而不会影响应用程序的加载时间或运行时性能。我们可以使用以下技术来减轻性能回归的风险

  • 延迟加载模型和 TensorFlow.js,而不阻塞初始页面加载时间
  • 在主线程之外查询模型,这样我们就不会在主线程中丢帧,并实现 60fps 的渲染体验

满足这两种约束的 Web 平台 API 是 服务工作者。服务工作者是您的浏览器在后台新线程中运行的脚本,与网页分离。它还允许您插入请求循环并提供缓存控制。

当用户在应用程序之间导航时,我们将向服务工作者发布消息,其中包含他们访问的页面。根据导航历史记录,服务工作者将预测未来的导航并预取相关的产品资产。

Example of future navigation

让我们看一下各个活动部件的高级概述。

从 Angular 应用程序的主文件中,我们可以加载服务工作者

// main.ts

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/prefetch.worker.js', { scope: '/' });
}

此代码段将下载 prefetch.worker.js 脚本并在后台运行它。作为下一步,我们希望将导航事件转发给它

// app.component.ts

this.route.params.subscribe((routeParams) => {
  if (this._serviceWorker) {
    this._serviceWorker.postMessage({ page: routeParams.category });
  }
});

在上面的代码段中,我们监视 URL 参数的更改。发生更改时,我们将页面的类别转发到服务工作者。

在服务工作者的实现中,我们需要处理来自主线程的消息,根据它们进行预测,并预取相关信息。从总体上讲,这看起来像这样

// prefetch.worker.js

addEventListener('message', ({ data }) => prefetch(data.page));

const prefetch = async (path) => {
  const predictions = await predict(path);
  const cache = await caches.open(ImageCache);

  predictions.forEach(async ([probability, category]) => {
    const products = (await getProductList(category)).map(getUrl);
    [...new Set(products)].forEach(url => {
      const request = new Request(url, {
        mode: 'no-cors',
      });
      fetch(request).then(response => cache.put(request, response));
    });
  });
};

在服务工作者中,我们监听来自主线程的消息。收到消息后,我们将触发负责进行预测和预取数据的逻辑。

在 prefetch 函数中,我们首先预测用户可能访问的下一个页面。之后,我们遍历所有预测并获取相应的资源,以改善后续导航的用户体验。

有关详细信息,您可以参考 TensorFlow.js 示例存储库 中的示例应用程序。

自己尝试

查看 模型训练代码示例,其中显示了用于训练页面预取模型的 TFX 管道,以及将 Google Analytics 数据转换为训练示例的 Apache Beam 管道,以及 部署示例,展示了如何在样本 Angular 应用程序中部署 TensorFlow.js 模型以进行客户端预测。

致谢

如果没有 Becky Chan、Deepak Aujla、Fei Dong 和 Jason Mayes 的出色努力和支持,这个项目不可能完成。

下一篇文章
Speed-up your sites with web-page prefetching using Machine Learning

作者:Minko Gechev,David Zats,Na Li,Ping Yu,Anusha Ramesh 和 Sandeep Gupta 网页加载时间是网站用户体验最重要的决定因素之一。 研究 表明,更快的页面加载时间直接导致页面浏览量、转化率和客户满意度的提高。零售巨头新蛋(Newegg)在实施网页预取后,转化率提高了 50%……