[译]Web 性能

Posted 前端之音

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[译]Web 性能相关的知识,希望对你有一定的参考价值。

Web 性能

这是对现代 Web 加载性能的介绍。学习了解为什么性能是很重要的,存在哪些性能优化以及哪些工具有助于了解您的应用程序是否运行良好。

这就是我们要谈论的。

  1. 为什么性能很重要?

  2. javascript

    1. 压缩代码

    2. 使用 async 和 defer

    3. 代码拆分

    4. 从依赖包中删除未使用的代码

  3. CSS

    1. 压缩代码

    2. 使用关键 CSS 方式

  4. HTTP

    1. 压缩 html

    2. 使用 Gzip 压缩内容

    3. 使用 Brotli 压缩内容

    4. 使用 CDN 服务

    5. 预加载内容

  5. Images

    1. 选择适当的格式

    2. 压缩图片

  6. Fonts

    1. 指定后备字体

    2. 使用 font-display 属性

  7. Tools


[译]Web 性能

那么,为什么 web 性能很重要?

首先,因为网站慢很不舒服。

最好的例子是,当移动站点加载缓慢时,用户将承受与观看恐怖电影相同的压力。

其次,因为它直接影响您的产品。

  • 2016年,AliExpress 的网站速度提高了三分之一,并多获得了10.5% 的订单

  • 早在 2006 年时,Google 尝试将搜索速度降低半秒,然后发现用户的请求量减少了25%

  • 在 2008 年,Aberdeen Group 发现,将网站速度降低一秒会降低16% 的用户满意度

而且有很多此类数据–以前的和最新的研究可以参考(wpostats.com·pwastats.com)。

这就是为什么Web性能很重要的原因了。

现在,要了解我们到底要讨论什么,我们需要了解快速的站点是怎样的。

  • 它加载很快

  • 并且在加载后可以快速运行(这意味着动画不会跳过帧,平滑滚动等等)

[译]Web 性能

在以下情况下,网站可以快速加载:

  • 服务器在短时间内响应请求

  • web 应用程序本身可以快速加载和渲染

[译]Web 性能

在本文中,我们将讨论以下元素:如何进行网站加载和快速呈现。

  1. 服务器快速响应

  2. 快速加载和渲染

  3. 快速运行

大多数情况下,第一个要素不相关,性能问题在于第二个或第三个要素。第三个要素不在本文讨论。

所以开始讨论,如何快速加载和渲染吧!

[译]Web 性能

Javascript

让我们从 JavaScript 开始。因为通常,JavaScript 是加载缓慢的资源。

优化 JavaScript 的第一种方法是压缩。如果您已经知道,请跳到下一部分。

压缩(Minify)

什么是压缩?在编写 JS 时,通常会以一种方便的方式对其进行格式化。添加缩进,为变量使用有意义的长名称,编写注释,等等。因此,该代码更易于阅读,但是所有额外的空格和注释使它大大变大了。

[译]Web 性能

[译]Web 性能

所以为了解决这个问题,人们想出了压缩的方法。在压缩过程中,代码将删除所有不必要的字符,长变量名变为较短的变量名,依此类推。最后,JS 文件变小了,但仍按预期工作。

压缩使代码的大小减少了 30–40%。

可以使用主要应用程序构建器进行压缩:

  • Webpack 的 mode: production

  • Babel 的 babel-preset-minify

  • Gulp 的 gulp-uglify

[译]Web 性能

Async and defer

您编写了一个脚本,将其压缩了,现在要将其加载到页面上。如何将其连接到页面呢?

最简单的方式就是编写 <script> 标签并指定文件的路径。这是对的,而且可以运行。但是,您知道这种方法有什么问题吗?

问题就是 script 脚本阻塞解析。

[译]Web 性能

这是什么意思?

当浏览器加载页面时,它开始将 HTML 文档解析为标签并构建DOM树。稍后,它将使用此 DOM 树来渲染页面。问题是,script 可以更改 DOM 树的构建方式。

