天天看点

页面性能的基础因素 - 《Designing for Performance》

考虑页面性能可以从两种场景,第一个场景也是因素最多的场景,即首次访问。第二个场景则是重复访问,缓存将起决定性作用。

不同的页面类型的性能优化策略也是不一样的,比如富文本页面,富多媒体页面,响应式设计的页面,游戏页面等。

浏览器也提供了很多工具和插件,比如Chrome DevTools, YSlow和PageSpeed Insight都有相应的插件,可以为开发者提供页面优化建议,这是最为简捷的方式。我在这里也主要使用Chrome进行分析,部分会配合WebPageTest工具。

要优化页面性能,了解浏览器如何渲染页面是非常重要的。以下是浏览器加载的整套流程,特别强调了对首次打开性能影响很大的网络加载流程:

页面性能的基础因素 - 《Designing for Performance》

其中如果HTTPS,建立连接的过程中还需要进行身份认证。

通过Chrome Inspect中的网络也可以看到整个加载数据量,以及耗时:

页面性能的基础因素 - 《Designing for Performance》

上图是新浪首页的数据,共发出415请求,收到6.5MB的数据,主要是图片大多,果然是个大站!

点开可以看到细节的数据耗时:

页面性能的基础因素 - 《Designing for Performance》

上面可以看到为请求建立与服务器的连接的开销还是比较大的。特别是在移动网络下,DNS解析,错误重连的成本都非常高,浏览器厂商也都会针对性的进行优化。

无论是以前的Pipeline, 和现在的Http2都可以达到连接复用的目的,也可以省掉这部分的开销。

Chrome的开发者工具提供了Audit, 可以提供网络相关优化和页面性能优化的建议, 比如:

页面性能的基础因素 - 《Designing for Performance》

在Chrome Web Store里安装YSlow和PageSpeed Insights插件,就可以进一步分析页面的性能,以及提供相关的建议。下图是YSlow的显示页面组件的内容:

页面性能的基础因素 - 《Designing for Performance》

在后面Statistics页签会显示资源占比,以及启用缓存(下次访问)时需要发送的请求数和资源大小:

页面性能的基础因素 - 《Designing for Performance》

可惜这只是理想,新浪有些资源的url带有随机数,也就是每次请求的url并不相同,会导致http cache无法使用,会重新加载。

最终新浪首页的性能显示不怎么样,YSlow给出了D,附上一堆建议,点来Grade页签就可以看到。

PageSpeed Insights会给出相类似的建议,不过个人还是建议使用PageSpeed Insights, 它给出的建议会更加符合当前业界的标准。

除了TTFB这种主要由网络环境和后台服务器决定的因素外,页面设计,以及包括User Agent(客户端,如浏览器)可能影响的因素包括:

<b>连接管理 (连接数和复用)</b>

在HTTP下本来有一个Pipeline的机制,用来达到一个HTTP连接来并发获取多个资源,但是服务器支持的少。

另一种方法是Keep alive的常连接。即User Agent尝试保持若干个连接,完成一个资源的加载后,这个连接可以继续用来加载另一个资源。这样就没有重新建立连接的开销。

而HTTP 2最大的特色就是让每一个连接支持多个资源的并发请求。

<b>请求数</b>

<b>请求大小</b>

因为网络里上行和下行的速度差异,请求的大小也会对页面性能有所影响, 所以要避免不必要的请求头信息,其中Cookie最为明显。首先Cookie的存储、检索和提取就要耗费性能,再加上Cookie的应用往往是针对某个域名下或者路径下的所有请求,会导致性能的影响被放大。

<b>资源大小</b>

HTML5新的响应式图片更是允许根据客户端(User Agent)的屏幕大小,而选择不同的图片。

<b>HTTP Cache</b>

网络层的缓存模块,负责管理可缓存的资源,尽量复用缓存中已经有的可用资源。最快的请求就是不发请求,善于使用Http Cache,可以大大优化除首次打开外页面性能。但是一些网站遇到一些缓存问题时,常常简单的为url增加一个随机数,让缓存失效,这样既让客户端的整体缓存命中率下降(缓存了很多不必要的资源),强烈建议不要使用这种方法。

开始加载页面,到实际显示出内容,有一个最小的路径,即关键渲染路径。尽量缩短这条路径才能真正优化到用户的体验。

最核心的流程是浏览器收到页面数据后解析为DOM (Document Object Model), 加载CSS文件,生成CSSOM,计算各个元素的排版数据生成Layout Tree, 结合者CSSOM生成Render Tree,再交由渲染模块完成渲染显示出页面内容。

这过程中包括很多的并发行为,因为串行完成的性能不可能达到用户体验的要求。

CSS

在这个路径主要是注意一些会阻塞页面解析的元素,如CSS。前面提到CSS文件放到head和body中的方式。

JavaScript

直接出现在页面中的JavaScript会阻塞页面解析, 所以需要将一些JavaScript可以改为异步加载和执行。

<b>定义:可操作时间 (Time To Interactivity)</b>

可操作时间是指从开始加载页面到用户可以在页面进行操作(如搜索,点击链接等)的时间。

通过优化关键渲染路径可以减少可操作时间,包括以下方法:

异步加载内容

优先加载可见内容

遵循CSS/JS加载的最佳实践 (看YSlow和PageSpeed Insights的报告)

缓存资源

优先保证主要用户行为尽早可用

比如下面这个Chrome DevTools显示出一个Long Frame, 从前面一个Frame这里花去了很长的时间,这一般代表卡顿的出现 (只有9fps)。

页面性能的基础因素 - 《Designing for Performance》

如果使用PageSpeed Insights,可以得到关于Blocking CSS的建议。

继续阅读