龙电竞官网白屏问题和FOUC

2019-11-30 23:24栏目:龙电竞官网
TAG:

页面白屏与瀑布流解析方法

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

原稿出处: Taobao前端团队(FED)- 妙净   

龙电竞官网 1

有线页面包车型地铁开辟在我们的经常性工作中越发主要,有线的性质也是大家必要珍视关切的,而加载的习性又是有线性能中的三个要害难题。那么,前几日我们一同来看下怎么着去评估、测验有线页面的加载质量。

为了有帮忙解析页面的加载进程,这里将网络设置成最慢的 GP宝马X5S,并将加载进度摄像下来,平日你能够经过 Chrome 自带的 timeline, 勾选 screenhot,可以得到详尽的经过,如下图:

龙电竞官网 2

此地为了和伸手豆蔻梢头一清晰对照,用额外录屏工具( licecap )摄像下来。下文以Taobao双 11 男装分开会地点的预发页面作为测量检验,录像 结果 gif 如下,录制的 FPS 为 8。

帧解析如下:

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

龙电竞官网 3

好不轻巧等到第 7 帧,HTML 加载并解析完结,发出页面中的央求,同时 CSS/JS 的地点都杳无音信在 //g.alicdn.com 同一个域名下, Chrome 下 HTTP 1.1 左券下一个域名下协助 6 个冒出。

1 年前,PC 上从前还大概有几个域名分区(img01-04.tbcdn.cn),PC 上首屏图片多,那样可并发越多,但越多的域名引进,也加大了域名分析的工本,衡量之下天猫以前图片域名选用了 4 个;后来公司透过繁荣昌盛的 HTTPS 改正,图片推荐收敛到 gw.alicdn.com ;手淘下今后利用 SPDY + HTTPS,比较 HTTP 1.1 ,更安全且可以多路复用。

龙电竞官网 4

到第 20 帧, CSS 下载完,DOM 和 CSSOM 都策画 OK 了,页面则开头渲染了;这是在 Chrome 上面看看的处境,但在 iOS 上并不是那样,它必要 JS 加载并实行完才渲染页面。

龙电竞官网 5

第 21 帧,紧接着,CSS 中的背景图发轫逐项渲染,可以知道 CSS 中渲染图片也可以有一点点耗费时间的。

龙电竞官网 6

第 23 帧,前面并行下载的 JS 都下载完,也起头实施了,看“疯狂 top 榜”是 JS 收抽出来的。同时 aplus 乞请也初步要求,那是个 getScript 的异步乞请,可以看到异步乞求真未有拥塞页面包车型客车渲染。

龙电竞官网 7

第 25 帧,JS 还在继续奉行,第一张图纸是 JS 依据当下 dpr、强弱互连网、设备宽度等算出最切合的图纸起始加载那张大 banner 了,而且起首发送数据诉求了。

龙电竞官网 8

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

龙电竞官网 9

然后下生机勃勃帧 28,开首央求商品图片了。

龙电竞官网 10

到 45 帧,6 个图片都在产出央浼,同上 gw.alicdn.com 同一个域下并发 6 个伏乞。但首屏除了大图外独有 4 张图(2 张商家 logo 被后面部分 bar 挡住了),这里发出了 6 个图片央浼,可以看到这些页面的懒加载的 buffer 值能够设置得更加小。

龙电竞官网 11

从 28 帧到 50 帧,经历了相当长的时刻,第一张图纸终于展现出来了。此外看见aplus_v2 执行完后,又发起了 spm 等央浼,前边 3 个央求( aplus-proxy.html/isproxy.js/m.gif )依旧串行的。

龙电竞官网 12

最后到第 61 帧,终于有所的图纸都加载完了,最终看下,最终下载完的是大 banner 图,因为有 46.9k ,那张图的分寸可能变为此页面包车型客车 load 时间的基本点;假如那张图没有那样大,最终下载完的或然是用来埋点的 m.gif。

龙电竞官网 13

从地点整个央浼的瀑布流解析下来,大家来回想下页面包车型大巴要害时刻点:

初藳出处: 天猫商城前端共青团和少先队(FED)- 妙净   

白屏难点

  1. 白屏的根本原因是浏览器在渲染的时候未有央浼到或央求时间过长产生的。
  2. 浏览器对于图片和CSS,在加载时会并发加载(例如二个域名下同期加载多少个公文),浏览器对于JavaScript,在加载时会禁止使用并发,並且阻止其后的公文及构件的下载。所以将js放在页面包车型客车顶部也可能有可能会诱致白屏。
  3. 现在比不上过去浏览器的拍卖CSS和HTML的办法是莫衷一是的:
    诸如,IE、chrome浏览器的渲染机制,接受的是等CSS全体加载拆解解析完后再渲染体现页面。
    Firefox则是在CSS未加载前先出示html的内容,等CSS加载后再度对体制实行改革。

故而:白屏的面世情状屡次因为CSS样式被放置后面部分(最终加载),当新窗口打开,刷新等的时候,页面会并发白屏。
若果利用 @import标签,它援用的文件则会等页面全部下载完毕再被加载,也大概出现白屏。

因此,
css使用 link 标签将样式表放在最上端,制止白屏难题应际而生。
JS 的停放地点平日是在body的关闭标签此前。

页面可见时间

在第 20 帧页面可以预知,CSS 完结之后,当然前提是此处未有外链 JS 在页面中间因为网络央求严重梗塞页面。这里深入分析的只有是 Chrome 浏览器,不是真机,在 iOS 上,就算 JS 在底部,直接 <script src="xx"> 也是会卡住页面。能够透过加 async 属性,文告渲染引擎那是不影响页面渲染的 JS,可以异步加载,iOS 下加多此属性可完结和 Android 或 PC Chrome 相通的效果与利益。

龙电竞官网 14

白屏不是bug,而是由于浏览器的渲染机制。

第大器晚成内容可以知道时间

根本内容可以看到,这里能够以为是货品数量,商品数量可以见到要等 JS 施行完而且异步央浼发送出去回来后才可以知道。

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

哪些让页面尽大概早地渲染页面,页面更早可知,让白屏时间更加短,特别是有线情状下,一直是性质优化的话题。

FOUC

FOUC (Flash of Unstyled Content卡塔尔 无样式内容闪烁:
假若把体制放在底部,对于IE浏览器,在一些场景下(点击链接,输入U智跑L,使用书签步入等卡塔尔国,会油但是生FOUC 现象(稳步加载无样式的原委,等CSS加载后页面才恍然表现出样式卡塔尔。对于 Firefox 会一向展现出 FOUC 。

  • 脚本会堵塞后边内容的变现
  • 脚本会窒碍其后组件的下载

对此图片和CSS, 在加载时会并发加载(如三个域归于同一时间加载五个文本卡塔尔(英语:State of Qatar)。但在加载 JavaScript 时,会禁止使用并发,况兼阻止其余内容的下载。

因而尽也许把 JavaScript 放入页面body底部。

白屏时间和补救措施

在 Wi-Fi 下,那 60 多帧的经过黄金年代眨眼就过去了,但在弱网络下,如这里最极端的网络 GPEvoqueS 下,整个首屏含图片全体加载成功需求 41.25s。当然那 40 多秒进程能及早现身内容,并渐进协调地表现出来是相比好的。

男装频道是改进过后的,相比以前的未管理的猜你心爱页面,现身长日子的白屏,如下:

龙电竞官网 15

以下为本土生活修复后的效果:

龙电竞官网 16

白屏管理只要微微注意下就足以,修复的惠及也大概,尽量同步输出,异步输出请尽量 mock 现身在首屏的沙盘模拟经营。若是是依靠 Cake[3] 工具开荒的,也得以一向用首屏填充伪标签。

页面可以知道时间

页面可以知道要经验以下进度:

  • 解析 HTML 为 DOM,解析 CSS 为 CSSOM(CSS Object Model)
  • 将 DOM 和 CSSOM 合成意气风发棵渲染树(render tree)
  • 完了渲染树的构造(layout)
  • 将渲染树绘制到显示屏

龙电竞官网 17

layout

龙电竞官网 18

由于 JS 也许随即会变动 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 地址

版权声明:本文由龙竞技官网发布于龙电竞官网,转载请注明出处:龙电竞官网白屏问题和FOUC