例如,script 脚本可以调用 document.write() 将开始注释标签写入文档中。在运行脚本之后,将破坏整个 DOM 树(和整个页面!)。这就是为什么浏览器在遇到脚本时会停止解析的原因,以防止文档跳转并避免做额外的工作。

[译]Web 性能

从浏览器的角度来看,它看起来像这样:

  • 浏览器浏览文档并对其进行解析

  • 有时,浏览器会遇到 <script> 标签。它将暂停解析 HTML 并开始下载和执行脚本

  • 执行脚本完后,浏览器将继续解析

[译]Web 性能

实际上,这意味着添加脚本时,在脚本下载并执行之前,该脚本之后的任何内容都是不可见的。而且,如果将脚本添加到 <head>中,则在脚本执行完成之前,所有内容都将不可见。

注意:实际上,现代浏览器通常会尝试进一步解析 DOM 树,即使它们遇到 <script> 标签也是如此。如果脚本未进行任何修改且DOM 树未更改,这有助于节省时间。但是,浏览器仍然不显示任何脚本之后的内容。

[译]Web 性能

那么该怎么办?使用 script 标签的属性 asyncdefer

这些属性告诉浏览器可以在后台下载脚本,而不会中断文档解析。它们的工作方式如下:

  • async 要求浏览器异步加载脚本(在后台),并在脚本下载时继续解析文档。(如果脚本在解析结束之前加载完,解析将暂停;但是由于加载脚本通常比解析花费更多的时间,因此这种情况很少发生。)

  • defer 告诉浏览器异步下载脚本并仅在解析文档之后执行脚本。

[译]Web 性能

[译]Web 性能

这个两个属性有一个重要的区别:

  • 使用 async 的脚本将在下载完后立即执行,而不会按照脚本顺序。这意味着,如果您有一个异步 React 包和一个异步 web 应用程序包,并且 React 包更大,则该应用程序将比 React 更快地下载并执行-- 这样网站将无法正常运行。

  • async 不同, defer 仅在下载所有脚本后才以正确的顺序执行。因此,在优化大型复杂 web 应用程序时,defer 可能比 async 更安全。

根据我的经验,这些优化可以减少 200–500 毫秒(甚至更多)加载时间,具体取决于您的代码大小和脚本链接数量。实际上很多时候是半秒。

[译]Web 性能

代码拆分(Code splitting)

继续深入了解。

通常,web 应用程序的构建是这样的:您编译应用程序并最终获得一个大捆绑包(bundle),每个请求都将其发送给客户端。问题在于应用程序的一些组件,用户在极少数情况下才会看到。

例如,每月才会打开一次的 modal 窗口或没有人使用的路由。即使这些路由或弹出窗口中的代码几乎没有用,它仍会占用捆绑包中的体积并增加加载时间。

[译]Web 性能

[译]Web 性能

这通常通过代码拆分来解决,将大捆绑包分成较小的捆绑包。

通过代码拆分,我们将应用程序功能的不同部分放入了不同的文件,并仅在必要时请求并加载它们。因此,如果用户不需要打开“更改头像” modal ,则根本不会下载它。

如何实现代码拆分?

首先,您需要使用打包工具,例如 webpack,Parcel 或 Rollup。(以下是最受欢迎的 webpack,因此我将主要介绍它。)所有这些打包工具都支持一个特殊的功能,称为 import()

在浏览器中,import() 接收传入的 JS 文件并异步下载该文件。此功能在当 web 应用启动时不需要第三方库,但稍后再使用它时很有用。

然而,对于打包工具,处理 import() 函数的方式有所不同。如果将文件名传递给 import() 函数,然后 webpack,Parcel 或 Rollup 将获取该文件,将其及其所有依赖项打包在一起,然后将结果放入一个单独的编译文件中。然后,只有在调用此 import() 时,应用程序才会下载该文件。

因此,在下图示例中,webpack 将 ChangeAvatarModal.js(及其依赖项)打包到一个单独的文件中。并且,在执行期间,当调用此 import() 函数时,将下载此文件。

这是实际的代码拆分。

[译]Web 性能

