无线性能优化,页面白屏与瀑布流分析方法永利澳门游戏网址304:

页面白屏与瀑布流深入分析方法

2015/12/03 · HTML5,
JavaScript · 1
评论 ·
瀑布流,
白屏

原来的书文出处: Taobao前端团队(FED)-
妙净   

永利澳门游戏网址304 1

有线页面包车型客车支付在我们的家常专门的职业中至关心重视大,有线的性情也是我们供给入眼关切的,而加载的属性又是有线性能中的叁个尤为重要难点。那么,前日大家一道来看下如何去评估、测量检验有线页面包车型大巴加载品质。

为了便利深入分析页面包车型地铁加载进程,这里将网络设置成最慢的
GP途胜S,并将加载进程录像下来,平日你可以因此 Chrome 自带的 timeline, 勾选
screenhot,能够赢得详尽的进程,如下图:

永利澳门游戏网址304 2

此处为了和乞请一一清晰对照,用额外录屏工具( licecap
)摄像下来。下文以Tmall双 11 男装分开会地点的预发页面作为测验,录像 结果
gif
如下,录制的 FPS 为 8。

帧解析如下:

首先帧:重新刷新页面,发起 HTML 需要,中间完整页面是刷新前的,请无视之。

永利澳门游戏网址304 3

终于等到第 7 帧,HTML 加载并深入分析完结,发出页面中的诉求,同一时候 CSS/JS
的地方都消失在 //g.alicdn.com 同二个域名下, Chrome 下 HTTP 1.1
公约下贰个域名下援救 6 个冒出。

1 年前,PC 上在此之前还应该有多个域名分区(img01-04.tbcdn.cn),PC
上首屏图片多,那样可并发愈来愈多,但更加多的域名引进,也加大了域名深入分析的资产,权衡之下Taobao此前图片域名选用了
4 个;后来公司透过如火如荼的 HTTPS 更改,图片推荐收敛到 gw.alicdn.com
;手淘下以后使用 SPDY + HTTPS,相比 HTTP 1.1 ,更安全且可以多路复用。

永利澳门游戏网址304 4

到第 20 帧, CSS 下载完,DOM 和
CSSOM
都计划 OK 了,页面则开端渲染了;那是在 Chrome 上面见到的气象,但在 iOS
上并不是那样,它须要 JS 加载并实践完才渲染页面。

永利澳门游戏网址304 5

第 21 帧,紧接着,CSS 中的背景图伊始相继渲染,可知 CSS
中渲染图片也可以有一点点耗费时间的。

永利澳门游戏网址304 6

第 23 帧,前面并行下载的 JS 都下载完,也初叶试行了,看“疯狂 top 榜”是 JS
收抽出来的。同有的时候候 aplus 乞请也开头央求,那是个 getScript
的异步央求,可知异步央求真未有阻塞页面包车型客车渲染。

永利澳门游戏网址304 7

第 25 帧,JS 还在继续奉行,第一张图纸是 JS 遵照当下
dpr、强弱网络、设备宽度等算出最符合的图形开端加载那张大 banner
了,何况先导发送数据须要了。

永利澳门游戏网址304 8

到 27 帧,终于数据诉求回来了,并且把文字和图片渲染到页面上了。

永利澳门游戏网址304 9

然后下一帧 28,开头央浼商品图片了。

永利澳门游戏网址304 10

到 45 帧,6 个图片都在出现央浼,同上 gw.alicdn.com 同二个域下并发 6
个央求。但首屏除了大图外唯有 4 张图(2 张商家 logo 被底部 bar
挡住了),这里发出了 6 个图片必要,可知那些页面包车型地铁懒加载的 buffer
值能够安装得越来越小。

永利澳门游戏网址304 11

从 28 帧到 50 帧,经历了不短的时刻,第一张图片终于展现出来了。其余见到aplus_v2 实践完后,又发起了 spm 等乞求,后边 3 个须要(
aplus-proxy.html/isproxy.js/m.gif )仍然串行的。

永利澳门游戏网址304 12

最终到第 61 帧,终于有所的图纸都加载完了,最终看下,最后下载完的是大
banner 图,因为有 46.9k ,那张图的尺寸或许形成此页面包车型地铁 load
时间的要紧;假诺那张图未有如此大,最终下载完的大概是用于埋点的 m.gif。

