$('.J_Module').each(function(mod) {
var $mod = $(mod);
var name = $mod.attr('tms');
var data = $mod.attr('tms-data');
if($mod.hasClass('tb-pass')) {
Reporter.send({
msg: "跳过模块 " + name
});
return;
}
// 保证首屏模块先加载
if (/promo|tmall|tanx|notice|member/.test(name)) {
window.requestNextAnimationFrame(function(){
// 最后一个参数为 Force, 强制渲染, 不懒加载处理
new Loader($mod, data, /tanx/.test(name));
});
} else {
// 剩下的模块进入懒加载队列
lazyQueue.push({
$mod: $mod,
data: data,
force: /fixedtool|decorations|bubble/.test(name)
});
}
});
TMS 输出的模块都会包含一个 .J_Module 钩子,并且会预先加载 js 和 css 文件。
对于无 JS 内容的模块,会预先打上 tb-pass 的标记,初始化的时候跳过此模块;对于首屏模块关键模块,会直接进入
懒加载监控:
// $box 进入浏览器视窗后渲染
// new Loader($box, data) ->
datalazyload.addCallback($box, function() {
self.loadModule($box, data);
});
// $box 立即渲染
// new Loader($box, data, true) ->
self.loadModule($box, data);
除必须立即加载的模块外,关键模块被加到懒加载监控,原因是,部分用户进入页面就可能急速往下拖拽页面,此
时,没必要渲染这些首屏模块。
非关键模块统一送到 lazyQueue 队列,没有基于将非关键模块加入到懒加载监控,这里有两个原因:
一旦加入监控,程序滚动就需要对每个模块做计算判断,模块太多,这里可能存在性能损失
如果关键模块还没有加载好,非关键模块进入视窗就会开始渲染,这势必会影响关键模块的渲染
那么,什么时候开始加载非关键模块呢?
var __lazyLoaded = false;
function runLazyQueue() {
if(__lazyLoaded) {
return;
}
__lazyLoaded = true;
$(window).detach("mousemove scroll mousedown touchstart
touchmove keydown resize onload", runLazyQueue);
var module;
while (module = lazyQueue.shift()) {
~function(m){
// 保证在浏览器空闲时间处理 JS 程序, 保证不阻塞
window.requestNextAnimationFrame(function() {
new Loader(m.$mod, m.data, m.force);
});
}(module);
}
}
$(window).on("mousemove scroll mousedown
touchstart touchmove keydown resize onload", runLazyQueue);
// 担心未触发 onload 事件, 5s 之后执行懒加载队列
window.requestNextAnimationFrame(function() {
runLazyQueue();
}, 5E3);