[译]Web 性能

另外,在 React 和 Vue.js 中,有一些辅助工具可与 import() 配合使用,使您的工作更加轻松。

例如,react-loadable 库是一个组件,可在等到另一个组件加载时,呈现一个占位符。React 16.6 添加了类似的内置功能 Suspense。Vue.js 支持异步组件已有一段时间了。

[译]Web 性能

代码拆分节省了加载成本吗?节省巨大。

如果处理得当,就加载资源、节省流量数据而言,代码拆分是最重要的优化。如果仅在应用程序中执行一种优化,请对其进行代码拆分。

请参阅指南以了解更多信息:

  • 有关代码拆分的 WebFundamentals 文章

  • 涵盖代码拆分基础的 React 文档

  • webpack 指南代码拆分

webpack-libs-optimizations 代码库

还有什么优化?优化的另一个巨大空间是应用程序依赖包。例如:

  • 用于处理日期的库 Moment.js 包含约 160kB 的不同语言的本地化文件。

  • 即使在生产环境的 bundle 中,React 组件也保留了 propTypes,尽管事实上并不需要。

  • 使用 Lodash,即使您只需要使用其中的几种方法,也很容易导入整个库。

所有这些都是应用程序依赖包带入 bundle 的无用代码。

[译]Web 性能

为了使开发人员更多地了解这些额外的代码,并帮助他们删除它们,我们(与 Google 一起)建立了一个代码块,该代码块收集了有关如何使用 webpack 优化各种依赖包的技巧。使用这些技巧可以使您的应用加载运行更快,体积更小!

→ GoogleChromeLabs/webpack-libs-optimizations

小结

这是所有关于 JS 的优化,总结如下:

  • 压缩 JS 代码

  • 使用 script 标签的 asyncdefer 属性

  • 拆分代码以尽可能加载更少代码量

  • 从依赖库中删除未使用的代码

[译]Web 性能

CSS

[译]Web 性能

接下来是如何又会 CSS 代码。

首先,就像 JS 代码一样,压缩 CSS。删除不必要的空格和字符以使代码体积更小。

[译]Web 性能

这些工具可以压缩 CSS 代码:

  • webpack 的 postcss-loader 和 cssnano

  • PostCSS 的 cssnano

  • Gulp 的 gulp-clean-css

其次-哦,样式阻塞渲染,您已经遇到了类似的问题,如 JS 阻塞渲染。

那是因为没有样式的网站看起来很奇怪。如果浏览器在加载样式之前呈现页面,则用户将首先看到以下信息。

[译]Web 性能

然后页面将闪烁,他们将看到以下内容。几乎没有令人愉快的用户体验。

[译]Web 性能

这就是为什么样式仍在加载时页面仍空白的原因。

现在,这里有一个聪明的优化技巧。在样式尚未加载的情况下,浏览器将页面保持空白是完全合理的,我们也不想摆脱这一点。但是,我们仍然可以通过只为页面加载初始渲染所需的一部分样式,然后再获取其余样式,使页面的渲染速度更快。初始渲染所需的那些样式称为“关键 CSS”。

让我们看看它是如何工作的。

使用 Critical CSS,加载页面的过程如下所示:

  1. 您将样式分为关键和非关键CSS。

  2. 您可以将关键 CSS 内联到 HTML 文档中,这有助于尽快为 HTLM 提供样式。

[译]Web 性能

现在,只要您使用内联的关键 CSS 来给 HTML 提供样式,页面就已经可以渲染了。但是,您仍然需要获取并应用非关键 CSS。

加载剩余 CSS 的方式有很多种,不幸的是,它们全都是 hacky(骇客)。这就是我更喜欢这样做的方式:

  1. 需要添加 <link rel="preload"> 以开始获取非关键 CSS 文件。

  2. 并且,一旦文件被加载并存储缓存中,就将 rel 属性从 preload 更改为 stylesheet。这使浏览器可以使用缓存的 CSS 文件并将其应用于文档。

[译]Web 性能

如何知道要在关键 CSS 中包括什么以及以后要使用什么样式?通常,规则是:

