返回 登录
2

Algolia团队是如何提高网站性能的 值得借鉴!

阅读1632

原文:Improving Web Performance to Mirror Engine Speed
作者: Jonas Badalic Guides, Technology
翻译:无阻我飞扬

摘要:本文作者以Algolia网站为例,详细讲述了影响网站性能的因素,分几个模块阐述了网站优化的方法,以下是译文。

这里写图片描述

性能是Algolia网站的核心特征。我们的搜索引擎从数百万条数据记录中给出毫秒级的搜索结果。它最初是为资源有限的移动设备设计的,但是在转换为在线API之后,它现在作为一个NGINX模块在运行。我们的前端库是以一种允许在客户机上以相同速度展示的方式编写的,它确保跨设备有一个优质的客户体验。Algolia网站的引擎和集成对于网站性能来说是一个高水准的富有灵感的设计,所以我们想反映出我们网站的卓越表现。

减少负载

正如谷歌网站性能工程师;W3C Webperf WG联席主席Ilya所说,拥有一个高速度网站的最快方法就是尽可能的少发送数据。我们的网站依赖于大量的外部依赖关系,这就增加了需要转换数据的总大小,并延迟了加载时间。共有180个请求和2.4M流量必须由我们的网站访问者去转换。

这里写图片描述

加载网站需要发送2.4M的流量负载和180个请求

降低对JavaScript的依赖

去除依赖项,如jQuery,Underscore和其他一些依赖项,将JS脚本大小缩减到初始大小的20%左右。这并没有对我们编写前端代码的方式产生很大的影响,但是它迫使我们要用浏览器自身的API来编写,如querySelector API ,而不是用jQuery。

为了舒缓处理进程,我集成代码为transpiling,所以我们可以写ES6代码并用Babel去transpile.这使得编写代码更加高效和快速。

运行时性能

一旦网站加载,就要避免jank,为用户交互做好准备,通过配置JavaScript代码来寻找瓶颈是非常有用的。

Chrome开发工具在控制台内有一个很有用的透视选项卡,它显示了你网站上被定期更新的区域也可能是导致jank的原因。

这里写图片描述

用Chrome开发工具分析页面性能

这主要是为了用新的IntersectionObserver API重写滚动事件侦听,确保DOM操作不是太频繁,动画只会导致复杂的浏览器操作(看到一个关于csstriggers的操作列表需要更新属性)。

这减轻了浏览器绘制和重绘屏幕所需的繁重的工作,作为回报,为用户提供了更流畅的浏览体验。

减少CSS的大小

由于前端团队没有真正的CSS编写习惯,所以随着我们添加新页面,CSS的大小和它的特性都在快速增长。为了解决这个问题,我们编写了一小组我们自己的助手类,并且采用了使用这些类编写HTML的方法。这样做可以将CSS文件大小减少到初始大小的60%,在不继续增加CSS文件大小的情况下,为站点添加新页面铺平了道路。

令人讨厌的耗时的部分已经完成;现在是时候确保用户真正看到页面速度越快越好。

优先处理first paint

优先处理first paint需要确定哪些素材对网站的展示至关重要。这意味着异步加载所有的网站素材,除了一些很小的图片,如logo和网站大小约50KB的主应用程序的CSS文件。

这样做的目的是为了通过在后台加载其余的素材,以便更快的将网站显示在屏幕上。

下图是关键素材优化前加载的样子。

这里写图片描述

优化后的体验:

这里写图片描述

这种优化带来更快的感知性能体验,而总的加载时间保持不变。

尽可能少的拥有关键素材,在你的域名中托管这些素材也是一种很好的优化方式。否则每次对不同域名的请求都必须要经过DNS查找,连接和SSL协商阶段,这将会增加执行请求网站所需的往返时间。

例如, 如果你从他们的CDN中使用Google字体,而你的服务器支持HTTP/2协议,最好在最初请求的同一个域名上自己安装这个字体。这将大大改善来自移动网络的访客的体验,移动网络本身信号质量差,对访问网站往返时间的要求更高。

在我们的例子中,自己安装字体,而不是从CDN上下载google字体,在3G网络连接中,提高了约1秒的网站加载时间。

这里写图片描述

前(通过googleApi加载字体)vs.后(自己安装同样的字体)

如果你仔细看,你也可以看到fonts.googleapis请求实际是请求了一个包含@font-face规则的CSS文件,由这个CSS文件创建加载字体文件的实际请求。这意味着,通过在我们的应用程序CSS文件中包含@font-face规则,我们也省去了额外的请求—双赢。如果你想深入研究字体加载策略,来自FilamentGroup的Zach Leat写了一篇非常有用的概述,讲述了你今天能做些什么改进。

增加WebP支持

