• 为什么使用 Containjs 模块化管理工具效率高?


    为什么使用 Containjs 模块化管理工具效率高?

    要说明这个首先得说明一下,Containjs 的模块加载原理。

    • 第一步,首先使用异步加载(ajax)在 js 目录下的 app.js 入口模块(Containjs内部会默认加载 ('js/app.js'))
    • 第二步,生产已经加载成功模块的上下文环境
    • 第三步,查找该模块文件中是否有依赖其他模块,如果有则异步加载所依赖模块,加载成功后继续第二步,直到最基础模块(没有依赖其它模块的模块)
    • 第四步,等待应用所依赖模块都加载完成,则默认调用 require('js/app.js') 运行入口模块

    看了 Containjs 的加载流程,好像也没明白为什么效率高对吧?下面就让我慢慢道来~

    其实,奥秘就在第二步生产模块上下文和 require 加载依赖模块中。

    在 Containjs 中模块加载成功后,会调用模块函数的生产函数(production),其中有一段是下面这样

    // 生产模块,但是未执行
    modules[url] = {
      ........
      context : function(require, exports, module){
          eval( data )
      }
      .......
    }
    

    上面代码中的 context 就是模块执行时候的上下文环境,很明显它被包含在一个匿名函数中,其中注入了三个接口 require、exports、module,具体什么作用这边就不多解释,可以去看我上一篇博客《Containjs是什么》

    但是,只要有点经验的人就会说,不对啊这函数中调用了 eval(data) 这效率能高吗?(其中 data 就是使用异步加载过来的模块代码字符串)

    首先,说一个场景,传统的模块引入都是异步生成 script 标签然后添加到文档流中去异步加载的,加载成功后浏览器会立即解释并执行。

    而 Containjs 使用的是 ajax 异步加载,加载成功后传入模块生产函数进行生产,生产的时候使用 eval() 函数进行解释 data 代码。当模块全部加载完成后,会默认调用 require('js/app.js') 入口模块,后开始执行。并且执行过后,马上被缓存模块接口,之后无论调用几次都不会在执行本模块,直接返回缓存的继承。

    很多人会说 eval 效率很低啊,为什么你说效率高?是这样的,以前说使用 eval 效率低的原因场景是这样,在一个常用函数中使用 eval 比如:

    // 普通定义
    function add(a,b){
      return a + b;
    }
    
    // 使用eval
    function add(a,b){
      eval('return a+b');
    }
    

    在普通定义中,return a+b 语句只被解释器,解释一次。而使用 eval 中则是每一次调用都调用 eval 解释并执行 return a+b 所以效率低。

    而 Containjs 模块 eval 解释执行只会一次,之后会被缓存。传统的 script 引入也是一样代码也是会被解释执行一次。只不过发生在加载成功后马上执行而已。所以你懂的

  • 相关阅读:
    【Impala】为Impala Daemon服务配置Executor和Coordinator角色
    [Mysql]ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds
    C/C++ 计算文件ROF再计算VAOF
    C/C++ 判断进程32位还是64位
    商业化管理
    数据库设计 ER图
    单例模式及其序列化/反序列化
    IDEA怎么生成UML类图
    UML 类图描述
    单例设计模式——readResolve()源码分析
  • 原文地址:https://www.cnblogs.com/iron-whale/p/Containjs-eval-explain.html
Copyright © 2020-2023  润新知