删除样式并隐藏页面元素,直到页面开始看起来真的很有趣(或不正确)为止。剩下的 CSS 就是关键 CSS 了。

例如,页面布局或文章中文本的样式很关键-因为没有它们,页面看起来会很奇怪。且对于 JavaScript 弹出窗口或页脚而言,样式也不是至关重要的,因为用户不会立即看到这些元素,而且如果没有这些样式,页面看上去也将非常完美。

[译]Web 性能

这听起来可能很复杂,但值得庆幸的是,有一些自动化工具可以为您做到这一点:

  • styled-components, 这是一个 CSS-in-JS 库,可在服务器端渲染期间提取并返回关键 CSS。仅当您已经使用 styled-components 编写样式时,这才有效,但是如果您已经这样做,它确实可以很好的提取关键 CSS。

  • critical, 这是一种实用程序(utility),可接收 HTML 页面,在无头浏览器中渲染,并提取首屏内容的样式。由于 critical 仅在单个页面上运行,因此对于复杂的单页面应用程序可能无法很好地工作。

  • penthouse, 它与 critical 类似,但可以使用 URL 提取关键 CSS, 而非使用 HTML 页面。

使用关键 CSS 节省加载时间吗?节省巨多。根据我的经验,提取关键 CSS ,完成第一次绘制可能节省 200-500 毫秒的时间,甚至更长!

要了解有关关键 CSS 的更多知识,请阅读《 Smashing Magazine》的指南。

[译]Web 性能

小结

CSS 的主要优化策略:

  • 压缩 CSS 代码

  • 提取关键的 CSS 并优先加载

[译]Web 性能

HTTP

[译]Web 性能

现在,让我们转到 HTTP 和相关网络内容的优化技巧。

再次,网络传输较少数据的第一种方法是压缩文档。如前所述,压缩要发送给客户端的 HTML 文档(以及CSS和JS)。第二种方法是使用 Gzip 压缩发送给客户端的所有内容。

Gzip 是一种算法,可以使用复杂的归档算法压缩您发送给客户端的数据。压缩后,您的文档看起来像是不可读的二进制文件,但是其体积将减少 60–80%。当浏览器接收到数据时,会将其解压缩。

[译]Web 性能

基本上,使用 Gzip 压缩是一种生产标准,因此,如果您使用任何流行的服务器(例如 Apache 或 nginx),则只需更改几个配置即可将 Gzip 打开。

Apache 指导 · Nginx 指导

注意:按照这些说明指令开启 Gzip 将导致服务器动态压缩资源,这会使响应时间略长。在大多数情况下,您无需关心这一点,但是如果您希望获得一流的响应时间,请在构建过程中预先压缩资源。

[译]Web 性能

注意:除了文本,不要将 Gzip 用于压缩其他内容!图片,字体,视频和其他二进制文件通常已经被压缩了,因此将其压缩后只会增加响应时间。SVG 图像是唯一的例外,因为它们是文本。

[译]Web 性能

Brotli

Gzip 有另一种选择,一种称为 Brotli 的压缩算法。

Brotli 的优势:在相同的 CPU 负载下,压缩率比 Gzip 好 20% 至30%,请求下载的字节数减少了 30%!

Brotli 的缺点:它相对较新,所以支持比 Gzip 差。因此,您无法轻松方便地用 Brotli 替换 Gzip,必须同时使用两者才能进行压缩,才能在不同的浏览器中使用。

[译]Web 性能

自 Apache 2.4.2 6 版以来,已经支持 Brotli。且 Nginx 可以将Brotli 作为外部模块使用。

Apache 指导 · Nginx 模块

注意:请勿将 Brotli 的压缩级别设置为最高,因为它会使压缩速度大大低于 Gzip。Brotli 的压缩 level 4 既比 Gzip 的默认级别快,而且压缩效果更好。

CDN

现在,让我们谈谈 CDN。

