当前位置: 永利皇宫463手机版 > Web前端 > 正文

你先要知道这几点细节,端渲染优化指北

时间:2019-11-21 20:27来源:Web前端
研究首屏时间?你先要知道这几点细节 2016/01/11 · CSS,JavaScript ·首屏 原文出处:AlloyTeam    做移动web页面,受移动网络网速和终端性能影响,我们经常要关注首屏内容展示时间(以下简

研究首屏时间?你先要知道这几点细节

2016/01/11 · CSS, JavaScript · 首屏

原文出处: AlloyTeam   

做移动web页面,受移动网络网速和终端性能影响,我们经常要关注首屏内容展示时间(以下简称首屏时间)这个指标,它衡量着我们的页面是否能在用户耐心消磨完之前展示出来,很大程度影响着用户的使用满意度。

永利皇宫463娱乐网址 1

怎么获取首屏时间呢?

我们经常要先问自己:页面是怎么加载数据?

A:加载完静态资源后通过ajax请求去后台获取数据,数据回来后渲染内容

永利皇宫463娱乐网址 2

 

在每个点打上一个时间戳,首屏时间 = 点8 – 点1;

B:使用后台直出,返回的html已经带上内容了

永利皇宫463娱乐网址 3

此时首屏时间 = 点4 – 点1。

永利皇宫463娱乐网址,注:1. 打了这么多个点,是因为当我们收集到首屏时间之后,要去分析到底是哪一段是性能瓶颈,哪一段还有优化空间,所以我们需要收集 点2 – 点1、点3 – 点1 ……这些时间以作分析;

  1. 打点1我们一般是在html文件head标签的开头打个时间戳;

  2. 在css文件加载前一般没有别的加载处理,所以打点1和打点2一般可以合并。

 

到此我们就收集到首屏相关各种数据,可以做各种针对性优化。Wait!在你大刀阔斧优化前,你要了解一些细节,它们有利于你做更准确的分析和更细致的优化。

web 端渲染优化指北

细节1:js后面的点 – js前面的点 ≠ js的加载时间

永利皇宫463娱乐网址 4

JsEndTime – JsStartTime = js文件的加载时间,对吗?

不对!明显地,这个等式忽略了js的执行时间。js执行代码是需要花费时间的,特别是做一些复杂的计算或频繁的dom操作,这个执行时间有时会达到几百毫秒。

那么,JsEndTime – JsStartTime = js文件的加载执行时间?

依然不对!因为CSS文件的加载执行带来了干扰。觉得很奇怪对吧,别急,我们来做个试验:我们找一个demo页面,在chrome里面打开,然后启动控制台,模拟低网速,让文件加载时间比较久:永利皇宫463娱乐网址 5

先在正常情况下收集 JsEndTime – JsStartTime 的时间,然后使用fiddler阻塞某一条css请求几秒钟:

永利皇宫463娱乐网址 6

然后再恢复请求,拿到此时的 JsEndTime – JsStartTime 结果,会发现第一次的时间是几百毫秒将近1s,而第二次的时间低于100ms甚至接近为0(我的示例,时间视读者具体的js文件决定),两者的差距非常明显。

这是什么原理?这就是我们常说的”加载是并行的,执行是串行的“的结果。html开始加载的时候,浏览器会将页面外联的css文件和js文件并行加载,如果一个文件还没回来,它后面的代码是不会执行的。刚刚我们的demo,我们阻塞了css文件几秒,此时js文件因为并行已经加载回来,但由于css文件阻塞住,所以后面 JsStartTime 的赋值语句是不执行的!当我们放开阻塞,此时才会运行到 JsStartTime 的赋值、js文件的解析、JsEndTime的赋值,由于大头时间加载早已完成,所以 JsEndTime 和 JsStartTime 的差值非常小。

 

知道这个有何用?

  1. 别再把 JsEndTime – JsStartTime 的结果成为js文件的加载执行时间(除非你没有外联css文件),不然会被内行人取笑滴;
  2. css文件的阻塞会影响后面js代码的执行,自然也包括html代码的执行,即是说此时你的页面就是空白的。所以css文件尽量内联,你可以让构建工具帮你忙;
  3. 如果真想要知道js文件的加载时间,最正确的姿势是使用 Resource Timing API,不过这个API移动端只能在Android4.4及以上的版本拿到数据,也就在业务PV大的场景才够我们做分析用

当然,那两个打点留着还是可以做分析用的。

 

前言

web端近年来发展十分迅速,网页在 native app 中的占比也不断增加,但H5应用的渲染方式,刷新方式与 native 应用有很大的区别。带来的问题是用户会感觉刷新慢,易卡顿,体验差,本篇博文主要针对渲染速度问题进行优化~

细节2:html里面外联的js文件,前一个文件的加载会阻塞下一个文件的执行;而如果a.js负责渲染并会动态拉取js、拉取cgi并做渲染,会发现它后面的js文件再怎么阻塞也不会影响到它的处理

前半部分的结论在细节1里面已经证明,因为浏览器的执行是串行的。这说明,我们负责渲染内容的js代码要等到它前面所有的js文件加载执行完才会执行,即使那些代码跟渲染无关的代码如数据上报:

永利皇宫463娱乐网址 7

而后半部分的结论很好验证,我们在负责渲染的js文件后面外联一个别的js文件并把它阻塞住,你会发现渲染相关的js不管是动态拉取新的js文件、拉取渲染相关内容都一切正常,页面内容顺利渲染出来,它们的执行并不需要等被阻塞的这个文件。

 

知道这个有何用?

  1. 无关紧要”的js不要放在负责渲染的js前面,这里的“无关紧要”是指和首屏渲染无关,如数据上报组件。我们可以选择将要上报的数据临时存起来,先继续执行渲染的js,等负责渲染的js执行完再加载上报组件再上报。甚至连zepto之类的库我们也可以放后面,把渲染相关的代码抽离出来并用原生js书写,放到最前面;
  2. 可以看到,动态加载的js的执行是不会受到html后面外联的js的阻塞的影响,即是说,它的执行和后面js的执行顺序是不确定的。因此我们要小心处理好文件的依赖关系。当然还可以采用最不容易出错的方法:负责动态加载js的文件是html里面外联的最后一个文件

(注:个人觉得这是全文最重要的两点结论,因为我正在做首屏优化^-^)

 

渲染原理

永利皇宫463娱乐网址 8

渲染原理图

从上图可知web界面的渲染原理,这样我们就可以针对此进行优化了,先强调一下html的加载原理,我们常说的”加载是并行的,执行是串行的“的结果。html开始加载的时候,浏览器会将页面外联的css文件和js文件并行加载,如果一个文件还没回来,它后面的代码是不会执行的。

细节3:如果html的返回头包含chunk,则它是边返回边解析的,不然就是一次性返回再解析。这个是在服务器配置的

永利皇宫463娱乐网址 9

打点1一般写在html里head标签的最前面,时常有朋友拿直出时的 点4 – 点1 的时间和非直出时 点8 – 点1 的时候做对比,来说明直出优化了多少多少毫秒,我倒觉得不一定。要知道直出的情况html文件包含渲染后的内容和dom节点,文件大小一般比非直出大,有时甚至大个几十K都有,那我觉得要说明直出优化了多少就要把html的加载时间考虑进去了。那上面的计算方法是否考虑上html的加载时间?

那就要看html文件的返回头是否包含chunk:

永利皇宫463娱乐网址 10

如果包含这个返回头,那html文件是边返回边解析的,此时上面的计算方法是合理的。如果不包含这个头,则html文件是整一个返回来后才开始解析,此时上面的计算方法就少算了html的加载时间,也就不够精准。这个返回头是由后台控制的。

 

知道这个有何用?

  1. 如果我们想说明直出的优化程度,最好先瞧瞧你的html返回头。如果不包含chunk返回头,考虑拿HTML5 performance里面的 navigationStart 作为打点1(这个API也是Android4.4及以上才支持),要不就要评估文件大小变化做点修正了;
  2. 对于没有启用chunk的html,建议不要inline太多跟渲染首屏内容无关的js在里面,这样会影响渲染时间

 

优化渲染速度

大概从如下几个方面进行优化:

  1. 采用SPA开发模式
  2. 采用 Virtual DOM 进行界面更新优化
  3. 服务端渲染
  4. 首屏渲染速度优化
  5. 代码自动化优化审查
  6. 懒加载
  7. 预加载
  8. 资源压缩
  9. 开发规范

细节4:写在html里面的script节点的加载和解析会影响 domContentLoaded 事件的触发时间

我们有时会用 domContentLoaded 事件代替 onload 事件,在页面准备好的时候做一些处理。然而要知道,domContentLoaded里面的dom不止包含我们常说的普通dom节点,还包括script节点。

试验一下,我们将页面里面外联的一个js文件阻塞住一段时间再放开,我们看下chrome控制台:

永利皇宫463娱乐网址 11

很明显,js文件的加载时间会影响这个事件的触发事件。那js代码的解析时间会不会影响?我们在最后一个外联js文件后面打了一个点,它的时间是:

永利皇宫463娱乐网址 12

所以js文件加载执行会影响domContentLoaded事件的执行时机。

知道这个有何用?

  1. 如果我们打算在domContentLoaded、onLoad 事件里面做一些特殊处理且这些处理比较重要(如跟渲染有关),那我们最好就不要在html里面直接外联一些跟渲染无关的js文件,可以考虑改用动态加载

SPA开发模式

由于传统多页模式开发,界面切换造成了频繁的网络请求,导致界面渲染效率十分低下,来自Alexander Aghassipour和Shajith Chacko发表的这篇文章讲述了单页应用程序是如何创建而来的。
单页面应用是指用户通过浏览器加载独立的HTML页面并且无需离开此导航页面,这也是其独特的优势所在。对用户操作来说,一旦加载和执行单个页面应用程序通常会有更多的响应,这就需要返回到后端Web服务器,而单页面应用为用户提供了更接近一个本地移动或桌面应用程序的体验。

单页Web应用程序的优点:

首先,最大的好处是用户体验,对于内容的改动不需要加载整个页面。这样做好处颇多,因为数据层和UI的分离,可以重新编写一个原生的移动设备应用程序而不用(对原有数据服务部分)大动干戈。
单页面Web应用层程序最根本的优点是高效。它对服务器压力很小,消耗更少的带宽,能够与面向服务的架构更好地结合。

单页Web应用程序的缺点:

虽然还有一些历史遗留问题(大部分是针对HTML5的改进)以及SEO。如果你看中SEO,那就不应该在页面上使用JavaScript,你应该使用网站而不是Web应用。目前该技术还存在一些争议,但这并不是重点,因为这种类型的体系架构为SAAS Web Apps提供了一个极大的可用性。

单页Web应用程序的结构很简单:首先传递HTML文档框架;然后使用JavaScript修改页面;紧接着再从服务器传递更多数据然后再修改页面,如此循环。从性能的角度看,在现代浏览器中单页面Web App已经能够和普通应用程序相媲美,而且几乎所有的操作系统都支持现代的浏览器。使用HTML+CSS+Javascript编写应用程序,能使更多的人们都加入到程序开发的行列。

在单页开发框架中,我建议使用vue 2,下图是一些关于界面渲染相关的数据对比:

Type Vue 2(单位/s) React 15(单位/s) Angular 2(单位/s)
create rows Duration for creating 1000 rows after the page loaded. 171.36 227.44 198.06
replace all rows Duration for updating all 1000 rows of the table (with 5 warmup iterations) 68.76 211.71 178.45
remove row Duration to remove a row. (with 5 warmup iterations). 64.11 49.42 19.14
partial update Time to update the text of every 10th row (with 5 warmup iterations) 22.17 14.77 11.42
ready memory Memory usage after page load 3.43 4.64 15.45

总结

研究首屏时间和资源加载是一件挺有意思的事情,大家利用好chrome控制台(特别是里面的network标签)以及fiddler可以挖掘出很多有趣的小细节小结论。别以为这是在没事找事,理解好这些对大家做首屏性能优化、定位因为js文件执行顺序错乱导致报错等场景是非常有好处的。所以发现什么记得与我共享哈~

1 赞 10 收藏 评论

永利皇宫463娱乐网址 13

Virtual DOM

首先强调一下,Virtual DOM 并没有提升首屏渲染速度,而且它还延长了首屏渲染速度,但是 Virtual DOM 提升的是视图局部更新的速度,能够依靠映射关系快速查找到真正的 dom 节点。

在Virtual DOM方案中,更新浏览器的DOM分三个步骤:

  1. 只要数据发生改变,就会重新生成一个完整的Virtual DOM
  2. 重新计算比较出新的和之前的Virtual DOM的差异
  3. 更新真实DOM中真正发生改变的部分,就像是给DOM打了个补丁

服务端渲染

稍后补全~

首屏渲染速度优化

做移动web页面,受移动网络网速和终端性能影响,我们经常要关注首屏内容展示时间(以下简称首屏时间)这个指标,它衡量着我们的页面是否能在用户耐心消磨完之前展示出来,很大程度影响着用户的使用满意度。

方案:

  1. 三秒种渲染完成首屏指标
  2. 首屏加载3秒完成或使用Loading
  3. 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB
  4. 所有影响首屏加载和渲染的代码应在处理逻辑中后置

按需加载

将不影响首屏的资源和当前屏幕资源不用的资源放到用户需要时才加载,可以大大提升重要资源的显示速度和降低总体流量
PS:按需加载会导致大量重绘,影响渲染性能

  1. LazyLoad
  2. 滚屏加载
  3. 通过Media Query加载

预加载

大型重资源页面(如游戏)可使用增加Loading的方法,资源加载完成后再显示页面。但Loading时间过长,会造成用户流失
对用户行为分析,可以在当前页加载下一页资源,提升速度

  1. 可感知Loading(如进入空间游戏的Loading)
  2. 不可感知的Loading(如提前加载下一页)

资源压缩

减少资源大小可以加快网页显示速度,所以要对HTML、CSS、JavaScript等进行代码压缩,并在服务器端设置GZip

  1. 压缩(例如,多余的空格、换行符和缩进)
  2. 启用GZip
  3. 控制图片质量(使用tinypng进行压缩)

开发建议

html注意事项

加载是并行的:

  1. 别再把 JsEndTime – JsStartTime 的结果成为js文件的加载执行时间(除非你没有外联css文件),不然会被内行人取笑滴;
  2. css文件的阻塞会影响后面js代码的执行,自然也包括html代码的执行,即是说此时你的页面就是空白的。所以css文件尽量内联,你可以让构建工具帮你忙;

执行是串行的:

  1. 无关紧要”的js不要放在负责渲染的js前面,这里的“无关紧要”是指和首屏渲染无关,如数据上报组件。我们可以选择将要上报的数据临时存起来,先继续执行渲染的js,等负责渲染的js执行完再加载上报组件再上报。甚至连zepto之类的库我们也可以放后面,把渲染相关的代码抽离出来并用原生js书写,放到最前面
  2. 可以看到,动态加载的js的执行是不会受到html后面外联的js的阻塞的影响,即是说,它的执行和后面js的执行顺序是不确定的。因此我们要小心处理好文件的依赖关系。当然还可以采用最不容易出错的方法:负责动态加载js的文件是html里面外联的最后一个文件

html使用Viewport

Viewport可以加速页面的渲染,请使用以下代码

<meta name="viewport" content="width=device-width, initial-scale=1">

减少Dom节点

Dom节点太多影响页面的渲染,应尽量减少Dom节点

减少HTTP请求

因为手机浏览器同时响应请求为4个请求(Android支持4个,iOS 5后可支持6个),所以要尽量减少页面的请求数,首次加载同时请求数不能超过4个

  1. 合并CSS、JavaScript
  2. 合并小图片,使用雪碧图

无阻塞

写在HTML头部的JavaScript(无异步),和写在HTML标签中的Style会阻塞页面的渲染,因此CSS放在页面头部并使用Link方式引入,避免在HTML标签中写Style,JavaScript放在页面尾部或使用异步方式加载

减少Cookie

Cookie会影响加载速度,所以静态资源域名不使用Cookie

避免重定向

重定向会影响加载速度,所以在服务器正确设置避免重定向

异步加载第三方资源

第三方资源不可控会影响页面的加载和显示,因此要异步加载第三方资源

脚本执行优化

  1. CSS写在头部,JavaScript写在尾部或异步
  2. 避免图片和iFrame等的空Src(空Src会重新加载当前页面,影响速度和效率)
  3. 尽量避免重设图片大小(重设图片大小是指在页面、CSS、JavaScript等中多次重置图片大小,多次重设图片大小会引发图片的多次重绘,影响性能)
  4. 图片尽量避免使用DataURL(DataURL图片没有使用图片的压缩算法文件会变大,并且要解码后再渲染,加载慢耗时长)

编辑:Web前端 本文来源:你先要知道这几点细节,端渲染优化指北

关键词:

  • 上一篇:没有了
  • 下一篇:没有了