永利澳门游戏网址304 13

从地点整个央浼的瀑布流深入分析下来,大家来回看下页面包车型地铁机要时间点:

原稿出处: 天猫前端共青团和少先队(FED)-
妙净   

页面可知时间

在第 20 帧页面可知,CSS 完结之后,当然前提是此处未有外链 JS
在页面中间因为互联网伏乞严重阻塞页面。这里剖析的独自是 Chrome
浏览器,不是真机,在 iOS 上,固然 JS 在尾部,间接 <script src=”xx”> 也是会堵塞页面。能够透过加
async 属性,文告渲染引擎那是不影响页面渲染的 JS,能够异步加载,iOS
下增添此属性可完毕和 Android 或 PC Chrome 一样的效果与利益。

永利澳门游戏网址304 14

首要内容可知时间

重大内容可知,这里能够以为是货品数量,商品数量可知要等 JS
试行完何况异步哀告发送出去回来后才可知。

TMS[1]
的异步须求相当多走招引顾客数据平台(TCE[2])的接口,测量检验其单个诉求在真机的耗费时间约为
110ms(样本少之甚少,未多量测量检验)。

怎么让页面尽也许早地渲染页面,页面更早可知,让白屏时间越来越短,特别是有线蒙受下,一贯是性质优化的话题。

白屏时间和补救措施

在 Wi-Fi 下,那 60
多帧的进程一眨眼就过去了,但在弱网络下,如这里最极致的网络 GPKugaS
下,整个首屏含图片全部加载成功供给 41.25s。当然那 40
多秒进程能尽快出现内容,并渐进协调地展现出来是相比好的。

男装频道是修改过后的,相比较在此以前的未管理的猜你兴奋页面,出现长日子的白屏,如下:

永利澳门游戏网址304 15

以下为地目生活修复后的作用:

永利澳门游戏网址304 16

白屏管理只要稍微注意下就可以,修复的有益也简要,尽量同步输出,异步输出请尽量
mock 出现在首屏的模版。假诺是依照 Cake[3]
工具开垦的,也能够直接用首屏填充伪标签。

页面可知时间

页面可见要经历以下进程:

  • 解析 HTML 为 DOM,解析 CSS 为 CSSOM(CSS Object Model)
  • 将 DOM 和 CSSOM 合成一棵渲染树(render
    tree)
  • 达成渲染树的布局(layout)
  • 将渲染树绘制到显示器

永利澳门游戏网址304 17

layout

永利澳门游戏网址304 18

出于 JS 也许每30日会转移 DOMCSSOM,当页面中有恢宏的 JS
想及时实践时,浏览器下载并试行,直到完结 CSSOM
下载与构建,而在我们拭目以待时,DOM 创设同样被封堵。为了 JS 不阻塞 DOM 和
CSSDOM 的构建,不影响首屏可知的时间,测量试验二种 JS
加载攻略对页面可知的影响:

结束语

如上在 Chrome 上的测量检验,但实则在手淘里面,在
spdy、https、离线包内置能源等的影响下,它的瀑布流依旧那样的啊?

三种异步加载格局测量试验

  • A. head script: 即普通的将 JS 放在 head 中或放在 body
    中间:DEMO 地址
  • B. bottom script: 即常规的优化战略,JS 放body的底部:DEMO
    地址
  • C. document.write: 之前 PC 优化少用的一种异步加载 JS 的宗旨:DEMO
    地址
JavaScript

function injectWrite(src){ document.write('&lt;script src="' + src +
'"&gt;&lt;/sc' + 'ript&gt;'); }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a721bbc827ff070447677-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a721bbc827ff070447677-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a721bbc827ff070447677-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a721bbc827ff070447677-1" class="crayon-line">
function injectWrite(src){
</div>
<div id="crayon-5a721bbc827ff070447677-2" class="crayon-line crayon-striped-line">
  document.write('&lt;script src=&quot;' + src + '&quot;&gt;&lt;/sc' + 'ript&gt;');
</div>
<div id="crayon-5a721bbc827ff070447677-3" class="crayon-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>
  • D. getScript: 形如以下,也是 KISSY
    内部的getScript函数的简短完成:DEMO
    地址
JavaScript

&lt;script&gt; var script = document.createElement('script');
script.src = "//g.tbcdn.com/xx.js";
document.getElementsByTagName('head')[0].appendChild(script);
&lt;/script&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a721bbc82807359027480-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a721bbc82807359027480-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a721bbc82807359027480-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a721bbc82807359027480-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a721bbc82807359027480-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a721bbc82807359027480-1" class="crayon-line">
&lt;script&gt;
</div>
<div id="crayon-5a721bbc82807359027480-2" class="crayon-line crayon-striped-line">
  var script = document.createElement('script');
</div>
<div id="crayon-5a721bbc82807359027480-3" class="crayon-line">
  script.src = &quot;//g.tbcdn.com/xx.js&quot;;
</div>
<div id="crayon-5a721bbc82807359027480-4" class="crayon-line crayon-striped-line">
  document.getElementsByTagName('head')[0].appendChild(script);
</div>
<div id="crayon-5a721bbc82807359027480-5" class="crayon-line">
&lt;/script&gt;
</div>
</div></td>
</tr>
</tbody>
</table>
  • E. 加 async 属性:DEMO
    地址
  • F. 加 defer 属性:DEMO
    地址
  • G. 同时加 async defer 属性:DEMO
    地址

注:

  • [1]: TMS 为天猫商城内部运营移动系统。
  • [2]: TCE 为Taobao内部数据接口系统。
  • [3]: Cake 为天猫内部前端开拓套件。

 

1 赞 收藏 1
评论

永利澳门游戏网址304 19

测量检验结果

以下提到的 domReadyDOMContentLoaded 事件。

A (head script) B (bottom script) C (document.write) D (getScript) E (async) F (defer) G (async + defer)
1 PC Chrome 页面白屏长、domReady:5902.545、onLoad:5931.48 页面先显示、domReady:5805.21、onLoad:5838.255 页面先显示、domReady:5917.95、onLoad:5949.30 页面先显示、domReady:244.41、onLoad:5857.645 页面先显示、domReady:567.01、onLoad:5709.33 页面先显示、domReady:5812.12、onLoad:5845.6 页面先显示、domReady:576.12、onLoad:5743.79
2 iOS Safari 页面白屏长、domReady:6130、onLoad:6268.41 页面白屏长、domReady:5175.80、onLoad:5182.75 页面白屏长、domReady:5617.645、onLoad:5622.115 502s 白屏然后页面显示最后变更 load finish 时间、domReady:502.71、onLoad:6032.95 508s 白屏然后页面显示最后变更 load finish time domReady:508.95、onLoad:5538.135 页面白屏长、domReady:5178.98、onLoad:5193.58 556s 白屏然后页面显示最后变更 load finish 时间、domReady:556、onLoad:5171.95
3 iOS 手淘 WebView 页面白屏长、页面出现 loading 消失、domReady: 5291.29、onLoad:5292.78 页面白屏长、页面未跳转 loading 消失、domReady: 5123.46、onLoad:5127.85 页面白屏长、页面未跳转 loading 消失、domReady: 5074.86、onLoad:5079.875 页面可见快、loading 消失快在 domReady 稍后、domReady:14.06、load finish:5141.735 页面可见快、loading 消失快在 domReady 稍后、domReady:13.89、load finish:5157.15 页面白屏长、loading 先消失再出现页面、domReady: 5132.395、onLoad:5137.52 页面可见快、然后 loading 消失、domReady:13.49、load finish:5124.08
4 Android browser 页面白屏长、domReady: 5097.29、onLoad:5100.37 页面白屏长、domReady: 5177.48、onLoad:5193.66 页面白屏长、domReady: 5125.96、onLoad:5165.06 页面可见快、等 5s 后更新 load finish 时间 domReady:463.33、load finish:5092.90 页面可见快、等 5s 后更新 load finish 时间 domReady:39.34、load finish:5136.55 页面白屏长、domReady: 5092.45、onLoad:5119.81 页面可见快、等 5s 后更新 load finish 时间 domReady:50.49、load finish:5507.668
5 Android 手淘 WebView 白屏时间长、一直 loading 直接页面可见、domReady:5058.91、onLoad:5073.81 页面立即可见、loading 消失快、等 5s 后更新 domReady 时间和 load 时间 domReady:4176.34、onLoad:4209.50 页面立即可见、loading 消失快、domReady:6011.18、onLoad:6031.93 页面可见快、loading 之后消失、等 5s 后更新 load finish 时间 domReady:36.31、load finish:5081.76 页面可见快、loading 随后消失、等 5s 后更新 load finish 时间 domReady:25.11、load finish:5113.81 页面可见快、loading 随后消失、等 5s 后更新 domReady 时间和 load 时间 domReady:5213.11、load finish:5312.19 页面可见快、loading 随后消失、等 5s 后更新 load finish 时间 domReady:89.67、load finish:5589.95

从以上测验结果能够看见以下结论:

  • 横向看, iOS Safari 和 Android browser
    的在页面可知、domReady、onLoad 的年月表现一致。
  • 纵向看,bottom script、document.write 和 defer 三列,可见document.write 和 defer 无别的异步效果,可见时间、domReady、onLoad
    的触及时间和 bottom script 的图景亦然。
  • 纵向看,async + defer 联合用和 async 的表现一致,故合併为 async。
  • 纵向看,script 放页头(head script)和 script 放 body 尾巴部分(bottom
    script)。iOS Safari 、Android browser 和 iOS WebView 表现一致,就算script 放在 body 的底层也无济于事,页面白屏时间长,要等到 domReady
    5s 多后告竣才显得页面;唯独 Android WebView 的表现和 PC 的 Chrome
    一致。
  • 单独看手淘 WebView 容器中 loading 消失的日子,那几个时间点 iOS 和
    Android 的显现一样,即都以在 UIWebView 的 didFinishLoad
    事件触发时消失。那么些事件的触及可能在 domReady
    从前(如:A3、B3),也说不定在 domReady
    之后(如:D3、E3);那个事件触发和 JS 中的 onLoad
    触发时机也从没一定的维系,大概在 onLoad 以前(如:D3、E3)也说不定在
    onLoad 差十分少与此同不经常常候(如:A5)。 didiFinishLoad
    到底是怎么样机缘触发的吗,详见下章。
  • 页面可知时间,getScript 形式和 async 格局页面可知都不行快,domReady
    的大运接触得也非常的慢,顾客端的 loading 在 domReady
    稍后即未有。原因是因为提起底耗费时间的 JS
    要求异步化了,未有阻塞浏览器的
    DOM + CSSOM 营造,页面渲染实现就立刻可知了。全体看,如果 domReady
    的岁月快,则页面可见快;反之假诺页面可知快,domReady
    的时辰不断定快,如 B5、B1、C1、C5、F1、F5。假设异步化耗费时间间长度的
    JS,domReady 和 onLoad 的时日差别是不小的,不做别的处理 onLoad
    的日子 domReady 的日子差 30ms 左右。所以在异步化的前提下,可以用
    domReady 的时光作为页面可知的时光。

didFinishLoad 到底何时接触

didFinishLoad 是 native 定义的风云,该事件触发时手淘 loading
黄华消失,而且 windvane 中的发出恳求不再搜聚,也正是 native 计算出的
pageLoad 时间。在客商数量平台来看的瀑布流央求,便是在 didFinishLoad
触发前搜集到的有所央浼。

永利澳门游戏网址304 20

通过上方测量试验,客户端的 didFinisheLoad 事件的触及和 JS 中的
domReady(DOMContentLoaded)和 onLoad 触发未有其他关系。可能在 domReady
此前或之后,也大概在 onLoad 此前或未来。

那它到底是何许时候接触呢? iOS
官方文书档案
是 Sent after a web view finishes loading a frame。
结合搜罗的顾客央求和测验,didFinishLoad
是在连接发起的央浼甘休未来触发,监听一段时间内无诉求则触发。

于是平日探问到 data_sufei 那个 JS
文件,在有一点客户的瀑布流里面有,在某些顾客的又未有。原因是以此 JS 是
aplus_wap.js 故意 setTimeout 1s 后发出的,如果页面在 1s
前持有的须要都发完了则触发 didFinishLoad,前边的 data_sufei.js
的岁月就不算到 pageLoad 的小时;反之假如类似 1s
页面还会有图片等央浼还在发,则 data_sufei.js 的日子也会被算到里面。

据此在 JS 中用 setTimeout 来拖延发送诉求也可能有望会影响 didFinishLoad
的年月,建议 set提姆eout 的年月设置得越来越长一些,如 3s。

发表评论

电子邮件地址不会被公开。 必填项已用*标注