什么是 CDN?假设您构建了一个应用程序并将其托管在美国的服务器上。如果应用程序的用户在 Warsaw(波兰华沙),则他们的请求将必须一直到美国,然后再返回波兰。这将花费大量时间,因为请求将必须经过很长的距离(并且其速度受光速的限制);它还必须通过许多路由器和类似设备(并且每个设备都会增加处理延迟)。

如果有用户请求获取应用程序的数据,并且只有美国的一台服务器知道如何正确地形成数据,这是合理的。但是,如果用户尝试下载图像或视频,则绝对没有必要只向美国那台服务器请求,因为这只是常规的静态内容,几乎可以由任何服务器提供。

CDN 服务正是提供针对此问题的解决方案。CDN 代表“内容分发网络”,而 CDN 服务提供了大量服务器,可将您的静态文件(内容)发布到世界各地。要使用其中一个 CDN服务,需要注册 CDN 服务,上传文件并在应用程序中更新文件的域名。然后,每个用户的请求将重新路由到最接近其位置的服务器。

根据我们的经验,CDN 通常会将每个请求的延迟从数百毫秒减少到 5-10 毫秒。考虑到打开一个页面时应用程序发出了多少请求,使用 CDN 的效果确实很棒。

[译]Web 性能

Preloading

您知道 Google 会在搜索后立即开始预加载在搜索结果中的第一个链接吗?这是因为所有访问者中有三分之一点击了第一个链接,对其进行了预加载,从而使他们可以更快地查看目标网站。

如果您有页面或资源,需要在短时间快速加载,则浏览器可以提前加载它们, 像 Google 一样预先加载它们。

[译]Web 性能

共有 5 种不同的预加载方法,所有这些方法都适用于不同的目标。简要介绍一下这些方法的作用:

  • <link rel="preconnect"> 告诉浏览器提前执行到服务器的连接。这和 dns-prefetch 在同样情况下,都很有用,但是建立了完整的连接并节省了更多时间。这样做的缺点是打开新连接会占用大量资源,因此您不想过度使用此优化。

  • <link rel="prefetch"> 以低优先级在后台预加载和缓存资源。这对预加载应用的下一页 JS bundle 很有用。

  • <link rel="preload"> 以高优先级在后台预加载资源。这对于在几秒钟内预加载您需要的资源很有用,例如非关键 CSS 文件。

  • <link rel="prerender"> 在后台预加载指定的页面,并将其呈现在不可见的 tab 中。然后,当访问者点击指向预渲染页面的链接时,该页面将立即显示。这就是 Google 用来预加载其第一个搜索结果的方式。

注意:请勿过度使用预加载的方法。在后台下载内容仍然会消耗访问者的流量,而且在移动设备上确实很糟糕。因此,添加 10 个额外的预加载可能会使您的应用程序运行更快,但是您的访客将为此支付实际费用。每页 2-4 个预加载可能是比较好的。

[译]Web 性能

阅读更多:Preload, prefetch and other <link> tags

小结

总结 HTTP/网络 优化:

  • 压缩 HTML,CSS,JS 等资源

  • 使用 Gzip 和 Brotli 压缩文本资源

  • 使用 CDN 节省下载静态资源的时间

  • 预加载您稍后需要的资源

[译]Web 性能

Images

[译]Web 性能

Moving on,让我们来谈谈图像。

图片会占用大量流量,但幸运的是,它不会阻塞渲染(就像 JS 或 CSS 代码一样)。不过,最好也对其进行优化,以使其显示更快并使用更少的网络流量。

首先最重要的是,图片有不同的图片格式,不同目的适合不同类型的图片,要为每个图片选择合适的格式。

[译]Web 性能

最常见的格式是 svgjpgpngwebpgif。这是在它们之间进行选择的方法。

  • svg 最适合矢量图像,例如图标或徽标。

  • jpg 最适合照片,因为 jpg 的压缩只有轻微质量损失,人眼看不到的损失。

  • png 最适合显示光栅图形(raster graphics),而不会损失任何质量-例如,光栅图标(raster icons)或像素图(pixel art)。

  • Webp 同时支持有损和无损压缩,因此对照片和栅格图形均适用。它也比 jpgpng 压缩体积更小,小至少 20% 至 30%。

  • git 完全不要使用 gif 格式。gif 体积很大,通常它们需要数 MB 或数 10 MB 的数据。相反,使用视频文件(<video> 标签)可以更好地压缩文件。

