来自 奥门威尼斯网址 2019-10-19 00:33 的文章
当前位置: 威尼斯国际官方网站 > 奥门威尼斯网址 > 正文

奥门威尼斯网址:叁回浏览器质量提高

JavaScript 的代价

2018/08/31 · JavaScript · Javascript

原文出处: Addy Osmani   译文出处:开源中国   

奥门威尼斯网址 1

建立交互式网站包括向用户发送 JavaScript 。通常,太多了。你是否经历过在一个手机页面上,它看起来已经加载好了,但是点击一个链接或者试图滚动页面的时候,什么也没发生?

一字节又一字节,JavaScript 仍然是我们发送给手机的代价最大的资源,因为它会很大程度上延迟交互。

奥门威尼斯网址 2

由 WebPageTest(src) 评测的 CNN.com 的 JavaScript 处理时间。高端手机(iPhone8)在约4s的时间处理脚本。相比较而言,普通手机(Moto G4)是约13s的时间,以及2018年低端手机(Alcatel 1X)是约36s。

现在我们讨论一些策略,可以让你高效地传送 JavaScript ,同时给用户提供一个有价值的体验。

奥门威尼斯网址 3

概括:

  • 要保持快速,则只加载当前页面必要的 JavaScript 。优先考虑用户需要的内容,然后使用代码拆分延迟加载剩下来的内容。这是快速加载和交互的最好的机会。默认情况下,基于路由的代码拆分堆栈是一个转折。
  • 接受性能预算,学会在预算中生活。对于手机来说,JS的预算目标为简化/压缩后小于170KB。未压缩时代码约为0.7MB。预算对成功至关重要,然而,他们单独不能神奇地修正 perf 数值。团队文化,结构和强制措施。没有预算的项目建立会导致性能退化并导致失败。
  • 学习如何审计并裁剪 JavaScript 捆绑库。当你只需要一小部分却搭载了整个库,浏览器不需要的填充字符,或者重复代码,这些很容易发生。
  • 每个交互都是一个新的“交互时间”的开始;考虑在这种情况下进行优化。传送数据的大小对低端手机网络至关重要,而且 JavaScript 解析时间受设备 CPU 限制。
  • 如果客户端 JavaScript 对用户体验没有好处,问问自己是否真的有必要。也许服务端渲染 HTML 会更快一些。考虑将客户端框架限制到绝对需要它们页面上的使用。如果做的不好,服务器渲染和客户端渲染都会是灾难。

(本文基于我最近的“JavaScript 的代价”的演讲:)

作者丨exAspArk

网站因用户“体验”而膨胀

当用户访问网站,你可能正在下载大量文件,其中很多都是脚本。从给一个web浏览器的角度来看有点像这个:

奥门威尼斯网址 4

扔给你一大堆文件

虽然我很喜欢JavaScript,但它总是网站中消耗最大的东西。我想解释一下为什么这是一个主要问题。

奥门威尼斯网址 5

现在中等的web页面搭载了大概350KB的简化或压缩后的JavaScript脚本。浏览器需要处理的未压缩的脚本膨胀到了超过1MB。

注:不确定你的JavaScript包是否延迟了用户与网站交互速度?查看Lighthouse

奥门威尼斯网址 6

2018年7月的HTTP压缩状态的JavaScript报告中的统计突出显示了中等web页面搭载了约350KB的简化或压缩后的脚本。这些页面要花15s才能交互。

在移动设备上,搭载这么多的JavaScript脚本从经验来看要花费超过14+秒才能加载并交互。

其中的一个很大的因素是在移动网络中下载代码,然后再移动设备CPU上处理它,这个过程所花费的时间。

我们来看移动网络。

奥门威尼斯网址 7

在某一指标上表现较好的国家,颜色较深。不包括在内的国家是灰色的。还有值得注意的是,即使在美国,农村的宽带速度要比城市慢20%。

这个来自OpenSignal的图表展示了全球4G网络的稳定性,以及每个国家的用户体验到的平均连接速度。正如我们看到的,很多国家的连接速度仍比我们想象中要慢。

不仅中型网站的350KB的脚本要花上一段时间才能下载,事实上,如果我们浏览热门网站,实际上会加载比这更多的脚本:

奥门威尼斯网址 8

Facebook.com和其他网址相关数据”中的未压缩的JS包大小数据。像谷歌表格这样的网站被突出显示为最多加载5.8MB的脚本(在解压缩后)。

我们在桌面和移动web上都遇到了这个瓶颈,这些网站有时会加载几兆字节的代码,然后浏览器需要处理这些代码。问题是,你能负担得起这么多JavaScript脚本吗

译者丨姚佳灵

JavaScript 有代价

奥门威尼斯网址 9

“含有这么多脚本的网站根本不能送达全球的诸多用户;统计表示,用户不会(以后也不会)等待它们加载” — Alex Russell

注:如果你使用了大量的脚本,应该考虑使用 code-splitting 对其进行分解,或者使用 tree-shaking 技术减少 JavaScript 的加载量。**