WebP是一种新型的图片格式,它让图片无损和有损压缩更好。它的支持越来越多,因此我决定尝试一下它。

这里写图片描述

40KB WebP vs. 57KB JPG

我们团队进行了几个压缩试验,发现它可以将文件大小压缩到原始大小的75%,这节省了几百KB。

当在建设进程中寻找集成WebP支持时,我发现了一个简单的方法,就是用Cloudflare和他们的润色选项。我发现他们可以通过润色特性自动化进行WebP图像压缩,它整合了WebP超出范围的复杂性,使得它就像点一个按钮那样简单。

在启用了润色选项和WebP压缩后,Cloudflare的工作并不繁重。它检查图像请求是否包含图像值/WebP或者/的头文件,如下图所示。如果头文件匹配,它将原始图片转换为WebP格式并且增加了有内联值的内容配置头文件;文件名=”path/to/image.webp”,告知浏览器,该文件将会在页面上内联显示,并且给出资源文件的路径。

这里写图片描述

接受有webp支持的头文件—img/webp 和/**

这里写图片描述

响应有内容配置的头文件

在这个例子中,Cloudflare的解决方案是有效的,这意味着我们没有更新服务器配置和整合WebP转换构建时间。然而,如果这不是你想要的案例,你想要更多的灵活性,Ilya Grigorik写了一个样本配置检测WebP的支持,会有多个库,你可以用来将图片转换为WebP格式。

使用HTTP/2服务器推送

HTTP/2的一大优点是它具有复用连接服务器推送的特性,这相比较HTTP/1.1,性能上有了很大的改进。

复用连接允许浏览器通过单个连接发送多个请求,这大大的减少了客户端和服务器之间所需的连接数。

服务器推送的一个功能是允许服务器开始发送客户尚未请求的素材,但是已经知道客户将需要这些素材,因此,它就消除了客户端用于解析响应和请求素材的额外时间。

你可以通过添加自定义的HTTP头文件实现服务器推送,或者通过在你的HTML里添加与素材资源的链接rel=”preload” and as=””,在这种情况下,你可能需要polyfill你的行为。

为了额外提高首次绘制的时间,我决定避免polyfilling链接rel=”preload”,为剩下的资源素材建立链接头文件。这将会加快首次显示页面素材的载入时间,提高大约400ms的时间(取决于网络连接质量)。

为了验证服务器推送的素材,检查开发工具网络选项卡,在这里你可以看到该请求并不是由浏览器解析后的文件发起,但是它恰好是由index.html请求而发起的推送。

这里写图片描述

发起人-推送/(index)表明素材由服务器推送

如果你正在寻找一个如HTTP/2服务器推送这样具有高性能的托管解决方案时,可以看看Netlify—他们刚好增加了服务器推送支持,并且他们的托管非常可靠。

瓶颈隐患

当优化网站时,在即将达到优化目的时,突然发现一件事情没有意识到,那就是HTML文档大小。

index.html文件压缩大小是60KB。

究其原因,是内联SVG素材。内联SVG往往建议用在网站社区,因为其具有灵活性。有很多文章提倡它,但是他们推荐它作为通用解决方案往往是有缺陷的,这应该取决于不同的案例。往往有更好的方法去加载内联SVG素材而不是内联他们直接进入文档。

内联SVG文件带来两大后果:

  • 文件大小的增加
  • 素材没有缓存

如果你访问一个网站,它的index.html文件自己的大小约是60KB,获取文档本身需要时间,并且在完成获取之后,你仍然需要其它关键请求来呈现页面。

通过融合SVG文件到存储,将他们异步加载和注入到文档,作为一个额外增加的好处,能够将HTML文件大小从60KB减少到约15KB+,现在缓存了那些SVG文件—又是一次双赢。

衡量结果和变化

这里写图片描述

在整个开发过程中,使用了两个主要的工具来衡量对我们工作的性能影响—Chrome Lighthouse和webpagetest。第一个工具—Lighthouse,它即可以通过在审计选项卡下的Chrome开发工具来访问,也可以作为CLI工具或者Chrome扩展来访问。它提供了有价值的信息和前端指标,而webpagetest可以用来深入网络审计本身。

结果

加载性能得到巨大改善:网站加载更快,甚至在网络连接不良的情况下可以确保网站的访问者在浏览内容和使用搜索引擎时获得快速的体验。

相比原来的2.4MB,现在网站的总大小约700KB,约有300KB的外部依赖关系。相比原来的180S,现在的总请求量在70S以内。

此外,团队能够改善运行时间,并且为网站添加更多的逻辑和动画,而不会对网站页面性能产生负面的影响。

总结

这些改进给用户提供了统一和快速的用户体验,随之,社区页面也随着网站的性能提升而更新。

评论