关于淘宝的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 中的单行注释,否则转化成一行时,会出问题
但是,这样做,当时优点也是非常大的:比如大幅度的减少了首屏渲染的时间。尽量不改变原有的开发习惯并且用非常少的代码完成了很大的优化。
用注释来存放代码
为了便于获取注释内容,添加一层包裹:
用这种方式来获取内容
但是缺点是:
服务端,html 中的
服务端,html 中的
浏览器端,得到 htmlCode 后,要将上面的特殊标记替换回原值。
而且的那个注视里的东西太多的时候,这种方法的效率并不是忒高效。
用 textarea 来存放 html 代码
extarea 中的内容会按照 RCDATA 规则来解析:
遇到 & 时,会尽可能得到实体字符。
遇到 </textarea(\s|\\|>) 时,会结束解析。
其他都直接作为 textarea 的内容。
获取也是非常的简单:
但是缺点就是:
服务端要讲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
的玩法了~
在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
的玩法了~
相关文章推荐
- MyBatis的flushCache和useCache的使用注意
- textbox设置样式为空背景色透明
- 手动提交代替asp.net的button控件提交
- maven spope
- Go做复杂的单向链表
- 实现自己的控制层do-c (仿Struts2和SpringMVC)(七)
- JS延时执行函数
- DOCKER端口映射错误
- kilo版云主机无法终止,无法创建
- Java类加载机制的理解
- 云硬盘一直处于deleting状态
- 上传的镜像无法用来启动云主机
- 【Tomcat】get,put,post,delete含义与区别
- 短网址的简单实现
- 短网址的原理和实现
- linux学习--未整理命令
- CentOS7安装PHP5.6.23
- CentOS 7.0系统安装配置图解教程
- CentOS 7系统上yum搭建LAMP(超详细版)
- centos 7 中防火墙的关闭问题