现代网站通常会通过 JS 包发送下面这些东西:

  • 客户端框架或 UI 库
  • 状态管理(比如 Redux)
  • Polyfills(一般现代浏览器不需要他们)
  • 完整的库或仅用到的部分(比如 lodash 完整库、Moment + 其本地库)
  • 一套 UI 组件(按钮、顶部、侧边栏等)

累积起来的代码越来越多,页面加载的时候也就越来越长。

加载网页就像电影胶片一样,有三个关键时刻。

即:是否发生?是否有用?是否可用?

奥门威尼斯网址 10

加载是一个过程。我们正逐渐开始关心用户的良好体验。我们不再盯着 onload 和 domContentLoaded,而是会问“用户什么时候才能正常使用页面?”如果用户点击用户界面中L的o某个地方,是否有所反馈?

是否正在发生是指屏幕上开始显示某些内容。(导航开始了吗?服务器在响应吗?)

是否有用 指文本或内容显现之后,用户是否通过体验或参与感受到价值。

还有是否可用是指用户可以根据经验开始交互并发生一些事情。

我之前也提到过这个术语:“交互”,它到底是什么意思呢?

奥门威尼斯网址 11

交互时间的可视化强调,不好的体验会让用户认为他们能达到某个目标,但实际上页面还没有加载完要达到这个目标所需要的代码。感谢 Kevin Schaaf 的关于交互的动画

对于要交互的页面,它必须能够快速响应用户输入。较小的 JavaScript 可以保证快速响应。

无论用户点击链接还是滚动页面,他们都需要看到有反馈他们动画的事情发生。如果做不到这样的体验,用户就会感沮丧。

奥门威尼斯网址 12

灯塔有一系列以用户为中心的性能指标,比如在实验设置中的交互时间。

通常发生的地方是当服务端在渲染的过程中,下载一堆“溶入”界面的 JavaScript(添加事件处理函数和其它行为)。

浏览器可能会在处理用户输入的线程上运行许多可能需要处理的事件。这个线程称为主线程。

在主线程上加载太多 JavaScript(通过 <script> 等)会是个问题。把脚本加载到  Web Worker 或者由 [Service Worker]() 处理脚本会减轻这些与交互时间相关的负责影响。

(这里有一个用户点击 UI 的例子。通常,用户勾选复选框,或者点击链接,一切都很美好。但如果我,们模拟阻塞主线程,就什么事都不会发生了。用户无法勾选复选框,也不能点击连接,因为主H线程被阻塞了:)

应该尽可能地避免阻塞主线程。了解更多内容,请看 “为什么 Web 开发者需要关心交互性

我们看到我们合作的团队遭受JavaScript影响了许多类型网站的交互性。

奥门威尼斯网址 13

JavaScript可以延迟可见元素的交互性。可视化是Google搜索中的一些UI元素

太多(主线程)JavaScript可以延迟可见元素的交互性。这对许多公司来说都是一个挑战。

以上是Google搜索中的一些示例,您可以在这些示例中开始使用UI,但如果某个网站运行过多的JavaScript,则可能会在实际发生某些事情之前出现延迟。这会让用户感到有点沮丧。理想情况下,我们希望所有体验尽快互动。

奥门威尼斯网址 14

通过WebPageTest和Lighthouse衡量news.google.com的互动时间(来源)

通过衡量Google新闻在移动设备上的交互时间,我们观察到大约7s的高端交互与低端设备在55秒内实现交互的巨大差异。那么,什么是交互性的良好目标?

奥门威尼斯网址 15

谈到Time to Interactive,我们认为您的基准应该是在中等移动设备上的慢速3G连接上以五秒钟的速度进行交互。“但是,我的用户都在使用快速网络和高端手机!”……是吗?你可能会使用“快速”的咖啡店WiFi,但实际上只能获得2G或3G的速度。多变性问题

谁传输更少的 JavaScript 以减少响应时间?

奥门威尼斯网址 16

  • Pinterest 将 JavaScript 包从 2.5MB 减小到 < 200KB,响应时间从 23 秒减少到 5.6 秒。收益提升了 44%,注册人数上升了 753%,移动网站的是周活跃人数提升了 103%。
  • AutoTrader 将他们的 JavaScript 包大小减小了 56%,响应时间减少了约 50%。
  • Nikkei 将 JavaScript 包大小减小了 43%,响应时间提升了 14 秒。

我们来设计一个更具弹性的 Web,它不依赖于加载巨大的 JavaScript。

交互性会影响很多东西。它可能会影响网站的移动数据规划,或者咖啡厅的 WiFi,或者他们I只是伴随着时断时续的连接。

奥门威尼斯网址 17

这些事情发生的时候,你有一大堆的 JavaScript 需要运行,用户可以放弃等待网站的渲染。另外,如果有东西在渲染,也需要等待大量的时间才可以交互。理想情况下,较少的 JavaScript 可以减轻这些问题。

最近,我们把 Universe.com 的主页性能提高了 10 几倍。让我们一起来探索一下我们是如何实现这个结果的,涉及到了哪些技术。

为什么 JavaScript 如此昂贵?

为了解释 JavaScript 会有如此之大的代价,我想告诉你在内容发送到浏览器之后发生了些什么。当用户在浏览器的地址栏输入 URL:

奥门威尼斯网址 18

请求会被发送到服务器,然后服务器会返回一些标记。接着,浏览器解析这些标记,并找到必不的可少的 CSS、JavaScript 和图片。然后,浏览器还得获取并处理所有这些资源。

上面的动画准确描述了 Chrome 在处理你发送的所有内容时要干的事情(确实,它是一个巨大的表情工厂)。

这里存在一个挑战:JavaScript 最终会成为瓶颈。设想,我们希望能快速画出每一个像素,然后让页面可以交互。但是,如果 JavaScript 成为瓶颈,你最终只能看到东西却不能交互。

我们希望防止 JavaScript 为成现代体验的瓶颈。

要记住一点,作为一个流程,如果我们想要 JavaScript 变得更快,我们就必须快速地下载、解析、编译并执行它。

奥门威尼斯网址 19

也就是说,我们必须保证快速的网络传输,以及处理关于脚本其它方面的事情。

如果你花很长的时间在 JavaScript 引擎中解析和编译脚本,就是延迟用户与你的体验交互的时间。

为了提供这方面的数据,这里有一个 V8(Chrome 的 JavaScript 引擎)在处理页面中脚本的时间分解数据:

奥门威尼斯网址 20

JavaScript 解析/编译 = 在页面加载时 10–30% 时间消耗在 V8 (Chrome 的 JS 引擎) 上

橙色代表了当下流行的网站消耗在解析 JavaScript 上的全部时间。黄色部分则是编译所消耗的时间。它们总计占用了处理页面上 JavaScript 30% 的时间 —— 这是真实的成本。

对于 Chrome66 来说,V8 在后台线程中编译代码,将编译时间减少了 20%。但是解析和编译的代价仍然很高,而且想要看到一个大型脚本执行时间少于 50ms,实属罕见,哪怕不在主线程编译。

另一个要知道的是 JavaScript 的所有字节都不等价。200KB 的脚本和 200KB 的图片所需要的代价差异很大。

奥门威尼斯网址 21

并非所有字节都是等价的。除开原始的网络传输成本,200KB 的脚本和 200KB 的 JPG 所需要的代价大相径庭。

他们的下载时间可能一样,但处理起来却需要不同的成本。

JPEG 图像需要解码、光栅化,然后绘制在屏幕上。JavaScript 需要下载,然后解析、编译、执行—— 还有大量需要引擎完成的其它步骤。请注意,他们的成本并不相同。

成本变得重要的原因之一是因为移动端。

一开始,我们先来看看,为什么网站性能如此重要(在本文末尾附有本案例研究的链接):

移动端是一个谱系。

奥门威尼斯网址 22

移动端是一个包含了便宜/低端、中端和高端设备的谱系

如果运气好,我们可能会遇到一个中高端的手机。但实事上并非所有用户都有这么好的设备。

用户使用的可能是中低端的手机,而且各类设备之间也存在极大的差异;热节流、缓存大小差异、CPU、GPU —— 最终,处理资源的时间会像处理 JavaScript 一样存在较大的差异,这些都取决于所使用的设备。使用低端手机的用户甚至可能就在美国。

奥门威尼斯网址 23

newzoo 发表了“对 23 亿 Android 智能手机的观察分析”。Android 在全球占有 75.9% 的市场A份额。预计 2018 年至少还有 3 亿的智能手机进入市场。其中有大量的 Android 设备。

下面是 2018 年各种硬件设备下对 JavaScript 解析时间的分析:

奥门威尼斯网址 24

处理 (解析/编译) 1MB 未压缩的 JavaScript (压缩和 gZip 处理后 < 200KB)所需要的时间,这些时间是在真实设备上手工测得。(来源)

最上面是像 iPhone8 这样的高端设备,处理 JavaScript 相对较快。下面是一些普通手机,比如 Moto G4 和低于 100 美元的 Alcatel 1X。注意到处理时间的差异了吗?

随着时间的推移,Android 手机越来越便宜,而不是更快。这些设置的 CPU 频率更高,L2/L3 缓存也小得可怜。如果你期待用户都使用高端设备,那么你的目标用户就会减少。

我们从一个真实的网站来实际看看这个问题。下面是 CNN.com 的 JS 处理时间:

奥门威尼斯网址 25

CNN.com 上的 JavaScript 处理时间,来自 WebPageTest (来源)

iPhone 8 (使用 A11 芯片) 在处理 CNN 的 JavaScript 比说通手机快 9 秒。这 9 秒可以让增强用户体验。慢得甚至需要特别说明:

奥门威尼斯网址 26

对于 CNN.com,这个大量使用 JavaScript 的网站,比较中低端硬件通过 3G 访问加载的情况(来源)。Alcatel 1X 花了 65秒 才完成加载。

这暗示我们应该停止使用快速的网络和快速的设备。

奥门威尼斯网址 27

有一些用户不会使用快速的网络,或者没有最新最好的手机,所以我们有必要从实际的手机和实际的网络环境开始测试。易变性确实是个问题。

“可变性是杀死用户体验的原因” –  Ilya Grigorik。快速设备实际上有时可能很慢。快速网络可能很慢,可变性最终会使一切变得缓慢。

