Scripts without async or defer attributes, as well as inline scripts, are fetched and executed immediately, before the browser continues to parse the page.
默认情况下,页面中的JS脚本会阻塞DOM渲染,并且是根据它们出现在文档中的顺序来先后执行的,但是近日发现一种先执行后定义的处理方法:
(function(para) {
var p = para.sdk_url, n = para.name, w = window, d = document, s = 'script',x = null,y = null;
w['sensorsDataAnalytic201505'] = n;
w[n] = w[n] || function(a) {return function() {(w[n]._q = w[n]._q || []).push([a, arguments]);}};
var ifs = ['track','quick','register','registerPage','registerOnce','clearAllRegister','trackSignup', 'trackAbtest', 'setProfile','setOnceProfile','appendProfile', 'incrementProfile', 'deleteProfile', 'unsetProfile', 'identify','login','logout','trackLink','clearAllRegister'];
for (var i = 0; i < ifs.length; i++) {
w[n][ifs[i]] = w[n].call(null, ifs[i]);
}
if (!w[n]._t) {
x = d.createElement(s), y = d.getElementsByTagName(s)[0];
x.async = 1;
x.src = p;
y.parentNode.insertBefore(x, y);
w[n].para = para;
}
})({
sdk_url: '在 github 下载新版本的 sensorsdata.min.js ',
name: 'sa',
server_url:'数据接收地址'
});
sa.quick('autoTrack'); //神策系统必须是1.4最新版及以上
上面的代码把要执行的函数名和参数存储起来,随后异步加载SDK文件,当SDK文件加载完成后,利用配置的全局变量和其中存储的执行数据,传入真正的方法中执行。
代码解析:
1. 配置参数
sdk_url: 定义了真正可执行代码的远程JS代码地址
name: 当前页面的全局变量,防止变量名冲突,例子中使用了sa
2. 执行过程
sensorsDataAnalytic201505:本地定义的全局变量名和远程JSSDK中变量沟通的桥梁
将name定义为window中的对象,赋值为一个柯里化的函数
ifs声明了远程SDK中可调用的函数名, 通过上面的柯里化函数依次定义了相关函数出来
最后执行SDK异步加载(async)
3. 本地无需等待SDK加载,立即调用需要执行的函数,各函数执行的代码雷同,都是接收可变的参数,将它们拼接作为一个数组[a, arguments],然后append到window[name]._q的property中
sa.function1('param1_1', 'param1_2');
sa.function2('param2_1', 'param2_2');
执行之后,sa._q就会是以下赋值
[
[function1,'param1_1', 'param1_2']
[function2,'param2_1', 'param2_2']
]
前提是function1,function2在ifs定义的函数名数组中
网友评论