页面加载性能之SPOF

SPOF的简单示例

只是在页面上添加一个脚本或者一个样式,也许就会让大部分用户无法正常使用。比起考虑CSS错误或者JS报错的情况,核心问题在于如果这个新添加的资源文件超时,会发生什么?有了这个线索,我们可以构建一个测试用例:






Here's my page!

页面看上去很简单,如果 snippet.com 这个站点超载了,页面将会持续空白,等待 main.js 返回。下图是一些单点故障(SPOF)的示例,以及在不同浏览器下的影响,图片年代久远,仅供参考:

页面加载性能之SPOF_第1张图片

红色标注的是SPOF的情况,以下是从最坏到最好的四种可能的结果:

  • totally blank: 页面什么都没渲染,完全空白
  • blank below: 该资源下方的所有dom都未渲染
  • delayed: 使用自定义字体的文字不可见,直到字体文件下载完成后展示
  • flash: dom立刻渲染,等到样式文件或者字体下载完成,视情况重新渲染样式

如何避免SPOF?

事实证明,有一些Web性能最佳实践,除了可以让你页面变得更快之外,还可以避免大多数前端单点故障。

外部脚本

所有浏览器都会阻止外部脚本以下的dom渲染,直到该脚本下载并执行,然而还是有很多人把脚本放在 标签中,一旦该脚本超时,整个页面都会空白。最佳的Web性能实践就是异步加载这些脚本,不仅可以提升页面的加载速度,也能避免单点故障。

样式

浏览器在样式渲染上有所不同。FireFox和Opera会先渲染dom,等样式加载完再视情况重新渲染,而chrome、IE和safari则是等待样式加载完,再去渲染dom。如果样式文件超时,页面渲染被阻塞,用户只能看到白页了。在不阻止页面渲染的情况下加载样式的建议不多,因为这会造成内容闪烁的问题。

内联样式的自定义字体

如果自定义字体定义在内联样式中,单点故障会大大减少。FireFox、IE和Opera会先渲染文本,等自定义字体加载完,在重新渲染,但chrome和safari直到字体文件下载完才会相关文本,对于这些浏览器的用户,遇到问题的话就不能正常使用了。考虑到一般网站都只是部分文本使用自定义字体,这类问题的影响不会太大。

外部样式的自定义字体

把自定义字体定义在内联样式中,是避免单点故障的关键,因为如果字体文件超时,也仅仅是应用这些字体的文字不可见,至少页面其余部分是可见的。如果把自定义字体定义在外部样式中,不仅降低了你的网页的打开速度(需要2个顺序的请求来渲染文本),而且如果样式文件超时,该资源以下的dom将无法渲染,如果你的样式文件在 标签中,则完全空白了。

如何测试SPOF?

其实测试方式很简单,只要模拟一下这类超时的请求即可,需要一个黑洞服务器,你的请求发过去不会有任何响应那种,以下就是个示例:

blackhole.webpagetest.org (aka 72.66.115.13)

黑洞服务器指的就是请求可以到达,但都会被服务器丢掉,浏览器收不到任何响应。

然后绑定host:

72.66.115.13 ajax.googleapis.com     
72.66.115.13 apis.google.com         
72.66.115.13 www.google-analytics.com
72.66.115.13 connect.facebook.net    
72.66.115.13 platform.twitter.com 

这样,和上面相关资源就会超时了,当然还有更优雅的方式,具体的可以参考 https://blog.patrickmeenan.co...

总结

很多时候,我们都会把焦点放在后端的性能上,觉得只要后端接口能够快速返回就可以让用户更快的看到页面,而忽视了一些前端细节,可能因为你的一次第三方库的引入,就导致了SPOF,平时多问问自己:

  • 你的站点是不是一定要依赖这些资源?
  • 如果其中一个资源超时了,用户能不能看到内容?
  • 这些SPOF都是来自第三方库吗?
  • 在使用一些内嵌的资源的时候,考虑过如何避免SPOF吗?

对SPOF时刻保持警惕,引入第三方库的时候尽可能用无阻塞的方式。

参考

你可能感兴趣的:(web,前端性能优化)