如何使用r.js优化器优化大型js应用程序+加载libs,如jquery,来自CDN的bootstrap?

时间:2014-08-01 07:50:51

标签: requirejs concatenation single-page-application minify r.js

我们已经构建了一个巨大的骨干木偶应用程序,它有许多不同的库(bootstrap,gmaps,momentjs等)。当我将所有东西组合成一个单独的生产模式时,一切都像魅力一样。为了提高性能,现在应该从CDN加载大多数库。

但这似乎并不像预期的那么容易。我从这个很棒的教程(http://tech.pro/blog/1639/using-rjs-to-optimize-your-requirejs-project)开始,并添加了一个负责加载外部库的基础架构模块。

infrastructure.js

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

main.js(它在过去几个月中有所增长:D)

require.config({
    urlArgs: 'bust=1386581060770',
    paths: {
        // jquery: '../../bower_components/jquery/dist/jquery',
        jquery: '//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min',
        underscore: '../../bower_components/underscore/underscore',
        marionette: '../../bower_components/marionette/lib/backbone.marionette',
        backbone: '../../bower_components/backbone/backbone',
        moment: '../../bower_components/moment/moment',
        'moment.de': '../../bower_components/moment/lang/de',
        text: '../../bower_components/text/text',
        'backbone.modelbinder': '../../bower_components/backbone.modelbinder/Backbone.ModelBinder',
        'backbone.analytics': '../../bower_components/backbone.analytics/backbone.analytics',
        'requirejs-i18n': '../../bower_components/requirejs-i18n/i18n',
        'jquery.cookie': '../../bower_components/jquery.cookie/jquery.cookie',
        'jquery.simplePagination': '../../bower_components/jquery.simplePagination/jquery.simplePagination',
        'underscore.string': '../../bower_components/underscore.string/dist/underscore.string.min',
        parsleyjs: '../../bower_components/parsleyjs/dist/parsley',
        'parsleyjs-de': '../../bower_components/parsleyjs/src/i18n/de',
        'parsleyjs-comparison': '../../bower_components/parsleyjs/src/extra/validator/comparison',
        requirejs: '../../bower_components/requirejs/require',
        'underscore.deepExtend': '../../vendor/others/tools/underscore.mixin.deepExtend',
        'underscore.templatehelper': '../../vendor/others/tools/underscore.mixin.templateHelper',
        templates: '../templates',
        infrastructure: 'infrastructure',
        confighandler: 'config/confighandler',
        layout: 'views/layout',
        general: 'general',
        helper: 'helper',
        vent: 'vent',
        view: 'views',
        model: 'models',
        module: 'modules',
        behaviors: 'behaviors',
        collection: 'collections',
        controller: 'controllers',
        nls: 'nls',
        'bootstrap-select': '../../bower_components/bootstrap-select/bootstrap-select',
        'eonasdan-bootstrap-datetimepicker': '../../bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
        'eonasdan-bootstrap-datetimepicker.de': '../../bower_components/eonasdan-bootstrap-datetimepicker/src/js/locales/bootstrap-datetimepicker.de',
        'bootstrap': '../../bower_components/bootstrap/dist/js/bootstrap',
        'jquery-cropbox': '../../bower_components/jquery-cropbox/jquery.cropbox',
        'jquery-geocomplete': '../../bower_components/jquery-geocomplete/jquery.geocomplete',
        'seiyria-bootstrap-slider': '../../bower_components/seiyria-bootstrap-slider/js/bootstrap-slider',
        'leaflet': '../../vendor/leaflet/leaflet-custom',
        modernizr: '../../bower_components/modernizr/modernizr',
        intro: '../../bower_components/intro.js/intro',
        lightbox2: '../../bower_components/lightbox2/js/lightbox'
    },
    shim: {
        'underscore.deepExtend': 'underscore',
        'underscore.string': 'underscore',
        'parsleyjs': 'jquery',
        'eonasdan-bootstrap-datetimepicker': 'moment',
        'parsleyjs-comparison': 'parsleyjs',
        'parsleyjs-de': 'parsleyjs',
        'select2-de': 'select2',
        'lightbox2': 'jquery',
        'jquery.simplePagination': 'jquery',
        'bootstrap-select': 'bootstrap',
        'bootstrap-slider': 'bootstrap',
        'backbone.modelbinder': 'backbone',
        underscore: {
            deps: ['jquery'],
            exports: '_'
        },
        backbone: {
            deps: [
                'underscore',
                'jquery'
            ],
            exports: 'Backbone'
        },

        'backbone.analytics': {
            deps: [
                'underscore',
                'backbone'
            ],
            exports: 'Backbone.Analytics'
        },
        'backbone.deepmodel': {
            deps: [
                'underscore',
                'backbone'
            ]
        },
        marionette: {
            deps: [
                'backbone'
            ],
            exports: 'Backbone.Marionette'
        },
        leaflet: {
            exports: 'L'
        },
        'jquery-geocomplete': {
            deps: [
                'jquery',
                'general/googlemaps'
            ]
        }
    }
});

require(['infrastructure'], function() {
    'use strict';
    console.log('infrastructure');

    require(['app', 'model/session'], function(App, Session) {

        console.log('app, model/session');
        App.session = Session;

        App.session.login(function() {
            App.start();
        });
    });
});

我的grunt配置中包含的build.js部分

requirejs: {
  compile: {
    options: {
      mainConfigFile: 'app/scripts/main.js',
      paths: {
        jquery: 'empty:'
      },
      modules: [{
        name: 'main',
        exclude: [
          'infrastructure'
        ]
      }, {
        name: 'infrastructure'
      }],
      findNestedDependencies: true,
      preserveLicenseComments: false,
      stubModules: ['text'],
      inlineText: true,
      optimize: 'none',
      dir: '<%= build.dest %>/app/scripts/',
      wrapShim: true
    }
  }
}

在第一步中,我只想包含来自CDN的jquery。在构建过程之后,我有两个文件main.js和infrastrucute.js。但是,如果我尝试运行在控制台中抛出错误消息的应用程序:

 Uncaught Error: Bootstrap's JavaScript requires jQuery 

我认为这个问题不会发生,因为应用程序在应用程序的所有其他部分和依赖库加载到main.js之前需要制造模块。但似乎main.js中的所有依赖关系仍然在制造模块之前加载。

目前我有点困惑,不知道该怎么做,甚至不知道从哪里开始。

是否有人已使用来自CDN的libs的r.js优化了该大小的应用程序。另外你怎么看待连接/缩小过程+从CDN加载库?它真的能提升装载性能吗?

事先提前

1 个答案:

答案 0 :(得分:1)

为JQuery for Bootstrap添加一个依赖项。从服务器加载JQuery时,它的加载速度足以在Bootstrap启动时可用。既然JQuery来自CDN,它需要更多的时间来加载,并且在Bootstrap启动时不可用。