性能优化三部曲之二——通用纯前端优化首屏时间

背景:

  1. 对构建的改造已经完成,目前构建的能力可以较为灵活地支撑进一步的优化
  2. 希望进一步减少首屏时间,将首屏时间控制在2秒以内

页面情况:

优化之前,并没有上报首屏时间,页面加载时间约为2.4秒。

研究认为[1],用户最满意的网页打开时间是2秒以内。作为一个相对简单的页面,我们就应该最可能将首屏时间甚至加载时间控制在2秒以内,让用户体验到最佳的页面体验。

定义页面的首屏与加载时间:

首屏时间,英文称之为above the fold(首屏线之上)。我们以手Q群成员分布的页面作为例子。在iPhone5屏幕下,这个页面在没有往下滚动的时候,如上图。滚动到底部时,如下图。

我们所说的首屏时间,就是指用户在没有滚动时候看到的内容渲染完成并且可以交互的时间。至于加载时间,则是整个页面滚动到底部,所有内容加载完毕并可交互的时间。

在这个页面中,我们可以划分成四个部份,分别是活跃 群成员、男女比例、省市分布及年龄。我们将前三个部份归入首屏渲染时间。剩下的内容加载时间加上首屏加载时间即是页面加载时间。

另外值得一提的是,由于之前项目的开发将动画渲染时间也纳入统计,因此为了方便对比,我也将渲染时间纳入统计。实际上,如果除去动画渲染时间,首屏及加载时间会快300 - 500ms。

已经做好的优化:

除非各种性能优化书籍提出的要点之外,在这篇优化之前已经做到的优化并值得简单提出来的有两点。

  1. 活跃群成员头像的懒加载。由于手Q的头像允许gif,因此直接加载头像性能会比较低下。因此之前在完成这块业务的逻辑的时候,已经添加上懒加载,业务渲染的时候显示默认头像,等真实头像加载完成的时候再进行渲染。而且,在这次的优化项目中,我们并不将头像的加载时间也纳入首屏时间内。
  2. 其它内容动画的滚动渲染。其它部份的内容是会由滚动渲染效果的(这些逻辑并不由本人写)。感谢前人做比较模块化地做好了这部份逻辑,因此我能够比较容易地进行代码的搬迁与更改。 纯前端手段优化页面加载及渲染模式:

上图是项目旧有的加载模式,是比较通常的页面加载渲染模式。将css放在head标签内,为了避免阻塞将js放在底部。因此页面渲染完成后,还需要等待js的加载,js拉取数据以及js的渲染。 这便大大地减慢了首屏及加载时间。

从性能的角度看,将整个加载渲染模式换成下面的模式更有利于首屏的渲染,我们可以称之为首屏优先加载渲染模式。

根据上述的模型,我们可以将首屏优先模式总结为三个原则,一是首屏数据拉取逻辑置于顶部,二是首屏渲染css及js逻辑优先内联HTML,三是次屏逻辑延后处理和执行。

**原则一:**首屏数据拉取逻辑置于顶部,是为了数据能够第一时间返回,相比起将数据拉取逻辑放在外部资源会少了一个JS资源加载的往返时间。

**原则二:**首屏渲染css及js逻辑优先内联HTML,这是为了当HTML文档返回时CSS和JS能够立即执行。但要注意的是HTML文档最好不要超过14kb。这是由于,TCP协议里面有一个流控机制,被称为 slow start,也就是在连接建立过程中逐渐增加传输的分段(segments)大小[2],根据Paul Irish在他的演讲“Delivering the Goods”给出的结论是,一个Web应用最开始的 14kb 数据是最重要的[3]。

**原则三:**次屏逻辑延后处理和执行,各种数据上报最好是延时上报,这样可以减少阻塞。对于首屏的数据上报,可以先将数据存在变量里面,等上报组件report.js加载完毕后,再调用回调进行上报。 新人可能会问将这么多代码内联很不优雅,而且很麻烦呀。如果你用的构建是一个合格的构建,你大可以用构建帮你进行内联,这并不是很费时的事情(这也是为什么我将构建作为优化的第一篇章,构建给优化带来便利)。 经过优化以后,首屏时间方面,非离线包版本达到1400ms左右,离线包版本则达到850ms左右。

页面渲染完成时间方面,非离线包版本从平均2400ms左右,降至平均1600ms,性能提升33%。离线包版本从平均1350ms,降至平均970ms,性能提升28%。

[1] http://www.ruanyifeng.com/blog/2009/03/the_psychology_of_web_performance.html [2] https://docs.google.com/presentation/d/1MtDBNTH1g7CZzhwlJ1raEJagA8qM3uoV7ta6i66bO2M/present?slide=id.g3eb97ca8f_1536

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端知识铺

将你的 Virtual dom 渲染成 Canvas

一个基于Vue的virtual dom插件库,按照Vue render 函数的写法,直接将Vue生成的Vnode渲染到canvas中。支持常规的滚动操作和一些基...

1594
来自专栏数说工作室

移形换影 | 【SAS Says · 扩展篇】

【SAS Says·扩展篇】移形换影 | 5. call PRXCHANGE() 0. 前集回顾 1. 新的问题 2. 初识 PRXCHANGE() 3. 问题...

34011
来自专栏CSDN技术头条

IMVC(同构 MVC)的前端实践

导语 随着 Backbone 等老牌框架的逐渐衰退,前端 MVC 发展缓慢,有逐渐被 MVVM/Flux 所取代的趋势。 然而,纵观近几年的发展,可以发现一点,...

2116
来自专栏程序员的SOD蜜

无需重新编译代码,在线修改表单

    最近在跟朋友一起讨论工作流系统中自定义表单的问题,这些表单用于流程节点的数据处理,比如在请假流程中设计一个请假单。为了使工作流具有很高的灵活性,往往需要...

2236
来自专栏企鹅号快讯

史上最全的web前端学习教程汇总!

第一阶段:HTML+CSS HTML进阶、CSS进阶、div+css布局、HTML+css整站开发、 JavaScript基础:js基础教程、js内置对象常用方...

2235
来自专栏熊二哥

快速入门系列--MVC--07与HTML5移动开发的结合

    现在移动互联网的盛行,跨平台并兼容不同设备的HTML5越来越盛行,很多公司都在将自己过去的非HTML5网站应用渐进式的转化为HTML5应用,使得一套代码...

22310
来自专栏张善友的专栏

Metro风格XAML应用程序性能技巧

微软发布了一篇名为《Metro风格XAML应用程序性能技巧》的白皮书,其中包含一些关于保持响应、确保流畅动画、改善启动时间、消耗较少资源等方面的建议。我们在这里...

1748
来自专栏编程微刊

2018年各大互联网前端面试题三(阿里)

2173
来自专栏小程序之家

如何在小程序中使用罗盘

现代生活中,经常会用到导航系统,导航系统必不可少的一个功能就是罗盘,何为罗盘?简单罗盘通过磁力将内部的指针指向某个方向,从而实现判别方位。现代技术以及将罗盘缩小...

1193
来自专栏携程技术中心

干货 | IMVC(同构 MVC)的前端实践

作者简介 古映杰,携程度假研发部前端和 node.js 架构负责人。开源库 react-lite 作者。本文来自古映杰在“携程技术沙龙——新一代前端技术实践”上...

3905

扫码关注云+社区