做有态度的前端团队

网易FEG前端团队

浅谈NIE组件加载方式的变化和原理

这里主要会说说小组组件新旧加载方式的实现方式、优缺点,以及未来展望


旧的方式

一、调用方式:

1
2
3
nie.use(["nie.util.share","nie.util.video"],function(){
    //do something
});

典型的AMD加载方式,就是按需加载,异步回调,代表作:requirejs

二、实现原理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//以下为简单实现原理,并非代码全部
nie.use = function(modules,callback){
    //定义异步请求组件js成功数
    var flags = 0;
    //循环遍历组件名字,发起请求
    for(var i=0;i<modules.length;i++){
        //getScript为请求一个js文件,成功后回调,具体代码不罗列了
        getScript("http://res.nie.netease.com/comm/js/"+modules[i]+".js",function(){
            //每次请求后,成功数+1
            flags++;
            //判断成功总数大于等于组件数,调用成功回调
            if(flags >= modules.length)callback();
        });
    }
}

从代码实现不难看出,组件数越多,同时发起的请求数就越多(用一下requirejs就知道了),但这不符合web优化的原则,所以加载方式上做了一些调整来解决这个问题

三、调整方式:

1、利用md5加密,把一次需要加载的组件的名字加密,然后请求md5文件名的脚本

1
2
3
4
5
nie.use  = function(modules,callback){
     
    var link = md5(modules.join(""));
    getScript("http://res.nie.netease.com/comm/cache/"+link+".js",callback);
}

可能会奇怪?那这个加密了的md5文件的js文件哪来的?

2、服务器生成对应的md5文件

假设你需要请求"util.share"和"util.video"两个组件,加密后是:abcdejjdkjj(随便敲的),那么需要在服务器执行一段脚本

  • 读取util.share.jsutil.video.js两个文件,合并成为一个文件
  • 将文件名join一下,md5加密,把加密后的字符串作为合并后的文件名保存
  • 合并后文件存在cache文件夹下

四、优缺点:

AMD的方式在于按需要加载,利用上面的方式解决多次请求的问题。
如果你想加载某个组合的组件,那么需要先在服务器跑一下脚本生成这个文件出来,想更新某个组件的时候,需要把对应的相关的组合文件重新生成一遍,这样不太方便提供给随心所欲的调用者,异步调用,偶尔会出现以下的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
//函数A和B,都需要使用video组件,习惯性的就会这样写了
function A(){
    nie.use(["nie.video"],function(){
        //do something
    });
}
function B(){
    nie.use(["nie.video"],function(){
        //do something
    });
}
A();
B();

新的方式

一、调用方式:

1
2
3
4
5
nie.define(function(){
    var share = nie.require("nie.util.share");
    var video = nie.require("nie.util.video");
    //do something
});

典型的CMD加载方式,依赖前置,就是你引用组件的时候,就需要在这之前就加载好了,代表作:seajs

二、实现原理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//简单实现,并非全部
nie.define = function(callback){
    //定义异步请求组件js成功数
    var flags = 0;
    //提取出nie.require的内容,callback.toString实际就是函数内容转为字符串
    var requireList = callback.toString().match(/nie\.require\([^\)]+\)/g);
    //抽出组件明
    for(var i=0;i<requireList.length;i++){
        requireList[i] = requireList[i].match(/\(([^\)]+)\)/i)[1].replace(/'|"/g,"");
    }
    //循环遍历组件名字,发起请求
    for(var i=0;i<requireList.length;i++){
        //getScript为请求一个js文件,成功后回调,具体代码不罗列了
        getScript("http://res.nie.netease.com/comm/js/"+requireList[i]+".js",function(){
            //每次请求后,成功数+1
            flags++;
            //判断成功总数大于等于组件数,调用成功回调
            if(flags >= requireList.length)callback();
        });
    }
}

跟上面的旧方式一样,都会出现同一个问题,会同时发起很多个请求,所以,做了以下几件事优化

三、调整方式:

1、推动SA那边做CDNCombo事情

让CDN支持线上文件合并,比如请求??nie.util.share.js,nie.util.video.js,CDN自动合并文件然后返回

2、请求方式改动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//简单实现,并非全部
nie.define = function(callback){
    //定义异步请求组件js成功数
    var flags = 0;
    //提取出nie.require的内容,callback.toString实际就是函数内容转为字符串
    var requireList = callback.toString().match(/nie\.require\([^\)]+\)/g);
    //抽出组件明
    for(var i=0;i<requireList.length;i++){
        requireList[i] = requireList[i].match(/\(([^\)]+)\)/i)[1].replace(/'|"/g,"");
    }
    //拼接URL
    var link = "http://res.nie.netase.com/comm/js/??" + requireList.join(",");
    getScript(link,function(){
        callback();
    });
}

四、优缺点:

CMD方式依赖前置,写代码的时候就会感觉是同步执行,不用担忧异步请求和回调的问题,上面还可以添加去重、以及已经求求过的不请求等功能,减少不必要的请求;推动CDNCombo后,不再需要用服务器跑脚本,调用者也能随意组合组件请求。
这种方式就需要先请求完组件后再执行主体代码逻辑,执行时机会对比AMD来说慢,开发时候会容易规避AMD的一些写法问题。

五、展望与未来:

目前的组件加载方式,实现了类似seajs的功能,模块加载和组件加载,之后会把jquery也拆出来,只保留核心库,其它都按需要加载,不再全部打包成一个文件

PS:组件加载方式源码链接->GitLab

手机阅读请扫描下方二维码:

none
上一篇:WEUI实践   下一篇:图片懒加载
分享到:

    已有 55 条评论

    1. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    2. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    3. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    4. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    5. admin

      jhcwlghvnwoaeesooowx

    6. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    7. jhcwlghvnwoaeesooowx

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    8. admin%0d%0aCRLF-Header:CRLF-Value

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    9. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    10. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    11. admin

      12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

    12. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    13. 1

      1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

    14. 1

      1

    15. 1

      1

    16. 1

      1

    17. 1

      1

    18. 1

      1

    19. 1

      1

    20. 1

      1

    21. 1

      1

    22. 1

      1

    23. 1

      1

    24. 1

      1

    25. 1

      1

    26. 1

      1

    27. 1

      1

    28. 1

      1

    29. 1

      1

    30. 1

      1

    31. 1

      1

    32. 1

      1

    33. 1

      1

    34. 1

      1

    35. 1

      1

    36. 1

      1

    37. 1

      1

    38. 1

      1

    添加新评论

    ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif