侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

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

2024-05-08 星期三 / 0 评论 / 0 点赞 / 52 阅读 / 5988 字

在pc的网页中,打开网站,能够迅速的给用户展现出来页面的东西,是非常重要的。而对于复杂的页面,如何让用户所关注的内容迅速的展现出来,这里大致有两种方式。 1、淘宝详情页采用的是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的节点数有两个方法。

  1. 和 Facebook 的 BigPipe 一样,调整页面代码为 页面布局 + 脚本块。BigPipe 是服务器 chunked 输出 html 内容,BigRender 是服务器一次性输出,其他都是一样的。
  2. 尽量少调整页面代码,但通过某种方式,将首屏不需要的 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;

但是缺点是:

  1. 服务端,html 中的 --> 要替换为某种特殊标记。(不能简单转义为 --&gt;
  2. 服务端,html 中的 -- 也要替换为某种特殊标记。否则在 Firefox 低版本中存在 bug.
  3. 浏览器端,得到 htmlCode 后,要将上面的特殊标记替换回原值。

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

 

用 textarea 来存放 html 代码

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

  1. 遇到 & 时,会尽可能得到实体字符。
  2. 遇到 </textarea(/s|//|>) 时,会结束解析。
  3. 其他都直接作为 textarea 的内容。
<textarea id="area-data"><p>some text</p></textarea>

获取也是非常的简单:

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

 

但是缺点就是:

  • 服务端要讲html中的&转换成&amp
  • 服务端要打破ETAGO

 

 

 

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

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

 

 

完整的优化,还需要:

  1. 给浏览器合理的喘息(UI Update)时间,等首屏真正在显示器上绘制出来后,再进行下一步操作。
  2. 得到 textarea.value, 填充回 DOM 树时,得妥善处理内嵌的 script 代码。
  3. 对内嵌 script 代码中的 document.write 要妥善处理。
  4. 通过 textarea 回填,里面的非 defer 和 async 脚本会从同步变成异步。要妥善处理依赖关系,不破坏原有脚本逻辑。
  5. 对于优化项目来说,完备的测试和监控非常重要。
  6. 这次还做了 AssetsTransfer. 用户第一次访问时,会将首屏相关的脚本和样式内嵌,并做预加载。用户再次访问时,则改成外链方式,这样能充分利用浏览器缓存,并减少 html 传输量

 

 

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

的玩法了~

广告 广告

评论区