[译]Web 性能

不幸的是,Safari 和 Internet Explorer 不支持 webp。但是,您仍然可以使用 <picture> 标签加载具有 jpgpng 备选格式。

这就是带有 jpg 备选格式的用法。使用 <picture> 标签,支持 webp 的浏览器将加载 webp 文件。不支持 webp 的浏览器将退回到 jpg 图像。

[译]Web 性能

(图像压缩)Image compression

除了使用正确的图片格式外,还可以通过压缩来优化图片。不同图片格有不同的压缩方式。

首先是 svg:

  • 压缩,由于 SVG 图片是文本,因此可以通过删除注释和空格来压缩它们。

  • 简化路径(paths),如果从图形编辑器自动生成或导出 SVG 文件,则其中的路径可能会过于复杂。如果出现这种情况,请删除不会对视觉产生任何影响的路径点。

  • 简化文件结构。通常如果从图形编辑器导出 SVG 文件,则它还会包含额外的 meta 元素,删除那些减小 SVG 体积。

所有这些优化都可以用 svgo 控制台实用程序自动进行。svgo 的 UI 也很棒。

[译]Web 性能

第二是 jpg:

  • 减小图像尺寸。根据我的经验,这是照片中一个非常常见的错误。

当您将一幅大尺寸的图片(例如 2560×1440 px 的照片)放在一个小容器中(例如 533×300 px)时,就会出现问题了。发生这种情况时,浏览器必须下载不必要的大文件。此外,它还必须花时间将文件缩小到较小的尺寸。那是没有意义的。

要解决此问题,请在图像编辑器(如 Photoshop 或 Gimp )中使用Webpack 加载器(例如,responsive-loader)或使用其他工具来缩小图像。如果您需要 HiDPI 屏幕的高分辨率图片,请改用 <picture><img srcset> 实现。

[译]Web 性能

  • 以 70‑80 的压缩级别压缩 JPG 图像。这是因为,即使压缩到一定程度,质量损失也不明显。

例如,这是同一张 JPG 图像的三种不同版本:质量为 100 级,质量为 70 级和质量为 50 级。

原始图片:100 级,70 级, 50 级

Bruce Hon 在 Unsplash 上的拍摄

如果放大图片,则仅在 50 级压缩时会看到明显的压缩失真和细节损失。压缩级别 70 仍会有一些图像细节丢失,但不太明显。

裁剪和缩放的图像:100 级,70 级,50 级

但是,此图片的不同版本对的体积有很大不同。70 级图像几乎比 100 级图像小 7 倍,而且几乎保持相同的细节水平!

因此,要压缩到 70-80 级的 JPG 图像。质量损失微不足道,但体积减少却令人难以置信。

要压缩 JPG 图像,请使用 Photoshop 或 Gimp 等图形编辑器,和 Webpack 加载器(例如 image-webpack-loader)或其他工具。

[译]Web 性能

[译]Web 性能

  • 使用渐进式 JPEG(Progressive JPEG)。渐进 JPEG 是一种 JPG,其开始呈现的质量很差,但是随着图像的加载而逐渐改善。

例如,这是在网络速度较慢时通常加载非渐进式(基准)图像的方式。它只是从上到下缓慢地渲染。

[译]Web 性能

但是,渐进式图像开始使用较少的细节进行渲染,并在加载过程中得到增强。因此,访问者可以较早地大致看到图像中的内容。

[译]Web 性能

要使图像渐进,请使用 Photoshop 或 Gimp 等图形编辑器,和 Webpack 加载器(例如 image-webpack-loader)或其他工具。

注意:使用渐进式 JPEG 并非是没有代价的。它们的解码速度较慢,并且比相同的基准图像大。在 Addy Osmani 的 images.guide 中阅读更多内容。