当差异可能会破坏用户体验时,使用缓慢的基线进行开发可确保每个人(快速和慢速设置)都能获益。如果您的团队可以查看他们的分析并准确了解您的用户实际访问您网站的设备,那么您将会提示您应该在办公室中使用哪些设备来测试您的网站。

奥门威尼斯网址 28

    测试真实的手机&网络。

webpagetest.org/easy在“移动”配置文件下预先配置了许多Moto G4。如果您无法购买自己的中等级硬件进行测试,这将非常有用。

这里设置了许多配置文件,您可以使用这些配置文件已预先配置了常用设备。例如,我们有一些中等移动设备,如Moto G4准备测试。

在代表性网络上进行测试也很重要。虽然我已经谈到了低端手机和中位手机的重要性,但布莱恩霍尔特提出了这个观点:了解你的观众非常重要。

奥门威尼斯网址 29

“了解您的受众,然后适当地关注应用程序的性能至关重要” –  Brian Holt(src)

并非每个站点都需要在低端手机上的2G上表现良好。也就是说,在整个频谱范围内实现高水平的性能并不是一件坏事。

奥门威尼斯网址 30

谷歌分析>观众>移动设备>设备 可视化设备&操作系统访问您网站的位置。

您可能在频谱的较高端或频谱的不同部分拥有广泛的用户。请注意您网站背后的数据,以便您可以合理地调用所有这些内容。

如果您希望JavaScript快速,请注意低端网络的下载时间。您可以进行的改进包括:减少代码,缩小源代码,利用压缩(即gzip,Brotli和Zopfli)。

奥门威尼斯网址 31

利用缓存重复访问。对于CPU速度慢的手机,解析时间至关重要。

奥门威尼斯网址 32

如果您是后端或全堆栈开发人员,您知道您可以获得有关CPU,磁盘和网络的费用。

当我们构建越来越依赖JavaScript的网站时,我们有时会以我们并不总是容易看到的方式支付我们发送的内容。

用户体验:糟糕的性能导致无响应,从 UI 和 UX 角度来看,这可能会让用户感到沮丧。

怎样才可以发送更小的 JavaScript

无论如何,只要我们能让发送出去的 JavaScript 最小,同还还能让用户有较好的体验,那么成功就在眼前。Code-splitting 就是一个能实现这一愿望的选择。

奥门威尼斯网址 33

基于页面、路由或组件拆分巨大而完整的 JavaScript 包。如果“splitting”一开始就用在你的工具链中,你离成功就更近一步。

Code-splitting 的思想是这样的:不是向用户发送一个巨大的单个 JavaScript 文件 —— 就像一个巨大的披萨一样 —— 如果每次只给他们一块怎么样?只要有足够多片(但不是全部 —— 译者注)就能让当前页面跑起来。

Code-splitting 可以工作在页面、路由或组件级别。这对于很多现代的库和框架来说是件好事,这些库或框架可能通过 webpack 和 Parcel 生成脚本包。按照指南,可以将其用于 React、 Vue.js 和 Angular。

奥门威尼斯网址 34

在 React 应用中通过 React Loadable  添加 code-splitting。React Loadable 是一个高阶组件,它可以将动态导入封装在对 React  友好的 API 中,将 code-splitting 应用于给定的组件。

最近,很多大型团队看到了胜利背后的 code-splitting。

奥门威尼斯网址 35

基于希望用户能快速进入交互的需求,Twitter 和 Tinder 积极采用代码分割方法来重写他们的移动 Web 体验,其交互性能提高了 50%。

像 Gatsby.js (React)、Preact CLI 和 PWA Starter Kit,通过尝试,在普通的移动硬件上达到了快速加载以及快速入进交互的效果。

这些网站还做了一件事情,就是采用审查,使其成为工作流程的一部分。

奥门威尼斯网址 36

定期审查 JavaScript 包。像 webpack-bundle-analyzer 这样的工具非常适合用来分析构建出来的 JavaScript 包,以及可视代码的导入成本,这对于将本地化迭代工作流程错综复杂的依赖关系可视化非常有效。(比如,使用 npm install 导入包时)

值庆幸的是,JavaScript 生态系统中有大量优秀的工具可用于包分析。

像工具 Webpack Bundle AnalyzerSource Map Explorer 和 Bundle Buddy 允许你审核你的包用以减少包的数量。

这些工具可视化了JavaScript包的内容:它们突出显示您可能不需要的大型库,重复代码和依赖项等。

奥门威尼斯网址 37

来自Benedikt Rötsch的 “放下你的Webpack包,节制使用”  

打包审计通常会突出显示重要的依赖项(如Moment.js及其语言环境)的机会,以获得更轻的替代方案(例如 date-fns)。

如果你使用 webpack, 您可能会发现我们打的包中通用库问题在打包中很有用。

转化率和收入:通常,响应缓慢的网站会导致客户流失,并对转化率和收入产生不好的影响。

衡量,调优,监控,然后重复。

如果你不确定你对JavaScript性能方面是否有什么问题,请查看Lighthouse:

奥门威尼斯网址 38

你可能没有注意到,Lighthouse最近添加了大量有用的新的性能审计功能。

Lighthouse是一个嵌入到Chrome开发工具的工具。它也可以作为Chrome扩展使用。它给你一个深入的性能分析来凸显提高性能的机会。、

