`
zccst
  • 浏览: 3294938 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

seajs与requirejs区别

阅读更多
作者:zccst

区别:

1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

2. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b') // 依赖可以就近书写
b.doSomething()
// ... 
})

// AMD 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
}) 

虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。


3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。









SeaJS与RequireJS最大的区别
来自豆瓣

如下模块通过SeaJS/RequireJS来加载, 执行结果会是怎样?
define(function(require, exports, module) {
    console.log('require module: main');

    var mod1 = require('./mod1');
    mod1.hello();
    var mod2 = require('./mod2');
    mod2.hello();

    return {
        hello: function() {
            console.log('hello main');
        }
    };
});

猜猜看?



先试试SeaJS的执行结果
    require module: main
    require module: mod1
    hello mod1
    require module: mod2
    hello mod2
    hello main
很正常嘛, 我也是这么想的...






再来是RequireJS的执行结果
    require module: mod1
    require module: mod2
    require module: main
    hello mod1
    hello mod2
    hello main
神马情况? 你他么是在逗我吗?



RequireJS你坑的我一滚啊, 这也就是为什么我不喜欢RequireJS的原因, 坑隐藏得太深了.
终于明白玉伯说的那句: "RequireJS 是没有明显的 bug,SeaJS 是明显没有 bug"是什么意思了


因此我们得出结论(分别使用SeaJS 2.0.0和RequireJS 2.1.6进行测试)
-------------------------
SeaJS只会在真正需要使用(依赖)模块时才执行该模块
SeaJS是异步加载模块的没错, 但执行模块的顺序也是严格按照模块在代码中出现(require)的顺序, 这样才更符合逻辑吧! 你说呢, RequireJS?

而RequireJS会先尽早地执行(依赖)模块, 相当于所有的require都被提前了, 而且模块执行的顺序也不一定100%就是先mod1再mod2
因此你看到执行顺序和你预想的完全不一样! 颤抖吧~ RequireJS!



详细的代码请参考
-------------------------
SeaJS测试加载/执行模块
RequireJS测试加载/执行模块


后记
-------
注意我这里说的是执行(真正运行define中的代码)模块, 而非加载(load文件)模块.
模块的加载都是并行的, 没有区别, 区别在于执行模块的时机, 或者说是解析.

为了说明阻塞的问题, 翠花上图
SeaJS的懒执行



RequireJS的预执行




注意图中巨大的pinyin-dict.js模块, 取自pinyin.js, 复制了N次后以增加它的"重量", 增强演示效果, 大家有兴趣的话可以亲手试试.

可以很明显的看出RequireJS的做法是并行加载所有依赖的模块, 并完成解析后, 再开始执行其他代码, 因此执行结果只会"停顿"1次, 完成整个过程是会比SeaJS要快.

而SeaJS一样是并行加载所有依赖的模块, 但不会立即执行模块, 等到真正需要(require)的时候才开始解析, 这里耗费了时间, 因为这个特例中的模块巨大, 因此造成"停顿"2次的现象, 这就是我所说的SeaJS中的"懒执行".

最后感谢大家的各种意见建议, 我这里并没有说SeaJS与RequireJS哪个更好一些, 仅仅是为了说明下他们的区别, 各种取舍请大家根据实际情况来定, 希望能帮到大家。


牛人观点:
1,
我个人感觉requirejs更科学,所有依赖的模块要先执行好。如果A模块依赖B。当执行A中的某个操doSomething()后,再去依赖执行B模块require('B');如果B模块出错了,doSomething的操作如何回滚?
很多语言中的import, include, useing都是先将导入的类或者模块执行好。如果被导入的模块都有问题,有错误,执行当前模块有何意义?
总之载入的所有模块,都是当前要使用的,为什么要动态的去执行?这个问题可以总结为模块的载入执行是静态还是动态。如果是动态执行的话,那页面的程序执行过程会受到当前模块执行的影响。而正如楼主所言,动态执行总体时间上是比静态一次执行要慢的。
楼主说requirejs是坑,是因为你还不太理解AMD“异步模块”的定义,被依赖的模块必须先于当前模块执行,而没有依赖关系的模块,可以没有先后。在楼主的例子中,假设mod1和mod2某天发生了依赖的话,比如在某个版本,mod1依赖了mod2(这是完全有可能的),这个时候seajs的懒执行会不会有问题?而requirejs是不会有问题,也不需要修改当前模块。
在javascript这个天生异步的语言中,却把模块懒执行,这让人很不理解。想像一下factory是个模块工厂吧,而依赖dependencies是工厂的原材料,在工厂进行生产的时候,是先把原材料一次性都在它自己的工厂里加工好,还是把原材料的工厂搬到当前的factory来什么时候需要,什么时候加工,哪个整体时间效率更高?显然是requirejs,requirejs是加载即可用的。为了响应用户的某个操作,当前工厂正在进行生产,当发现需要某种原材料的时候,突然要停止生产,去启动原材料加工,这不是让当前工厂非常焦燥吗?
暂且不去理会这个吧,等ECMA规范中加入了模块化的定义后,再看谁更合理吧。


2,
AMD 运行时核心思想是「Early Executing」,也就是提前执行依赖。这个好理解:

//main.js
define(['a', 'b'], function(A, B) {
    //运行至此,a.js 和 b.js 已下载完成(运行于浏览器的 Loader 必须如此);
    //A、B 两个模块已经执行完,直接可用(这是 AMD 的特性);

    return function () {};
});
个人觉得,AMD 的这个特性有好有坏:

首先,尽早执行依赖可以尽早发现错误。上面的代码中,假如 a 模块中抛异常,那么 main.js 在调用 factory 方法之前一定会收到错误,factory 不会执行;如果按需执行依赖,结果是:1)没有进入使用 a 模块的分支时,不会发生错误;2)出错时,main.js 的 factory 方法很可能执行了一半。

另外,尽早执行依赖通常可以带来更好的用户体验,也容易产生浪费。例如模块 a 依赖了另外一个需要异步加载数据的模块 b,尽早执行 b 可以让等待时间更短,同时如果 b 最后没被用到,带宽和内存开销就浪费了;这种场景下,按需执行依赖可以避免浪费,但是带来更长的等待时间。

我个人更倾向于 AMD 这种做法。举一个不太恰当的例子:Chrome 和 Firefox 为了更好的体验,对于某些类型的文件,点击下载地址后会询问是否保存,这时候实际上已经开始了下载。有时候等了很久才点确认,会开心地发现文件已经下好;如果点取消,浏览器会取消下载,已下载的部分就浪费了。
https://www.imququ.com/post/amd-simplified-commonjs-wrapping.html


如果您觉得本文的内容对您的学习有所帮助,您可以微信:
  • 大小: 119.7 KB
  • 大小: 131.9 KB
  • 大小: 75.2 KB
  • 大小: 136.2 KB
分享到:
评论
2 楼 嘿嘿哈哈嘿 2016-05-09  
seajs 和 requirejs最大的区别是执行阶段。

相同点:seajs和requirejs都是先把所有依赖到的js文件从server端load到本地。

不同点:seajs是按照调用require方法的顺序执行依赖的js文件中定义的function,而require是按照依赖关系执行js文件中定义的function
1 楼 lobtao 2015-10-09  
也觉得前置加载比较好,不会造成卡顿。

这也涉及到效率优先,还是选择加载优先。

相关推荐

    SeaJS与RequireJS区别

    本示例是一个简单的sea js 及 require js 的基本用法、执行原理和区别!供学习者参考!

    SeaJS 与 RequireJS 的差异对比

    主要介绍了SeaJS 与 RequireJS 的差异对比,本文主要对CMD规范和AMD规范的弊端做了对比,并做出了一个总结,需要的朋友可以参考下

    seajs和requirejs模块化简单案例分析

    本文实例讲述了seajs和requirejs模块化。分享给大家供大家参考,具体如下: 如今,webpack、gulp等构件工具流行,有人说seajs、requirejs等纯前端的模块化工具已经被淘汰了,我不这么认为,毕竟纯前端领域想要实现...

    JavaScript 模块化开发实例详解【seajs、requirejs库使用】

    主要介绍了JavaScript 模块化开发,结合实例形式详细分析了基于seajs、requirejs库的JavaScript模块化使用相关操作技巧,需要的朋友可以参考下

    RequiresJS_2.0_API中文

    requirejs define,requirejs 教程,requirejs 中文,requirejs shim, seajs require,requirejs seajs ,requirejs css,requirejs api, requirejs require

    前端模块化进程-requirejs seajs

    requirejs seajs amd cmd,该PPT主要用于讲解前端模块化的前世今身。 requirejs seajs amd cmd,该PPT主要用于讲解前端模块化的前世今身。

    js模块化规范介绍ppt

    js模块系统介绍的ppt,简要介绍js现有的几个模块规范,包括commonJS模块规范,amd,cmd,es6模块系统。并详细对比seaJS和requireJS的异同

    模块化开发及AMD、CMD、Require.js、sea.js、common.js、ES6的对比

    模块化开发及AMD、CMD、Require.js、sea.js、common.js、ES6的对比;模块化开发就是封装细节,提供使用接口,彼此之间互不影响,每个模块都是实现某一特定的功能。模块化开发的基础就是函数

    Require-Seajs:js模块化

    模块化js常用的工具Requirejs和Seajs, Requirejs是按照AMD的规范来定义模块的,Seajs是按照CMD的规范来定义模块的.Requirejs 与 Seajs 的最大区别:执行模块的机制不同RequireJS对模块的态度是预执行,也就是所依赖...

    LABjs、RequireJS、SeaJS的区别

    二、RequireJS 和 SeaJS 则是模块加载器,倡导的是一种模块化开发理念,核心价值是让 JavaScript 的模块化开发变得更简单自然。模块加载器也可降级为文件加载器用,因此使用 RequireJS 和 SeaJS,也可以达成 LABjs ...

    js简单课程设计

    js简单应用的课程设计,主要运用多种简单js,知识点:JavaScript+jQuery+Ajax+正则表达式+面向对象+js插件+代码性能优化+github+seaJs+requireJs+gulp 通过学习JavaScript基础变量、运算符、数据类型,函数,DOM...

    高级java笔试题-ama:《节点全栈》问我

    模块化加载seajs\requirejs\commonjs mvc/mvvm Bootstrap jQuery/Extjs/Dojo/Mootools/Yui Backbone Angular 移动端 h5/localstorage/websocket/canvas phonegap/cordova 是否具备编写原生插件能力 优化:fastclick...

    JavaScript模块化之使用requireJS按需加载

    主流的JS模块加载器有requireJS,SeaJS等,加载器之间可能会因为遵循的规范不同有微妙的差别,从纯用户的角度出发,之所以选requireJS而不是SeaJS主要是因为: 功能实现上两者相差无几,没有明显的性能差异或重大...

    Nv-engine:升级,重建和重命名所有代码

    你可以把他当做seaJs或者requireJs的替代品,可以单独使用,原因是他很简单不用做过多配置就能实现他们大部分功能。 常见实用场景 C端高并发量的首页、频道页、活动页 B端所有中台界面 面向对象的经典模块化开发所有...

    基于RequireJS和JQuery的模块化编程——常见问题全面解析

    最近正在把逻辑很重的js拆分成模块,在一顿纠结是使用requirejs还是seajs的时候,最终还是偏向于requirejs。毕竟官方文档比较专业嘛… 不过即便是有完整的官方文档,仍然遇到不少的问题,比如jquery-ui的使用。 下面...

    ImgLoader:图片延迟加载组件

    #调用方式通过seajs或者requirejs加载 var ImgLoader = require('ImgLoader'); imgloader = new ImgLoader({ skip_invisible : true, //如果图片未显示,则不加载 showEffect : 'fadeIn' }); imgloader.load();

Global site tag (gtag.js) - Google Analytics