审计是一种确认我们的渐进式 Web 应用是一个真正的 PWA,符合名称标准的方法。此审计是我们检查工作并确保我们的应用在 PWA 功能方面尽可能好的重要最后一步。
如前所述,进步网络应用的最大拥护者是谷歌。他们的 Chrome 浏览器和 Android 操作系统不仅是所有 PWA 中最友好的,谷歌还花了大量精力教育开发者如何以及为什么构建 PWA。当您(超越本书)进入 PWA 的世界时,您可能会经常查阅他们的文档。
然而,谷歌提供了另一种方式来照亮通往进步网络的道路。为了确保您的网页或应用的质量,他们发布了一套工具,根据一套标准来衡量您的网站。他们使用的主要工具是灯塔。
以下是我们将在本章中介绍的内容:
- 什么是灯塔?
- 它遵循什么标准?
- DevTools 中的审计选项卡是什么?
- 运行我们的第一次审计
- 评估读数
- 使用 Lighthouse CLI
在一句话中,Lighthouse是一个运行您的站点的工具,并根据一组特定的标准告诉您它到底有多进步。
它通过尝试在各种条件下加载页面(包括 3G 网络和脱机)并评估页面的响应方式来实现。它还检查一些 PWA 备用设备,如启动屏幕和服务工作器。
以下标准基本上是 Lighthouse 在查看应用时遵循的检查表。每个“测试”都是一个简单的是/否。如果你通过了所有测试,你会得到 100 分。这就是我们想要的!
以下是截至 2017 年 8 月的标准书面清单:
- 注册服务工作器:服务工作器是一项技术,它使您的应用能够使用许多渐进式 Web 应用功能,例如脱机、添加到主屏幕和推送通知。
- 当你正在构建一个渐进的 Web 应用时,考虑使用一个服务工作器,这样你的应用可以离线工作。
- 在 JavaScript 不可用时包含一些内容:当 JavaScript 被禁用时,您的应用应该显示一些内容,即使这只是警告用户使用应用需要 JavaScript。
- **为自定义启动屏幕配置:**将为您的应用构建默认启动屏幕,但满足这些要求可确保高质量启动屏幕,用户可以从点击主屏幕图标过渡到应用的第一次绘制。
- 使用 HTTPS:所有站点都应该使用 HTTPS 进行保护,即使是不处理敏感数据的站点。HTTPS 防止入侵者篡改或被动监听应用与用户之间的通信,是 HTTP/2 和许多新 web 平台 API 的先决条件。
- 将 HTTP 流量重定向到 HTTPS:如果您已经设置了 HTTPS,请确保将所有 HTTP 流量重定向到 HTTPS。
- 3G 上的页面加载速度足够快:如果互动持续时间的时间短于 PWA 基线检查表(来源--定义的 10 秒,则满足该标准 https://developers.google.com/web/progressive-web-apps/checklist )。需要网络节流(具体来说,RTT 延迟>=150 RTT 是预期的)。
- **可以提示用户安装 Web 应用:**当用户可以手动将您的网站添加到其主屏幕时,如果满足各种要求且用户与您的网站有适度接触,则该提示(也称为应用安装横幅)将主动提示用户安装应用。
- **地址栏与品牌颜色匹配:**浏览器地址栏可以设置主题以匹配您的网站。当用户浏览站点时,
theme-color
元标记将升级地址栏,并且一旦添加到主屏幕,清单主题颜色将在站点范围内应用相同的主题。 - **有一个标签,带有宽度或初始比例:**添加一个
viewport
meta 标签以优化移动屏幕应用。 - **内容大小是否适合视口:**如果应用内容的宽度与视口的宽度不匹配,则应用可能无法针对移动屏幕进行优化。
在 Chrome60 发布之前,Lighthouse 仅在测试版中作为 Chrome 扩展或命令行工具提供。然而,现在它在 Chrome 开发工具中有了自己的位置,在新的审计选项卡中。
在“审计”选项卡中,除了 Lighthouse PWA 审计之外,还包括一系列其他基准测试,包括性能和 web 最佳实践。我们将重点关注 PWA 测试和性能测试,但也可以随意运行其他测试。
“审计”选项卡的另一个有用功能是保存以前的审计,以便在改进应用时获得应用的某种历史记录。
好了,说够了。让我们继续进行第一次审计!
打开 DevTools,导航到 Audits 选项卡,然后单击 RunAudit。
drumroll,这应该需要几秒钟的时间,然后给你一个很好的网站外观总结。我们的渐进式 Web 应用有多好
一点也不坏。事实上,它没有比 PWA 类别中的更好。拍拍自己的背,也许为出色完成的工作击掌。让我们评估读数,然后决定是继续前进,还是在所有类别中实现 100%的目标。
请注意,由于灯塔正在积极开发中,由于新的标准,您的分数可能与上述不符。在这种情况下,我鼓励你们看看灯塔在抱怨什么,看看你们是否能解决它,达到 100 分。
如果您的结果与前面的不匹配,则有两种可能性:
- Chrome 添加了一个我们的应用无法完成的新测试。正如我们多次提到的,PWA 是一种不断发展的技术,因此这当然是可能的。
- 你在书中遗漏了一些步骤;发生在我们最好的人身上。
无论哪种情况,我都鼓励您调查并尝试解决根本问题。谷歌为每个测试标准提供文档,这是一个很好的起点。
在我们的例子中,我们唯一没有通过的测试就是性能。让我们看看我们没有这样做的原因:
正如我们在这里看到的,我们的第一个有意义的绘画大约需要三秒钟。请注意,我们的应用外壳并不被认为是有意义的绘画,尽管它确实提高了页面的感知性能。Chrome 足够聪明,知道直到我们的login
表单或chat
容器出现,屏幕上才有真正有意义的内容——用户可以实际使用的内容。
不过,显示有意义的内容需要三秒钟以上,原因是我们需要等待 JavaScript 加载、启动,然后加载用户当前是否登录,然后加载聊天消息或重定向到登录。这是很多后续步骤。
这是一个可以解决的问题吗?可能我们可以在 React 加载之前找出用户是否登录的方法(换句话说,将一些 JavaScript 移出我们的主应用)。我们可以将chat
容器和login
表单移出 React,以确保它们可以在库加载之前呈现,然后在 React 初始化后找到一些替换它们的方法(挑战是在不删除用户开始键入的任何内容的情况下替换输入)。
所有提到的挑战都属于优化关键渲染路径的范畴。对于任何想深入研究性能优化的人,我鼓励您尝试一下。然而,从业务的角度来看,这是一个大量(可能有缺陷的)优化,但收获甚微。根据之前的基准测试,我们的用户已经在大约 400 毫秒内接收到内容,而完整的应用只需三秒多。请记住,由于缓存,大多数用户在随后的访问中将获得更快的加载时间。
事实上,我们较低的性能分数证明了使用诸如 React 之类的重要 JavaScript 库构建高性能应用的成本效益。对于那些对更轻量级的替代方案感兴趣的人,请查看下一章中关于 Preact 的部分,这是前面问题的可能解决方案。
从“审计”选项卡运行测试既方便又好,但是在我们将应用推到现场之前,我们如何确保应用的质量得到保持呢?
答案是将 Lighthouse 纳入我们的部署过程,并使用它自动评估我们的构建。这类似于当我们点击yarn deploy
时运行测试套件。幸运的是,谷歌提供的 Lighthouse CLI 正是为了实现这一目的。
让我们使用以下内容安装它:
yarn add --dev lighthouse
在这里,我们的目标是在运行yarn deploy
时在应用上运行 Lighthouse。为此,我们必须制作一个自定义部署脚本。
如果您打开我们的package.json
,您将在scripts
下看到以下内容:
"scripts": {
"build": "node_modules/.bin/webpack --config webpack.config.prod.js",
"start": "node_modules/.bin/webpack-dev-server",
"deploy": "npm run build && firebase deploy"
},
让我们将其更改为以下内容:
"scripts": {
"build": "node_modules/.bin/webpack --config webpack.config.prod.js",
"start": "node_modules/.bin/webpack-dev-server",
"deploy": "npm run build && node scripts/assess.js && firebase deploy"
},
我们将使用 node 来运行用 JavaScript 编写的自定义构建脚本。在您的根目录中创建scripts/ folder
以及assess.js
文件。
我们的程序如下:
- 本地提供我们的
build
文件夹,使其在浏览器中运行。 - 使用灯塔评估服务页面。
- 控制台记录结果。
让我们添加为build
文件夹提供服务所需的软件包:
yarn add --dev serve
请注意,我们将此和lighthouse
保存为dev
依赖项,因为我们永远不会在生产中使用它们。
在我们新的scripts/assess.js
中,需要serve
包:
const serve = require('serve');
我们要做的就是port:5000
上的serve
我们新编译的build
文件夹,看起来像这样:
const server = serve('./build', {
port: 5000
});
我们可以通过运行server.stop()
随时停止服务器。一旦我们的分数显示出来,我们就会这样做。
现在,让我们在assess.js
顶部再需要两个工具:
const lighthouse = require('lighthouse');
const chromeLauncher = require('lighthouse/chrome-launcher');
chromeLauncher
将允许我们打开 Chrome 到目标页面,然后运行 Lighthouse。让我们创建一个名为launchChromeAndRunLighthouse
的函数来实现这一点:
function launchChromeAndRunLighthouse(url, flags= {}, config = null) {
}
我们可以选择性地传递一些标志和配置,我们在这里不使用这些标志和配置(标志可用于在进程展开时打开日志记录)。
在函数内部,我们将启动 Chrome,设置 Lighthouse 运行的端口,然后运行它。最后,我们将停止 Chrome:
function launchChromeAndRunLighthouse(url, flags = {}, config = null) {
return chromeLauncher.launch().then(chrome => {
flags.port = chrome.port;
return lighthouse(url, flags, config).then(results =>
chrome.kill().then(() => results));
});
}
顺便说一下,此函数直接取自 Lighthouse CLI 文档。
好的,现在是最后一步。我们将使用所选 URL 运行函数(将其放在文件底部,serve
命令下方):
launchChromeAndRunLighthouse('http://localhost:5000', {}).then(results => {
server.stop();
});
一旦得到结果,我们就停止服务器,但我们需要正确显示结果。
results 变量作为对象输入。它给出了每个类别的详细分类和分数,但我们只关心麻烦的领域。在函数调用上方,让我们添加一个分数截止点:
const CUTOFF = 90
launchChromeAndRunLighthouse('http://localhost:5000', {}).then(results => {
我们将用它来表示“只显示得分低于 90/100 的结果。”
注销结果的过程并不太令人兴奋,因此我们不会在这里深入讨论。以下是完整的文件:
const serve = require('serve');
const lighthouse = require('lighthouse');
const chromeLauncher = require('lighthouse/chrome-launcher');
function launchChromeAndRunLighthouse(url, flags = {}, config = null) {
return chromeLauncher.launch().then(chrome => {
flags.port = chrome.port;
return lighthouse(url, flags, config).then(results =>
chrome.kill().then(() => results));
});
}
const server = serve('./build', {
port: 5000
})
const CUTOFF = 90
launchChromeAndRunLighthouse('http://localhost:5000', {}).then(results => {
score = results.score
const catResults = results.reportCategories.map(cat => {
if (cat.score < CUTOFF) {
cat.audits.forEach(audit => {
if (audit.score < CUTOFF) {
const result = audit.result
if (result.score) {
console.warn(result.description + ': ' + result.score)
} else {
console.warn(result.description)
}
if (results.displayValue) {
console.log('Value: ' + result.displayValue)
}
console.log(result.helpText)
console.log(' ')
}
})
}
return cat
})
catResults.forEach(cat => {
console.log(cat.name, cat.score)
})
server.stop()
});
如果您从终端运行node scripts/assess.js
,您应该会看到问题区域列表以及每个类别的最终分数。通过运行yarn deploy
将所有内容整合在一起,您将看到这些分数出现在 Firebase 部署之前。
现在,我们有了一种简单而干净的方法,可以随着应用的发展随时了解其最新状态,而无需亲自启动站点进行测试。
完成!我们对我们的申请进行了全面审计,并以优异的成绩通过了所有类别的申请。我们有一个正在运行的渐进式 Web 应用。在本章中,我们了解了灯塔是什么,以及为什么验证我们的 PWA 很重要。我们还将其作为部署过程的一部分添加,以确保我们的应用继续符合质量标准。我们现在可以考虑我们的应用在各个方面都是完整的。
接下来,我们将讨论后续步骤以及增加 PWAs 知识的有用资源,但首先,将我们的应用提交给您的朋友和 Chatastrophe board。