奥门威尼斯网址 39

我们最近已经在Lighthouse添加了对高“JavaScript启动时间”标记的支持。这个审计工具突出显示那些可能花大量时间来解析/编译的脚本,这些脚本延迟了交互。你可以将这个审计工具看做一个机会,不是拆分脚本,就是在这里做更少的工作。

你还可以做的另外一件事就是确定你不会为你的用户加载无用代码:

奥门威尼斯网址 40

使用Chrome开发工具中的覆盖率标记来找到无用的CSS和JS代码。

代码覆盖率是开发工具中的一个特性,它可以让你发现页面中的无用JavaScript(以及CSS)。在开发工具中加载页面后,覆盖标记会显示执行了多少代码vs.加载了多少代码。你可以通过只加载一个用户需要的代码来提高页面性能。

奥门威尼斯网址 41

注:通过覆盖率记录,你可以与应用交互,然后开发工具会刷新用到了哪些包。

对于找机会来拆分脚本以及在需要的时候延迟加载非必要代码,这是有价值的。

如果你正在寻找有效地为用户提供JavaScript的模式,请查看PRPL模式。

奥门威尼斯网址 42

PRPL是高效加载的性能模式。它代表着:将关键资源推送(Push)到初始路由上,渲染(Render)初始路由,预缓存(Pre-cache)其他路由,延迟加载(Lazy-load)并按需创建剩余路由

