您的位置:首页 > 其它

关于淘宝的BigRender详解以及提高首屏加载速度的方法

2016-07-18 00:00 197 查看
摘要: 关于淘宝的BigRender详解以及提高首屏加载速度的方法

在pc的网页中,打开网站,能够迅速的给用户展现出来页面的东西,是非常重要的。而对于复杂的页面,如何让用户所关注的内容迅速的展现出来,这里大致有两种方式。

1、淘宝详情页采用的是BigRender 的方式。这种的优化主要在浏览器端。我们都知道,当页面下载完毕后我们经过tokenizatoin-Tree Construction-Rendering。所以要让首屏的内容尽快的展现出来,我们需要给浏览器更少的工作量。这里往往有两种方式:

1):减少DOM节点数。节点数越少,浏览器的Rendering耗费的时间就更少。

2):减少脚本执行的时间。脚本执行和 UI Update 共享一个 thread, 脚本耗的时间越少,UI Update 就能越发提前

2、Facebook的BagPipe方式。先输出页面的整体布局,然后再输出脚本块,一边输出一遍渲染,将页面渲染回原来的布局中。这样可以让服务端的运算、网络传输和浏览器端的渲染变成并行。BigPipe 最主要解决的问题是服务端的运算时间,当服务端的运算时间大于 300 ~ 500ms 时才能体现出优势。当服务端响应非常快(小于 100ms),BigPipe 退化为上面讲的 BigRender.

减少DOM的节点数:

对于BigRender来说,减少DOM的节点数有两个方法。

和 Facebook 的 BigPipe 一样,调整页面代码为 页面布局 + 脚本块。BigPipe 是服务器 chunked 输出 html 内容,BigRender 是服务器一次性输出,其他都是一样的。

尽量少调整页面代码,但通过某种方式,将首屏不需要的 html 代码先存放起来。渲染好首屏后,再将存储好的 html 代码逐步渲染出来。

用JS存放HTML代码

facebook就是这么的一个做法

在<script> 标签中添加html代码,但是这种方法对于BigRender来说并不是特别的好

由于代码是存放在html中的字符串变量中的,所以对于单引号和双引号需要转义

由于 script 是内嵌的,需要对 script ETAGO 转义。

服务器端需要将 html 代码转化为一行。(也可以不转成一行,用续行符来做。)

当 html 代码中含有 script 时,需要先去除 script 中的单行注释,否则转化成一行时,会出问题

但是,这样做,当时优点也是非常大的:比如大幅度的减少了首屏渲染的时间。尽量不改变原有的开发习惯并且用非常少的代码完成了很大的优化。

用注释来存放代码

为了便于获取注释内容,添加一层包裹:

<div id="comment-data"><!--

html code

--></div>

用这种方式来获取内容

var htmlCode = document.getElementById(“comment-data”).childNodes[0].nodeValue;

但是缺点是:

服务端,html 中的
-->
要替换为某种特殊标记。(不能简单转义为
-->


服务端,html 中的
--
也要替换为某种特殊标记。否则在 Firefox 低版本中存在 bug.

浏览器端,得到 htmlCode 后,要将上面的特殊标记替换回原值。

而且的那个注视里的东西太多的时候,这种方法的效率并不是忒高效。

用 textarea 来存放 html 代码

extarea 中的内容会按照 RCDATA 规则来解析:

遇到 & 时,会尽可能得到实体字符。

遇到 </textarea(\s|\\|>) 时,会结束解析。

其他都直接作为 textarea 的内容。

<textarea id="area-data">

<p>some text</p>

</textarea>

获取也是非常的简单:

var htmlCode = document.getElementById(“area-data”).value;


但是缺点就是:

服务端要讲html中的&转换成&

服务端要打破ETAGO

在时候我们再回到首屏渲染的问题上来说

可以根据实际情况,将页面划分成几大区域。非首屏区域,简单转义后,直接用 textarea 包裹起来。这样,DOM 数立刻就减少了。浏览器在拿到 html 代码时,首次 Tokenization — Tree Construction 的速度就会大大加快

完整的优化,还需要:

给浏览器合理的喘息(UI Update)时间,等首屏真正在显示器上绘制出来后,再进行下一步操作。

得到 textarea.value, 填充回 DOM 树时,得妥善处理内嵌的 script 代码。

对内嵌 script 代码中的 document.write 要妥善处理。

通过 textarea 回填,里面的非 defer 和 async 脚本会从同步变成异步。要妥善处理依赖关系,不破坏原有脚本逻辑。

对于优化项目来说,完备的测试和监控非常重要。

这次还做了 AssetsTransfer. 用户第一次访问时,会将首屏相关的脚本和样式内嵌,并做预加载。用户再次访问时,则改成外链方式,这样能充分利用浏览器缓存,并减少 html 传输量

当然!现在对于这种填充,angular都有了指令,我想h5也应该有所行动的,所以我觉得接下来应该研究下webComponents

的玩法了~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息