原文:The State of the Web: A guide to impactful performance improvementsjavascript
互联网发展很是迅速,因此咱们创造了Web平台。一般咱们会忽视连通性等问题,但用户们却不会视而不见。一瞥万维网的现状,能够发现咱们并无用同情心、变通意识去构建它,更不要说性能了。php
因此,今天的Web是什么状态呢?css
在这个星球上的74亿人中,只有46%能够上网。平均网络速度上限为7Mb/s。更重要的是,有93%的互联网用户正在经过移动设备进行访问——若不适配移动设备将引发用户反感。一般状况下,数据比咱们假设的更昂贵——可能须要1到13小时才能购买500MB的数据包(德国 vs. 巴西;更有趣的统计数据参见 Ben Schwarz 的 Beyond the Bubble: The Real World Performance)。html
咱们的网站也不是完美的——平均网站是原始Doom游戏的大小(约3 MB)(请注意,为了统计准确,应使用中位数,阅读 Ilya Grigorik 的优秀“平均页面”是一个神话,中档网站大小目前为1.4MB)。图像能够轻松占用1.7 MB的带宽,而JavaScript平均值也有400KB的体积。这不只是Web平台的问题,原生应用程序可能更糟,还记得为了获取错误修复版本,而下载200MB安装包的情景吗?前端
技术人员常常会发现本身处于特权状态。随着最新的高端笔记本电脑、手机和快速有线互联网链接,很容易让咱们忘记,这些并非每一个人都有的条件(实际上,真的不多)。java
若是咱们从特权和缺少同情的角度来构建网络平台,那么将致使排他性的糟糕体验。react
考虑到设计和开发的性能,咱们怎样才能作得更好?webpack
理解浏览器如何分析和处理资源,是显著提升性能的最强大但未充分利用的方式之一。事实证实,浏览器在嗅探资源方面很是出色,同时解析并肯定其优先级。这里是关键请求的来源。git
若是请求中包含用户视口中呈现内容所必需的资源,则该请求相当重要。github
对于大多数网站,它将是HTML、必要的CSS、logo、网络字体,也多是图片。在许多状况下,几十个其余不相关的资源(JavaScript、跟踪代码、广告等)影响了关键请求。幸运的是,咱们可以经过仔细挑选重要资源并调整优先级来控制这种行为。
经过<link rel ='preload'>
咱们能够手动强制调高资源的优先级,确保所需的内容按时呈现。这种技术能够显著改善“交互时间”指标,从而使最佳的用户体验成为可能。
关键请求对许多人来讲,彷佛仍然是一个黑匣子,可共享资料的缺少并不能改变现状。幸运的是,Ben Schwarz
发表了关于这个问题的很是全面并平易近人的文章——关键请求。另外,请参阅Addy的文章,在Chrome中的预加载、预取和优先级(Preload, Prefetch and Priorities in Chrome)。
[在Chrome开发人员工具中启用优先级]
要跟踪在请求优先级处理方面的状况,请使用Lighthouse性能工具和关键请求链审核工具,或查看Chrome开发人员工具中“网络”选项卡下的请求优先级。
图片一般占网页传输的大部分有效载荷,所以图片优化能够带来最大的性能提高。有许多现有的策略和工具能够帮助咱们删除额外的字节,可是首先应考虑的问题是:“图片对于我想传达的信息和效果相当重要吗?”。若是能够消除它,不只能够节省带宽,并且还节省了请求。
在某些状况下,能够经过不一样的技术实现相似的结果。好比CSS就具备艺术方向的一系列属性,例如阴影、渐变、动画及形状,容许咱们构造适当风格的DOM元素。
若是不能舍弃图片,肯定哪一种格式更合适就很重要了。首先要在矢量和光栅图形之间作出选择:
作出首个决定后,能够选择如下几种格式:JPEG、GIF、PNG–八、PNG–24,或最新的 WEBP 与 JPEG-XR 格式。有了这么多的选项,如何确保咱们作出正确的选择?如下是找出最佳格式的基本方法:
Photoshop能够经过各类设置,例如下降质量、下降噪音或色彩数量来优化以上每一种格式。确保设计师了解上述性能实践,并可以使用正确的方式优化相应格式的图片。若是您想了解更多如何处理图片,请阅读 Lara Hogan 的好文 Designing for Performance。
图像格式有几个较新的玩家,即WebP、JPEG 2000 和 JPEG-XR。它们都是由浏览器厂商开发的:Google 的 WebP,Apple 的 JPEG 2000 和 Microsoft 的 JPEG-XR。
WebP 是最受欢迎的竞争者,支持无损和有损压缩,这使得它很是灵活。无损的 WebP 比 PNG 小26%,比 JPG 小25-34%。WebP 有着74%的浏览器支持,它能够安全地进行降级,最多可节省1/3的传输字节。JPG 和 PNG 能够在 Photoshop 和其余图像处理应用程序以及命令行界面(brew install webp
)中转换为WebP。
若是你想探索其余格式之间的视觉差别,推荐 Github 上这个很赞的 Demo。
即便使用了高效的图像格式,也不该跳事后处理优化。这一步很重要。
若是您选择了尺寸相对较小的 SVG,它们也是能够再次压缩的。SVGO 是一个命令行工具,能够经过剥离没必要要的元数据来快速优化 SVG。另外,若是您喜欢Web界面或受操做系统的限制,请使用 Jake Archibald 的 SVGOMG。由于 SVG 是基于 XML 的格式,它也能够在服务器端进行 GZIP 压缩。
ImageOptim 是大多其余图像类型的最好选择。包括 pngcrush、pngquant、MozJPEG、Google Zopfli等,它在一个全面的开源包中捆绑了一大堆优秀的工具。ImageOptim 能够以 Mac OS 应用程序、命令行界面和 Sketch 插件形式,轻松地实现到现有的工做流程中。对于那些在 Linux 或 Windows 上的场景,大多数 ImageOptim 的 CLI 均可以在您的平台上使用。
若是您倾向于尝试新兴的编码器,Google 今年早些时候发布了 Guetzli——源自 WebP 和 Zopfli 的开源算法。Guetzli 能够比任何其余可用的压缩方法生成35%更小体积的 JPEG。惟一的缺点是:处理时间慢(CPU 每处理百万像素须要1分钟)。
选择工具时,请确保它们生成所需的结果并适应团队的工做流程。理想状况是,将优化过程自动化,这样就不会产生漏掉的状况。
十年前,咱们使用一种分辨率,就能够为全部人服务,但时代变化太快,现今的响应式 Web 已非往日可比。这也是为何咱们必需要特别留心,去精心优化视觉资源,确保它们适应各类视口设备。幸运的是,感谢 Responsive Images 社区小组,咱们能够完美使用 picture
元素和 srcset
属性(两者都有85%+支持率)。
srcset
在分辨率切换方案中效果最佳——即当咱们须要根据用户的屏幕密度和大小显示图像时。基于srcset
和size
属性中的一组预约义规则,浏览器将选择最佳图片,相应地提供给视口。这项技术能够带来很大的带宽和请求节省,特别是对于移动用户。
[srcset 使用示例]
picture
元素和media
属性旨在使艺术设计变得容易。经过为不一样情形提供不一样图片(经过媒体查询进行测试),不管什么分辨率,咱们都能始终将图像中最重要的元素保持在焦点。
[picture 元素使用示例]
请务必阅读 Jason Grigsby 的 Responsive Images 101指南,以便对这两种方法进行完全的阐述。
视觉优化的最后一步是分发。全部资源均可以从使用 内容分发网络 中受益,但还有一些针对图片优化的特定工具,例如 Cloudinary 和 imgx。使用这些服务的好处远远超过了减小服务器上的流量,并显着下降了响应延迟。
CDN能够很好的解决重图片网站的复杂度,包括响应式服务与图片优化。虽然产品不一样(价格也是如此),可是大多数方案都是根据设备和浏览器,调整大小、裁剪来肯定哪一种格式最适合用户。甚至更多——它们能够压缩、检测像素密度、水印、识别面部,并容许后置处理能力。借助这些强大的功能,和将参数附加到URL的能力,以用户为中心的图片服务变得十分容易。
srcset
和picture
自定义字体是一项很是强大的设计工具。可是能力伴随着不少责任。现有68%的网站在使用 Web字体,这种类型的资源是性能杀手之一(平均轻松可达100KB,取决于变体和字体的数量)。
即便体积不是最大的问题,不可见文本闪动(FOIT)也算是。当Web字体加载中或加载失败时,会发生FOIT,这会让空白页面,从而致使内容没法访问。首先仔细检查咱们是否须要Web字体多是值得的。若是真是这样,有一些策略能够帮助咱们减轻对业务的负面影响。
有4种网络字体格式:EOT、TTF、WOFF 和最近的 WOFF2。TTF 和 WOFF 被普遍使用,拥有超过90%的浏览器支持率。根据支持状况,最有可能安全地使用WOFF2,并在旧版浏览器降级使用 WOFF。使用WOFF2的优势是,一套定制的预处理和压缩算法(如Brotli),并有大约30%的文件大小减小和改进的解析能力。
在@font-face
中定义网页字体的来源时,请使用format()
提示来指定应使用哪一种格式。
若是您使用 Google Fonts 或 Typekit 来提供字体,这两种工具都实施了一些策略来优化其性能。Typekit 如今能够异步地为全部套件提供服务,防止 FOIT 以及容许其JavaScript套件代码的10天延长缓存期限(而不是默认10分钟)。Google Fonts 能够根据用户设备自动提供最小的文件。
不管是否自主托管,字体数量、字体体积和样式,都将显著影响您的性能预算。
理想状况下,咱们只须要一种包括常规和粗体的字体。若是您不肯定如何选择字体范围,请参考 Lara Hogan 的 Weighing Aesthetics and Performance。
Unicode范围子集容许将大字体分割成较小的集合。这是一个相对先进的策略,特别是在处理亚洲语言的时候,可能会带来显着的节省(你知道中文字体有平均数为 20,000 个字形吗?)。第一步是将字体限制为必要的语言集,例如拉丁语,希腊语或西里尔语。若是仅使用Web字体作Logo类使用,则应使用Unicode范围描述符,来选择特定字符。
Filament Group 发布了一个开源命令行工具,能够根据文件或URL生成必要字形列表的 glyph hanger。或者,基于 Web 的 Font Squirrel Web Font Generator 提供高级子集和优化选项。若是在字体选择器界面中内置了使用Google Fonts 或 Typekit 选择语言子集,则使基本子集更容易。
字体是阻塞渲染的——由于浏览器必须首先构建 DOM 和 CSSOM;在使用与现有节点相匹配的CSS选择器以前,浏览器并不会下载Web字体。这种行为会明显延迟文本呈现,一般会致使前面提到的不可见文本闪动(FOIT)。在较慢的网络和移动设备上,FOIT会更加显着。
实施字体加载策略,可防止用户没法访问您的内容。一般,选择无样式文本闪动(FOUT)是最简单和最有效的解决方案。
font-display
是提供非 JavaScript 依赖解决方案的新 CSS 属性。不幸的是,它仅有部分支持(Chrome 和 Opera),目前正在 Firefox 和 WebKit 中开发。尽管如此,它能够而且应该与其余字体加载机制结合使用。
[font-display 属性实践]
幸运的是,Typekit 的 Web Font Loader 和 Bram Stein 的 Font Face Observer 能够帮助管理字体加载行为。此外,网页字体性能专家 Zach Leatherman 发布了字体加载策略综合指南,这将有助于为您的项目选择正确的方法。
目前,JavaScript 的平均大小为446 KB,已经使其成为第二大的资源类型(第一为图片)。
咱们可能没有意识到,咱们所爱的JavaScript隐藏着更加严峻的性能瓶颈。
优化交付只是解决网页膨胀的第一步。JavaScript 下载后,必须由浏览器进行解析、编译和运行。快速浏览一些流行的网站,显而易见的是,gzip 压缩的 JS 在解压以后至少变大三倍。事实上,咱们正在发送一大堆代码。
1MB JavaScript 在不一样设备上的解析时间。图片由 Addy Osmani 和他的 JavaScript Start-up Performance 文章提供。
分析解析和编译时间,对于理解应用程序是否准备好进行交互相当重要。这些耗时根据用户设备的硬件能力而异。解析和编译会很容易在低端手机上高出2-5倍。Addy的研究证明,在常规手机上,一个应用程序将须要16秒才能达到交互式状态,而在桌面电脑上为8秒。分析这些指标相当重要,幸运的是,咱们能够经过 Chrome DevTools 来完成。
[在 Chrome 开发工具中查看解析和编译过程]
请务必阅读 Addy Osmani 对 JavaScript 启动性能的详细说明。
现代软件包管理器的工做方式,能够垂手可得地掩盖依赖关系的数量和大小。webpack-bundle-analyzer 和 Bundle Buddy 是很好的可视化工具,帮助识别出代码重复、最大性能问题和过期的、没必要要的依赖。
图 webpack bundle analyzer 实践(译者注:原gif太大,只能用外链了)
经过 VS Code 和 Atom 中的Import Cost
扩展,咱们可使导入依赖成本更加明显。
只要有可能,咱们就应只提供用户体验所必需的资源。向用户发送一个完整的
bundle.js 文件,包括他们可能永远看不到的交互效果处理代码,并不太理想(假设在访问着陆页时,去下载处理整个应用程序的 JavaScript)。一样,咱们不该广泛提供针对特定浏览器或用户代理的代码。
Webpack,最受欢迎的模块打包器之一,天生具有代码分割支持。最简单的代码分割能够按页面实现(如用于着陆页的home.js
,联系人页面的contact.js
等),Webpack 还提供了一些高级策略,如动态导入及延迟加载,值得一看。
JavaScript 前端框架突飞猛进。根据2016年的 JavaScript 调查,React 是最受欢迎的选择。仔细审视架构选择,可能会发现,您可使用更为轻量级的替代方案,例如 Preact(请注意,Preact 并非一个完整的 React 从新实现,只是一个高性能,功能更轻的虚拟 DOM 库)。相似地,咱们能够将较大的库更换成更小的版本——moment.js
换成date-fns
(或者在特定状况,删除moment.js
中未使用的 locales)。
在开始一个新项目以前,有必要肯定什么样的功能是必需的,并为您的需求和目标选择最具性能的框架。有时这可能意味着选择写更多的原生 JavaScript。
咱们已经讨论了一些策略,在大多数状况下会对咱们正在创建的产品用户体验产生积极的变化。性能多是一个棘手的问题,有必要长期地跟踪咱们调整的结果。
卓越的性能指标,旨在尽量接近描绘用户体验。以往的onLoad
,onContentLoaded
或SpeedIndex
对「用户多快能与页面交互」给出的信息很是少。当聚焦到传输资源时,量化地感知性能十分困难。好在,有一些时间能够全面地描述内容的可视性和互动性。
这些指标是首次渲染(First Paint),首次有意义渲染(First Meaningful Paint),视觉完整(Visually Complete)和可交互时间(Time to Interactive)。
这些时间直接对应于用户的实际体验,所以能够做为重点进行追踪。若是可能,将它们记录所有,不然选择一两个来更好地监控性能。其余指标也须要留意,特别是咱们发送的字节数(优化和解压缩)。
全部这些上报数字可能会很快变得混乱和不易理解。没有可操做的目标和对象,很容易迷失咱们最初的目的。几年前,Tim Kadlec 写过关于性能预算的概念。
遗憾的是,并无一个万能的神奇公式。性能预算一般归结为竞争分析和产品目标,而这是每一个业务所各异的。
设定预算时,重要的是要达到明显的差别,一般是至少改善20%。实践和迭代您的预算,利用 Lara Hogan 的方法新设计与性能预算做为参考。
试用性能预算计算器或Chrome扩展浏览器卡路里,以帮助建立预算。
监控性能不该该是手动的。市面上有不少强大的工具,还能够提供全面的报告。
Google Lighthouse 是一个能够审核性能、可访问性、渐进式网络应用程序等的开源项目。您能够在命令行中或直接在 Chrome Developer Tools 中使用Lighthouse。
[Lighthouse 运行一次性能审查]
对于持续的追踪,选择选择 Calibre,它能够提供性能预算、设备仿真、分布式监控和许多其余功能,无需咱们仔细构建本身的性能套件便可得到。
[Calibre 报表]
不管您在追踪什么,请确保使整个团队或组织可以透明地访问数据。
性能是一项分担责任,远远超过开发人员团队——咱们都应对所建立的用户体验负责,无论是什么角色或职级。
倡导速度和创建协做流程,以便在产品决策或设计早期阶段,尽早暴露可能遇到的瓶颈,是很是重要的。
关心性能不只仅是一个业务目标(可是若是您须要经过销售统计数据来进行销售,那么能够经过PWA统计)。这是关于基本的同情和用户体验放在第一位。
做为技术专家,咱们的责任是,不要让用户的注意力和时间放在等待页面上,而已能够更开心地花费在其余地方。咱们的目标是创建意识到时间和人们关注的工具。
提倡性能意识应该是每一个人的目标。让咱们抱着性能和同情心,为你们创建一个更好、更有意义的将来吧。