PRPL (Push, Render, Precache and Lazy-Load) 是一种模式,用于为每条路径快速划分代码,然后利用服务[工作者](

这意味着当用户导航到体验中的其他视图时,它很可能已经存在于浏览器缓存中,因此他们在启动脚本和获取交互方面的开销降低了很多。

如果你关心性能,或者你曾经为你的网站做过性能补丁,那么你知道有时你可能最终会遇到这样一类问题修正,几周之后回来才发现团队中的某个人正在处理的功能和无意中破坏了这类体验。它有点像这样:

奥门威尼斯网址 43

值得庆幸的是,我们可以尝试解决这个问题,一种方法是制定性能预算

奥门威尼斯网址 44

性能预算至关重要,因为他让每个人都在页面上。他们创造了分享热情的文化,不断改善用户体验和团队责任感。

预算通过定义可计算的约束来允许团队达到他们的性能目标。正因为你不得不生活在预算的约束之中,所以每一个步骤都需要考虑到性能,而不能事后再考虑。

基于Tim Kadlec的工作,性能预算的指标可包括:

  • 里程碑时间 — 基于加载页面的用户体验的计时(例如 Time-to-Interactive)。在页面加载时,您通常需要匹配多个里程碑时间来准确的呈现完整的故事。
  • 基于质量的测量— 基于初始值(例如 JavaScript的weight,HTTP请求的number)。这些都专注于浏览器体验。
  • 基于规则的测量— 由例如Lighthouse或者WebPageRest这样的工具生成分数。通常情况下,单个数字或者一些列的数据来评价您的网站。

奥门威尼斯网址 45

Alex Russell发表了一片关于预算性能的tweet-storm文章,其中有几点值得关注:

  • “领导的支持很重要. 为了保持整体用户体验的良好性,领导愿意将特征工作保持在对技术产品的深思熟虑的管理中。”
  • “性能是有关工具支持的文化。浏览器尽可能的优化了HTML+CSS。将您的工作更多的投入到JS中会为您的团队和所用的工具带来负担。”
  • “预算不会让你伤心。他们的存在使得组织能够自我纠正。团队需要预算来约束决策空间并帮助打击他们。”

影响网站用户体验每个人都与网站的性能有关。

奥门威尼斯网址 46

将性能作为讨论的一部分。

SEO:从 2019 年 7 月 1 日开始,谷歌将对所有新网站默认启用移动优先索引。如果网站在移动设备上的响应缓慢,并且没有适合移动设备的内容,那么它们的排名会降低。

性能更多是一种文化挑战,而不是技术挑战。

在规划会议和其它集会时讨论性能。询问商业项目关系人他们期望的性能是什么。他们是否明白性能是如何影响他们所关心的业务指标的?问开发团队他们如何规划定位性能瓶颈。当得不到满意答复的时候,他们开始讨论。

奥门威尼斯网址 47

“通过展示性能是如何影响项目关系人所关心的性能指标,来使性能与他们的目标相关联。若没有性能文化,性能将无法保证。”——Allison McKnight
性能行动规划如下:
创建性能视图。这是商业项目关系人和开发者达成共识的“良好性能”的协议。
设置性能预算。从视图中挑出关键性能指标(KPIs),并从中设置合理的,可计量的目标。例如:“5秒内加载并获取交互”。大小预算可能会从而消失。例如“将JS限制在简化/压缩后170KB的大小”。
建立关于KPIs的定期报告。这可以是一份定期发送给业务部门的报告,强调进展和成就。

Andy Still的《网络性能勇士》(Web Performance Warrior)和Lara Hogan的《为性能而设计》(design for Performance)都是很好的书,讨论了如何思考建立性能文化。

性能预算的工具怎样?你可以用Lighthouse CI项目持续集成设置Lighthouse评分预算:

奥门威尼斯网址 48

如果您的性能分数低于Lighthouse CI的规定值,可以拒绝那些合并的拉取请求。Lighthouse阈值是另一种基于配置的方法来设置性能预算。

许多性能监控服务支持设置性能预算和预算报警,包括Calibre、Treo、Webdash和SpeedCurve:

奥门威尼斯网址 49

我网站teejungle.net的JavaScript性能预算使用SpeedCurve,它支持一些列的预算指标。

接受性能预算可以鼓励团队来认真思考他们从设计阶段的早期到里程碑结束的任何决策的后果。

寻找进一步参考?美国数字服务部门通过为时间到交互等指标设定目标和预算,用Lighthouse记录他们跟踪性能的方法。

下一步..

每个站点都应该可以访问实验室和现场性能数据。

要跟踪JavaScript可能对RUM(真实用户监控)设置中的用户体验产生的影响,网络上有两件事情我建议您检查一下。

奥门威尼斯网址 50

现场数据(或RUM  – 真实用户监控)是从用户在野外经历的实际页面加载中收集的性能数据。拥有大量JavaScript负载的站点将受益于通过长任务和第一输入延迟测量此工作的主线程。

第一个是长任务 – 一个API,使您能够收集任务(及其属性脚本)的真实世界遥测,持续时间超过50毫秒,可能会阻止主线程。您可以记录这些任务并将其记录回分析。

第一输入延迟(FID)是衡量用户首次与您的站点交互时(即,当他们点击按钮时)到浏览器实际能够响应该交互的时间的度量。FID仍然是一个早期指标,但我们今天有一个可用的折叠,您可以查看。

在这两者之间,您应该能够从真实用户那里获得足够的遥测,以查看他们遇到的JavaScript性能问题。

奥门威尼斯网址 51

马塞尔·弗赖比希勒(Marcel Freinbichler)发布了一则面向欧盟用户的关于“今日美国”(USA Today)的病毒推文,用它比正常页面加载快42秒。

众所周知,第三方JavaScript可能会对页面加载性能产生严重影响。虽然这仍然是正确的,但重要的是要承认,今天的许多经验也带来了很多自己的第一方JavaScript。如果我们要快速加载,我们需要消除这个问题的双方可能对用户体验产生的影响。

我们在这里看到了几个常见的漏洞,包括团队在文档头部使用阻止JavaScript来决定向用户显示的A / B测试。或者,将所有A / B测试变体的JS运送下来,即使实际上只使用了一个。

奥门威尼斯网址 52

如果这是您目前遇到的主要瓶颈,我们会另外提供有关加载第三方JavaScript的指南。

没有最快,只有更快

性能就像一段旅程,经过了许多小的变更的积累,最终获得大的性能提升。

让你的用户可以尽可能平滑的与你的网站进行交互,运行最少的JavaScript脚本来传递数据。你可以通过逐步递进的方法来慢慢实现这些。最终,你会得到用户的认可。

奥门威尼斯网址 53

参考:

  • Can You Afford It?: Real-world Web Performance Budgets
  • Progressive Performance
  • Reducing JavaScript payloads with Tree-shaking
  • Ouch, your JavaScript hurts!
  • Fast & Resilient — Why carving out the “fast” path isn’t enough
  • Web performance optimization with Webpack
  • JavaScript Start-up Optimization
  • The Impact Of Page Weight On Load Time
  • Beyond The Bubble — Real-world Performance
  • How To Think About Speed Tools
  • Thinking PRPL

非常感谢Thomas Steiner, Alex Russell, Jeremy Wagner, Patrick Hulce, Tom Ankers 和 Houssein Djirdeh 对文章的贡献,也非常感谢 Pat Meenan 在WebPageTest上的努力, 这里有一篇文章是关于WebPageTest的,有兴趣的话可以看一看,你也可以在Twitter上关注我。

 

1 赞 收藏 评论

奥门威尼斯网址 54

在本文中,我们将简要介绍帮助我们提高页面性能的以下几个主要方面:

性能测量:实验室和现场测试工具。

渲染:客户端和服务器端渲染,预渲染和混合渲染方法。

网络:CDN、缓存、GraphQL 缓存、编码、HTTP/2 和服务器推送(Server Push)。

浏览器中的 JavaScript:包大小预算、代码拆分、异步和延迟脚本、图像优化(WebP、延迟加载、渐进)和资源提示(预加载、预取、预连接)。

针对某些情况,我们的主页是用 React(TypeScript)、Phoenix、Puppeteer(无头 Chrome)和 GraphQL API(Ruby on Rails )构建的。在移动设备上的界面如下所示:

奥门威尼斯网址 55

Universe homepage 和 explore

1

性能测量

提供线索的编辑没有数据,只不过是空谈。—— W. Edwards Deming

实验室测试工具(Lab instruments)

实验室测试工具允许在受控环境中,用预定义设备和网络设置采集数据。借助这些工具,调试任何性能问题和具有良好重现性的测试就变得更加简单。

Lighthouse 是在本地计算机上审核 Chrome 页面的出色工具。它还提供一些关于如何提高性能、可访问性、SEO 等有用技巧。下面是一些模拟 Fast 3G 和 4 倍 CPU 减速的 Lighthouse 性能审核报告:

用 First Contentful Paint 提高 10 倍性能的前后对照

然而,只使用实验室测试工具的缺点是:它们不一定能发现真实世界的瓶颈问题,这些问题可能取决于终端用户的设备、网络、位置和很多其他因素。这就是为什么使用现场测试工具也很重要的原因。

现场测试工具(Field instrument)

现场测试工具使我们可以模拟和测量真实的用户页面负载。有很多有助于从实际设备中获取真实性能数据的服务:

WebPageTest——允许在不同位置的实际设备上执行来自不同浏览器的测试。

Test My Site——使用基于 Chrome 使用情况统计的 Chrome 用户体验报告(Chrome User Experience Report,简称 CrUX);它对公众开放,并每月更新一次。

PageSpeed Insights——结合了实验室(Lighthouse)和现场数据。

奥门威尼斯网址 56

WebPageTest 报告

2

渲染

渲染内容的方法有很多,每种方法都有其优缺点:

服务器端渲染(Server-side rendering,简称 SSR)是在服务器端为浏览器获取最终 HTML 文档的过程。优点:搜索引擎可以爬取网站而不执行 JavaScript、快速初始页面加载、代码只存在于服务器端。缺点:没有丰富的网站交互、重新下载整个页面,对浏览器功能的访问有限制。

客户端渲染是使用 JavaScript 在浏览器中渲染内容的过程。优点:丰富的网站交互、在初始下载后根据路由变化快速渲染、可以访问现代浏览器功能(如,Service Workers 的离线支持)。缺点:不支持 SEQ、初始页面加载速度慢、通常需要在服务器端执行单页面应用程序(Single Page Application、简称 SPA)和 API。

预渲染和服务器端渲染类似,但是它是在构建时期提前发生的,而不是在运行时发生的。优点:服务构建静态文件通常比运行服务器简单、支持 SEO、初始页面加载快。缺点:如果代码有任何变化,需要预先预渲染所有可能的页面、重新加载整个页面、站点交互不够丰富、访问浏览器功能受限。

客户端渲染

之前,我们把我们的主页和 Ember.js 框架一起实现为具有客户端渲染的 SPA。我们遇到的一个问题是,Ember.js 应用程序包太大。这意味着,在浏览器下载、解析、编译和执行 JavaScript 文件时,用户只能看到一个空白的屏幕。

白屏

我们决定用 React 重建该应用程序的某些部分。

我们的开发人员已经熟悉构建 React 应用程序。

我们已经有了一些 React 组件库,可以在多个项目之间共享它们。

新页面有一些交互式 UI 元素。

有一个拥有大量工具的庞大的 React 生态系统。

借助浏览器中的 JavaScript,可以构建具有大量良好功能的渐进式 web 应用程序(Progressive Web App)。

预渲染和服务器端渲染

例如,用 React Router DOM 构建的客户端渲染应用程序的问题, 仍然和 Ember.js 的相同。JavaScript 开销大,并且需要一些时间才能看到浏览器中的首次内容绘制(First Contentful Paint)。

当我们决定使用 React 后,我们马上就用其它潜在的渲染选项进行试验,以让浏览器更快地渲染内容。

奥门威尼斯网址 57

使用 React 的常规渲染选项

Gatsby.js 使我们可以用 React 和 GraphQL 预渲染页面。Gatsby.js 是个很棒的工具,它支持很多开箱即用的性能优化。然而,对我们来说,预渲染没有用,因为我们可能有无数个页面,它们包含用户生成的内容。

Next.js 是流行的 Node.js 框架,它允许服务器端用 React 渲染。然而,Next.js 很自我,需要使用其路由、CSS 解决方案等等。我们现有的组件库是为浏览器而构建的,与 Node.js 不兼容。

这就是我们为什么决定尝试一些混合方法的原因,尝试从每个渲染选项中获得最佳效果。

运行时预渲染

Puppeteer 是个 Node.js 库,它允许使用无头 Chrome。我们希望让 Puppeteer 试试在运行时进行预渲染。这支持使用一种有趣的混合方法:服务器端用 Puppeteer 渲染,客户端用激活渲染。这里有一些谷歌提供的有用窍门,关于如何使用无头浏览器来进行服务器端渲染。

奥门威尼斯网址 58

用于运行时预渲染 React 应用程序的 Puppeteer

使用这种方法有如下优点:

可以使用 SSR,对 SEO 来说,这很棒。爬虫程序不需要执行 JavaScript 就能看到内容。

允许构建简单浏览器 React 应用程序一次,然后把它用在服务器端和浏览器中。让浏览器应用程序更快地自动让 SSR 更快,这是双赢。

在服务器上用 Puppeteer 渲染页面通常比在终端用户的移动设备上更快(连接更好, 硬件更好)。

激活允许用对 JavaScript 浏览器功能的访问来构建丰富的 SPA。

我们无需事先知道所有可能的页面来预渲染它们。

然而,我们在使用这个方法时遇到了一些挑战:

吞吐量是主要问题。在单独的无头浏览器进程中执行每个请求消耗了大量资源。你可以使用单个无标题浏览器进程,并在单独的选项卡中运行多个请求。然而,使用多个选项卡将会使整个进程的性能下降了。

奥门威尼斯网址 59

使用 Puppeteer 进行服务器端渲染的体系结构

稳定性。扩展或缩小很多无头浏览器,让流程保持“热度”及平衡工作负载是个挑战。我们尝试了不同的托管方法:从 Kubernetes 集群自托管到用 AWS Lambda 和 Google Cloud Functions 的无服务器。我们注意到,后者在用到 Puppeteer 时有一些性能问题:

奥门威尼斯网址 60

在 AWS Lambdas 和 GCP 函数上的 Puppeteer 响应时间

随着我们越来越熟悉 Puppeteer,我们已经迭代了我们的初始方法。我们还进行着一些有趣实验,通过一个无头浏览器来渲染 PDF。还可以使用 Puppeteer 来进行自动端到端测试,甚至都不用写任何代码。现在,除了 Chrome,它还支持 Firefox。

混合渲染方法

在运行时使用 Puppeteer 很具挑战性。这是我们为什么决定在构建时使用它,并借助一个在运行时可以从服务器端返回实际用户生成内容的工具。与 Puppeteer 相比,它更稳定,并且吞吐量更大。

我们决定尝试一下 Elixir 编程语言。Elixir 看起来像 Ruby,但是运行于 BEAM(Erlang VM)之上,旨在构建容错且稳定的系统。

Elixir 使用 Actor 并发模型。每个“Actor”(Elixir process)只占用很少的内存,约为 1-2KB。这样允许同时运行数千个独立进程。Phoenix 是一个 Elixir web 框架,支持高吞吐量,并在独立的 Elixir 过程中处理每个 HTTP 请求。

我们结合了这些方法,充分利用了它们各自的优点,满足了我们的需要:

奥门威尼斯网址 61

Puppeteer 用于预渲染,而 Phoenix 用于服务器端渲染

Puppeteer 在构建时用我们希望的方式预渲染 React 页面,并以 HTML 文件形式保存它们(App Shell 来自 PRPL 模式)。

我们可以继续构建一个简单的浏览器 React 应用程序,不需要在终端用户设备上等待 JavaScript 就可以快速加载初始页面。

我们的 Phoenix 应用程序服务于这些预渲染页面,并动态地把实际内容注入到 HTML 中。

这让内容 SEO 变得很友好,允许根据需要处理大量不同的页面,并且更容易扩展。

客户端接收并立即显示 HTML,然后激发 Recat DOM 状态以继续作为常规 SPA。

这样,我们可以构建高度交互的应用程序,和访问 JavaScript 浏览器功能。

奥门威尼斯网址 62

使用 Puppeteer 进行预渲染、使用 Phoenix 进行服务器端渲染和激发使用 React 的客户端的体系结构

3

网络

内容分发网络

使用 CDN 可以实现内容缓存,并可以加速其在世界范围内的分发。我们使用 Fastly.com,它为超过 10% 的互联网请求提供服务,并为各种公司使用,如 GitHub、Stripe、Airbnb、Twitter 等等。

Fastly 允许我们通过使用名为 VCL 的配置语言编写自定义缓存和路由逻辑。下图显示了一个基本请求流的工作原理,根据路由、请求标头等等来自定制每个步骤:

奥门威尼斯网址 63

VCL 请求流

另一个提高性能的选择是在边缘使用 WebAssembly和 Fastly。把它想象成使用无服务器,但是在边缘使用这些编程语言,如 C、Rust、Go、TypeScript 等等。Cloudflare 有个类似的项目支持 Workers 上的 WASM.

4

缓存

尽可能多地缓存请求对提高性能很重要。CDN 级别上的缓存可以更快地为新用户提供响应。通过发送 Cache-Control 头来缓存可以加快浏览器中重复请求的响应时间。

大多数构建工具(如 Webpack)允许给文件名添加哈希值。可以安全地缓存这些文件,因为更改文件将创建新的输出文件名。

通过 HTTP/2 缓存和编码的文件

GraphQL 缓存

发送 GraphQL 请求最常见的方法之一是使用 POST HTTP 方法。我们使用的一种方法是在 Fastly 级缓存一些 GraphQL 请求:

我们的 React 应用程序注释了可以缓存的 GraphQL 请求。

发送 HTTP 请求前,我们通过从请求正文构建哈希值来附加 URL 参数,该请求正文包括 GraphQL 请求和变量(我们使用 Apollo Client 自定义 fetch)。

默认情况下,Varnish使用整个 URL 作为缓存键的一部分。

这允许我们继续在请求正文中使用 GraphQL 查询发送 POST 请求,并在边缘缓存,而不会访问我们的服务器。

发送带有 SHA256 URL 参数的 POST GraphQL 请求

以下是一些其它潜在的 GraphQL 缓存策略:

在服务器端缓存:整个 GraphQL 请求,在解析器级别上或通过注释模式声明性地进行缓存。

使用持久的 GraphQL 查询和发送 GET/graphql/:queryId 以便能够依赖 HTTP 缓存。

本文由威尼斯国际官方网站发布于奥门威尼斯网址,转载请注明出处:奥门威尼斯网址:叁回浏览器质量提高

关键词: