前端优化:BigRender的textarea延迟渲染和关于LABjs的实践
郑昀 201207
前端优化三:BigRender的textarea延迟渲染
-淘宝网首页的实践-
首页的右侧栏的“全球购”、“旅行”、“拍卖”和“二手市场”四个模块,逐一被textarea所包裹。
这部分的特点是,直接把html代码放置入textarea,来做到延迟渲染:
首页最下方的“热卖单品”模块则是把ajax放入textarea,只有屏幕滚动到此处,才会触发下载数据、Append新节点和渲染,通过 kissy 的 datalazyload.js 实现:
-textarea延迟渲染原理(郑昀)-
据玉伯介绍,HTML元素中有一种RCDATA elements,含textarea和title。
RCDATA=Replaceable Character Data。
如果用隐藏的textarea来存放 html 代码,textarea 中的内容会按照 RCDATA 规则来解析:
- 遇到 & 时,会尽可能得到实体字符。
- 遇到 </textarea(\s|\\|>) 时,会结束解析。
- 其他都直接作为 textarea 的内容。
获取也非常简单:
据yiminghe介绍,对于屏幕外延迟渲染的html存放在隐藏(visibility:hidden)的 textarea 中,并且该 textarea 占据本该渲染的位置,监控窗体滚动,当textarea进入可见区域,将该 textarea 内的 value, 插入到 textarea 之前,并删除掉 textarea 。
这样,把大量不需要在首屏展示的html代码分模块放入一个一个的textarea里,大大减少了DOM节点数,
从而给浏览器合理的喘息(UI Update)时间,等首屏真正在显示器上绘制出来后,
再得到 textarea.value ,填充回 DOM 树。
textarea+datalazyload,相对于其他延迟加载异步渲染解决方案,最大好处,还是减少首屏绘制时的DOM节点总数。
引用资源:
1.玉伯(真名王保平,id@lifesinger)《淘宝详情页的 BigRender 优化与存放大块 HTML 内容的最佳方式》(需FQ)
2.BigRender所依赖的“数据延迟加载组件”datalazyload
3.yiminghe《数据延迟加载组件》
前端优化四:拉手/Yupoo等的LABjs
-背景-
LABjs=Loading And Blocking JavaScript,一种脚本载入器。
官网是 http://labjs.com/ 。
它的最大特点是能尽可能并行地下载待加载的 js ,但需要时又能保证 js 的执行顺序。
-拉手网是怎么用的-
2012年的拉手网,在head里引入了LABjs外联js:
<script src="http://s2.lashouimg.com/js/lab.min.js" type="text/javascript"></script>
还是在head里,随后引入了内联js:
var js_url = 'http://d1.lashouimg.com/';
$LAB
.script(js_url+"js/jquery-1.3.2.min.js").wait()
.script("http://d2.lashouimg.com/js/jquery.autocomplete-01-min.js").wait()
.script("http://s1.lashouimg.com/js/baseindex-14-min.js").wait(
function () { var youhui_temp = 0; if(youhui_temp) {…………} });
让我们看看它的加载顺序,虽然都是写在head里的,但jquery.js的下载可是在lab.min.js下载的一秒后,时间拉得很开:
-2011年又拍网是怎么用的-
2011年年底,Yupoo的页面底部有这样的代码:
它的 http://www.yupoo.com/js/bootstrap.js?15541000.js 里把Modernizr v1.7、LAB.js v1.2.0合并了。
现在又拍网是通过下面的代码延迟加载所需JS:
uPai.addEvent('domready', function(){
uPai.require(['global','editable','slideshow','photoview','lighteditor','phototags','map'], function(){uPai.fireEvent('ready', [uPai])});
});
效果如下所示:
(郑昀)暂时不清楚它是不是直接引入的RequireJS的require语法,从而抛弃了LABjs(参考RequireJS入门,如下图所示)。
-脚本载入器是否值得引入?-
有人认为现代浏览器已经有很多优化了,
如Chrome和Firefox近两年的版本中,都可以并行下载多个JS文件(同时下载几个取决于浏览器的并行连接数),
并不需要LABjs来控制JS如何载入。
LABjs更关注JS执行的顺序,但未必一定要用这种方式解决。
可能大家更希望的是JS的下载和执行分离能力,即预载入 JavaScript 而不执行。
根据oldj的《LABjs分析》,LABjs检测不同类型浏览器版本,使用了不同脚本加载技术,从而为人诟病,很有可能无法应付现代浏览器更新。
引用资源:
1.oldj《LABjs分析》
2.怪飞《各浏览器的并行连接数(同域名) 》
3.玉伯的知乎问答《LABjs、RequireJS、SeaJS 哪个最好用?》
4.《关于脚本载入器的思考》
——郑昀 201207