JS/CSS module LazyLoad 之一

随着web app中JS越来越多,有时页面首次加载时有很多JS并没有用到。这时为了提高下载速度,提高页面渲染效率就需要让这部分暂时不用的JS延迟加载,即只在用到它们的时候再下载。这里会先实现一个最简单JS的惰性加载。后续几篇会逐步加强功能直至一个完整的JS/CSS模块加载库。这个系列里我不会实现队列,即各个JS文件是并行下载的,只有当多个JS全部下载后才执行回调。当然在第二个系列JS Queue LazyLoad中会实现各个JS文件顺序加载,每个JS文件下载后都有一次回调机会。这两种方式有各自的应用场景。


先给出使用接口

1
2
3
4
5
LazyLoad.js(
    urls  // js文件路径
    fn    // 全部加载后回调函数
    scope // 指定回调函数执行上下文
);

示例

1
2
3
LazyLoad.js(['a.js','b.js','c.js'], function(){
    alert('加载完毕');
});

Firebug中效果如下,a,b,c三个文件几乎是同一时间开始下载的。


这个系统会尽全力去加载所有的JS文件,即当某个文件不存在或加载失败它不会就此中断,仍然会去加载其它的JS文件。直到所有的模块都加载了一次才去回调。


完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
LazyLoad = function(win){  
    var list,
        isIE = /*@cc_on!@*/!1,
        doc = win.document,
        head = doc.getElementsByTagName('head')[0];
 
    function createEl(type, attrs){
        var el = doc.createElement(type),
            attr;
        for(attr in attrs){
            el.setAttribute(attr, attrs[attr]);
        }
        return el;
    }
    function finish(obj){
        list.shift();
        if(!list.length){
            obj.fn.call(obj.scope);
        }
    }
    function js(urls, fn, scope){
        list = [].concat(urls);
        var obj = {scope:scope||win, fn:fn};
        for(var i=0,len=urls.length; i<len; i++){
            var script = createEl('script', {src: urls[i]});
            if(isIE){
                script.onreadystatechange = function(){
                    var readyState = this.readyState;
                    if (readyState == 'loaded' || readyState == 'complete'){
                        this.onreadystatechange = null;
                        finish(obj);
                    }
                }
            }else{
                script.onload = script.onerror = function(){
                    finish(obj);
                }
            }
            head.appendChild(script);
        }
    }
    return {js:js};
}(this);

example下载

posted on   snandy  阅读(3854)  评论(14编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
< 2011年4月 >
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
1 2 3 4 5 6 7

统计

点击右上角即可分享
微信分享提示