Gif 来源:Jeff Atwood 的渐进式图像渲染

第三是 png:

  • 使用交错式 PNG(Interlaced PNG)。交错式 PNG与渐进 JPEG的工作方式相同:它开始以低质量渲染,但随着加载而改善。它并不适合所有内容。例如,逐渐加载 png 图标看起来很奇怪,但对于其他某些图片可能适用。

  • 使用索引颜色(indexed colors)。使用索引颜色时,PNG 图像会将其所有颜色放入调色板中,并使用索引来引用每种颜色。这样可以减少每个像素所需的字节数,并可能有助于减少整体图像体积。由于调色板的大小受限制(最多 256 种颜色),因此该解决方案不适用于颜色丰富的图片。

[译]Web 性能

交错式 PNG 和索引颜色都可以使用图形编辑器,image-webpack-loader 或其他工具生成。

以上所有操作都可以自动化!已经在前面提到了一些工具。但总结一下并添加更多内容:

  • webpack 的 image-webpack-loader,在每次构建(build)代码 时,几乎可以进行以上所有优化。它的默认设置是 OK 的,可以直接使用与生产模式。

  • 如果您需要一劳永逸地优化图像,可以使用 ImageOptim 之类的应用程序以及 TinyPNG 之类的网站。

  • 如果您无法将 webpack image-webpack-loader 插入构建过程中,那么还有许多 CDN 和服务可以为您托管和优化图像(例如 Akamai,Cloudinary 或 imgix)。

[译]Web 性能

这就是所有关于图像的优化。小结一下:

  • 选择适当的图像格式

  • 通过减小尺寸,降低质量或使图像渐进来优化图像加载时间

要了解有关图像优化的更多信息,请参考:

  • images.guide by Addy Osmani

  • Responsive images on MDN

[译]Web 性能

Fonts

[译]Web 性能

关于优化的最后一部分:字体。

当您通过慢速的网络浏览网页时,有时会出现页面开始加载,布局和图片已经可见的情况,但文本又消失了几秒钟。

当页面具有自定义字体时,会发生这种情况。在此类页面上,浏览器通常不会立即呈现文本。取而代之的是,它们等待几秒钟,等待这些字体加载完,才使用它们呈现文本。但在几秒钟后仍无法下载字体时,它们会使用后备字体。

这种不显示文本的行为通常是合理的,因为它可以防止未样式化文本闪烁(当一种字体替换为另一种字体时发生的文本跳动)。但是在速度较慢的网络中,此行为会使用户等待更长的时间。这是不可取的。

让我们看看如何优化字体来避免这种情况。

后备字体(Fallback fonts)

第一,请记住指定后备字体。

后备字体是无法下载主要字体或需要一段时间才能加载的字体时,浏览器使用的字体。后备字体是在自定义字体名称之后的定义的,使用 CSS fontfont-family 声明指定。

后备字体可能是一种流行的内置字体(例如 Georgia)。它可能是通用字体系列(例如衬线或无衬线)或两者兼而有之。通常,即使您指定了流行的内置字体,仍然应该添加通用字体系列,因为在某些设备上甚至可能没有该字体。

没有后备字体,如果自定义字体不可用,浏览器将以默认的衬线字体呈现所有内容。这可能看起来并不那么好看。

但是,使用后备字体,您可以指定类似于自定义字体的字体。

font-display

第二,使用自定义字体时,请使用 font-display CSS 属性。

font-display 属性调整了自定义字体的应用方式。在所有主流浏览器中,默认情况下,font-display 设置为 auto,浏览器将等待 3 秒,用来下载自定义字体。这意味着,如果网络速度慢,访问者将不得不等待整整 3 秒钟才能看到文本。

[译]Web 性能

这是不好的。要对此进行优化,请为该属性指定其他字体显示值。

注意:在 Microsoft Edge 中,font-display: auto 行为不同。设置了它,如果未缓存自定义字体,Edge 会立即以后备字体呈现文本,并在以后加载完了替换为自定义字体。这不是错误,因为 font-display: auto 可让浏览器定义加载策略。

