首页 > 网站 > WEB开发 > 正文

记录:sea.js和require.js配置 与 性能对比

2024-04-27 14:07:33
字体:
来源:转载
供稿:网友

记录:sea.js和require.js配置 与 性能对比

最近有点忙,很久无写博客,记录一下之前的配置require.js和sea.js的配置.(有误有望提出

require.js

文件目录

/app(项目使用js)

/lib(require.js jq存放处)

/plugin(框架对应的功能插件)

require.js比较方便在于,不是amd的模块组件可以通过配置文件进行依赖配置.而且异步加载js 页面加载速度是杠杠的.当然会有点问题的,网速过慢的话,可能会出现js,timeout(可以通过配置解决.

config.js (配置文件)

// 配置信息requirejs.config({    // 模块的基准路径    baseUrl: 'js/lib',    // 映射不直接放在baseUrl下的模块名    paths: {    app: '../app',    plugin: '../plugin',    jquery: 'jquery-1.9.1.min',    lazyload: '../plugin/jquery.lazyload.min',    base: '../',    controller: '../app/controller',    model: '../app/model'    },    // 为没有使用define()的模块声明依赖关系    shim: {    lazyload:{        deps: ['jquery'],        exports: 'lazyload'    },    'plugin/placeholder':{        deps: ['jquery'],        exports: 'placeholder'    }    },    // 设置请求超时时长,设为0时表示不限超时时间    waitSeconds: 0});

  官方的文档存在一个 indexMain.js 请求对应的首页js模块 index.js.(大概就以下的感觉)

require(['config'], function () {})

请求 ([依赖模块名称],回调());

require(['config'], function () {  require(['app/index']);});

  然后才在这个index.js模块上对各种模块进行操作,初始化等等操作

define(['jquery',], function($){});

定义模块 ([依赖模块名称],回调(模块返回参数变量));

define(['jquery',], function($){    $(document).click(function() {        alert($);    });});

  感觉有点多余,所以的采取的配置是这样一回事的直接一个index.js就 直接请求对应的模块为index服务了.

require(['config'], function(){require(['jquery','../common'], function($){        $(document).click(function() {          alert($);        });    });});

  requirejs也支持CMD写法(js里面写require(**)请求js),忘记在哪里看了一篇文章,requirejs 是通过把CMD转换成require(['jquery','../common'])这种模式.所以就不在探究.

sea.js

  好奇心作怪,个人还是测试了sea.js在开发中的使用.一样是模块加载,由于是cmd,懒加载模式下,逻辑思路感觉比较合理?

个人觉得sea的文档比较混乱,require的就比较齐全了.具体自己体验...

文件目录

/app (项目使用js 控制器)

/sea

  /seajs (seajsseajs 配置文件)

  /jquery

    /plugins

  /plugins

针对上次require js挖的坑进行了一次优化目录路径

旧版本seajs 可以通过<script src="./sea.js" data-main="./init"></script> 引进模块控制器,(过去了的旧demo会有这个)

现在是使用seajs.use([],function(){})来调用模块控制器

seajs.的配置文件需要使用标签引进,<script src="./config.js"></script>

config.js

/** * Created by moki on 2015-5-16. */var seaUrl=location.PRotocol+'//'+location.host;seajs.config({    // Sea.js 的基础路径    base: seaUrl+"/res/global/js/sea",    // 路径配置    paths: {        'tuonews_reception': seaUrl+'/res/app/tuonews/reception/default/js',        'tuonews_user': seaUrl+'/res/app/tuonews/user/default/js',        'jq':'jquery',        'jq_plugins': 'jquery/plugins',        'plugins':'plugins'    },    // 别名配置    alias: {        'jquery': 'jq/jquery',        '$': 'jq/jquery'    },    // 调试模式    debug: true,    // 文件编码    charset: 'utf-8'});

  在页面引进 sea.js 和config.js后 再调用对应的模块控制器,

  在页面中加入对应代码调用模块

  seajs.use(['jQuery','common'],function($){})

   调用模块      回调

  官方建议回调和模块中不使用seajs.use来请求模块调用,而是使用require;

/** * Created by moki on 2015-5-12. */define(function(require,exports,module){  //赋值变量 请求模块    var $ = require('jquery');    $(function (){   //根据节点判断是否需要加载对应的js插件    var banner = $('#banner');       if(banner[0]) {      require('banner');      banner.banner();    }    });});

  seajs的模块化插件 需要改变当前插件

jq ,新版jq本身支持amd模式,在seajs下只需把

if ( typeof define === "function" && define.amd && define.amd.jQuery ) {define( "jquery", [], function () { return jQuery; } );}

改为

if ( typeof define === "function") {define( "jquery", [], function () { return jQuery; } );}

至于低版本jq 需要定义jq

define('jquery',[],function(require, exports, module){//这里放jQuery源代码module.exports = jQuery;});

制作cmd jq插件

define('jquery',[],function(require, exports, module){        var $= require([jQuery]);//插件代码        $.fn.a = function (){}        //插件代码}); 

优缺点

基本上seajs和require配置完毕;现在开发中我遇到的问题;

require由于项目运维方向问题,导致整个项目还未正式投入实战当中,估计还会存在坑;

在开发的逻辑思路来说,

seajs是采取 按需请求js, sea的思路会比清晰,(还未压缩js前),控制器不多的时候,通过一个js 来控制多个页面,优势在于可以缓存这个js文件,

requirejs,是先加载依赖文件再编译,所以要多个不同的页面 使用同一个js控制,会令到不同页面都会把大部分无用js加载过来,所以还是有必要拆分多个js.在requirejs下采取cmd模式加载模块,结果如何?(应该本身就不建议这样写,只是方便过渡,所以还是不在考虑当中);

这么一看好像seajs更适合开发?

大家常说requirejs比seajs要快?

seajs会在模块加载后再执行 模块中的require,然而requirejs 是在加载完毕后会执行对应的js

想深究 究竟如何的人 请务必细心看完引用文章

来源 http://www.zhihu.com/question/20342350

    http://qingbob.com/let-us-talk-about-resource-load/ 让我们再聊聊浏览器资源加载优化

个人认为玉伯聊的比较抽象和宏观,比如标准,概念,机制,社区等。最近一直在做性能优化方面的工作,就自己的经验谈谈require.js和sea.js的异同。这两个加载器和标准没有优劣之分,这里指出的只是差别。具体还是要根据实际情况进行选择在开始之前我已经假设你对requirejs与seajs语法已经基本熟悉了,如果还没有,请移步这里:- CMD标准:https://github.com/cmdjs/specification/blob/master/draft/module.md- AMD标准:https://github.com/amdjs/amdjs-api/blob/master/AMD.md对比require.js与sea.js,某种意义上说就是对比AMD标准与CMD标准,个人认为两个类库在模块和factory的书写上其实无太大差异,差异在于
  • 模块的加载
  • factory函数的执行。
这里提前说一句,如果你的网站再上线前习惯把所有的模块打包压缩,其实requirejs和seajs并无太大差别。## 加载差异这一小节请允许我照搬一个帖子玉伯转过的一个SeaJS与RequireJS最大的区别,这个帖子原始(不包括后记)的结论是RequireJS你坑的我一滚啊, 这也就是为什么我不喜欢RequireJS的原因, 坑隐藏得太深了.SeaJS是异步加载模块的没错, 但执行模块的顺序也是严格按照模块在代码中出现(require)的顺序, 这样才更符合逻辑吧! 你说呢, RequireJS?而RequireJS会先尽早地执行(依赖)模块, 相当于所有的require都被提前了, 而且模块执行的顺序也不一定100%就是先mod1再mod2因此你看到执行顺序和你预想的完全不一样! 颤抖吧~ 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');        }    };});
运行结果应该是顺序的(sea.js下的结果):
require module: mainrequire module: mod1hello mod1require module: mod2hello mod2helo main
而不应该是异步的require.js下:
require module: mod2require module: mod1require module: mainhello mod1hello mod2helo main
但问题是,为什么"执行模块的顺序"应该是"严格按照模块在代码中出现(require)的顺序"? 并且"这样才更符合逻辑吧"?如果他以seajs的运行结果来要求requirejs,那requirejs肯定吃亏了。AMD标准从来都没有规定模块的加载顺序,它只是需要保证:The dependencies must be resolved prior to the execution of the module factory function, and the resolved values should be passed as arguments to the factory function with argument positions corresponding to indexes in the dependencies array.评论下方有人(jockchou)的回复更切中要害:我个人感觉requirejs更科学,所有依赖的模块要先执行好。如果A模块依赖B。当执行A中的某个操doSomething()后,再去依赖执行B模块require('B');如果B模块出错了,doSomething的操作如何回滚?很多语言中的import, include, useing都是先将导入的类或者模块执行好。如果被导入的模块都有问题,有错误,执行当前模块有何意义?楼主说requirejs是坑,是因为你还不太理解AMD“异步模块”的定义,被依赖的模块必须先于当前模块执行,而没有依赖关系的模块,可以没有先后。想像一下factory是个模块工厂吧,而依赖dependencies是工厂的原材料,在工厂进行生产的时候,是先把原材料一次性都在它自己的工厂里加工好,还是把原材料的工厂搬到当前的factory来什么时候需要,什么时候加工,哪个整体时间效率更高?显然是requirejs,requirejs是加载即可用的。为了响应用户的某个操作,当前工厂正在进行生产,当发现需要某种原材料的时候,突然要停止生产,去启动原材料加工,这不是让当前工厂非常焦燥吗?这样看来其实两者并无太大差别。但考虑这样一种业务情况,考虑某一个功能只对登陆用户开放,这样的话requirejs提前把模块加载是否有必要?(因为来到你页面的用户到离开也不会登陆)。这是非常实际的问题,一个页面可以有非常多的功能,比如登陆、分享、留言、收藏……但不一定每一个来到页面的用户都会使用这些功能,如果都作为页面模块的依赖提前加载的话,对页面一定是一个不小的负担。但seajs可以即用即加载,比如代码可以这么写
define(function () {    if (user_login) {        require(login_feature_module)    }        document.body.onclick = function () {        require(show_module)    }})
我同意这句话:很多语言中的import, include, useing都是先将导入的类或者模块执行好。如果被导入的模块都有问题,有错误,执行当前模块有何意义?但个人觉得考虑到页面的性能,可以考虑将要导入模块的懒加载(Lazy load)。你会不会觉得我上面说的懒加载是一种天方夜谭?但然不是,你去看看现在的人人网个人主页看看图中标注的“与我相关”、“相册”、“分享”都是在点击之后才加载对应的模块Facebook的情况更为严重,不仅要考虑内部不同团队的功能模块,还要考虑第三方的功能模块。早在09年,他们就是用了一套静态资源管理方案(Static Resource Management),用于管理一个功能所需要的js/CSS静态文件:
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表