我认为 font-display 有两种值适用于大多数情况。

第一个是 font-display: fallback,设置了它,浏览器将立即以可用字体呈现文本:自定义字体(如果已缓存),否则是后备字体。然后,如果未缓存自定义字体,浏览器将下载它。而且,如果自定义字体的下载速度足够快(通常在 3 秒内),浏览器就会将后备字体与下载好的自定义字体交换。

浏览器的这种行为,有时用户会看到后备字体的页面,然后开始浏览,但是随后浏览器将替换自定义字体,随着而来就是闪烁文本(另请参考:未样式化文本的闪烁)。这对用户体验来说稍差一些,但比完全不显示任何文本要好。

[译]Web 性能

第二个属性值是 font-display: optiona,设置了它,浏览器还将立即以可用的字体呈现文本:自定义字体(如果已缓存)或是后备字体。但是,即使下载了自定义字体,在刷新页面之前,浏览器也不会替代它。此行为意味着用户将只能在页面上看到自定义字体或后备字体,而永远不会体验到未样式化文本的闪烁。

[译]Web 性能

如何在 font-display: fallbackfont-display: optional 之间进行选择?

我相信这是一个个人或老板喜好的问题。我个人更喜欢使用自定义字体来呈现文本,因此我选择了 font-display: fallback。如果初次访问者会以备用字体看到您的网页, 也是 OK 的话,可以选择 font-display: optional

注意:此字体显示技巧不适用于图标字体(icon fonts)。在图标字体中,每个图标通常由很少使用的 Unicode 字符编码的。所以使用 font-display: fallback,随机字符出现在图标字体的位置。

要了解更多 font-display 的知识: CSS-Tricks article ·  demo of different font-display values

这是关于字体的优化,小结一下:

  • 指定适当的后备字体(和通用字体系列)

  • 使用 font-display 来配置如何应用自定义字体

[译]Web 性能

Tools

[译]Web 性能

万岁,最后是工具部分!以下是一些工具,可让您深入了解该 web 应用的性能。

第一个工具是 Google PageSpeed Insights。

PageSpeed Insights 对您提供的 URL 进行了许多审核。他们分析页面资源,找到优化建议,并计算您应用程序的性能得分。

如果您想从网络性能入手,则此工具将最适合您。旨在 PageSpeed 中得分达到 80 或更高。

[译]Web 性能

第二个工具是 Lighthouse。

Lighthouse 具有多个审核指标(包括性能,SEO 和可访问性)。它计算多个指标并输出更多性能建议。

与 PageSpeed Insights(作为独立网站运行)不同,Lighthouse内置在 Chrome DevTools 中。这意味着您甚至可以将其用于不公开访问的应用程序!

第三个工具是 WebPageTest。

WebPageTest 是一种高级审核工具。它分析站点性能,并输出大量数据,例如指标,加载瀑布,内容细分等。对于进行复杂的优化时非常有用。

最后一个工具是 webpack-bundle-analyzer。

webpack-bundle-analyzer 是一个 webpack 实用工具,可以可视化您的 bundle js 内容。可以了解 bundle js 的大小和哪个 bundle js 需要优化,这对性能优化很有用。在 WebFundamentals 上了解有关如何更多使用它的信息。

Thanks!

在Twitter上关注我: @iamakulov

感谢 Arun,Anton Korzunov,Matthew Holloway,Bradley Fe,Brian Rosamilia,Rafael Keramidas,Viktor Karpov 和 Artem Miroshnyk (无特殊顺序)提供了有关草稿的反馈。

原文链接:https://3perf.com/talks/web-perf-101



以上是关于[译]Web 性能的主要内容,如果未能解决你的问题,请参考以下文章

译ECMAScript 2016, 2017, 2018 新特性之必读篇

[译] Swift 编译器性能

CentOS6.5下编译安装LAMP环境

[译] 如何在React中写出更优秀的代码

在调试或发布/分发模式下编译时 iOS 应用程序的性能

译.NET 7 中的性能改进