为什么Require.js在加载所有DOM后加载基于jQuery的脚本?

时间:2014-03-31 15:01:21

标签: javascript jquery requirejs

最近我将require.js包含在我的项目中。我认为这将有助于我管理我的脚本并加快页面加载速度,只添加这些必要的文件。但结果非常相反。

我的问题是,为什么在添加AMD框架之后所有脚本都在加载? (see photo)当我通过脚本标记包含脚本时js正在加载正确,在加载DOM(没有图像等)之后。当我添加了require.js时,所有脚本都在页面上的所有内容加载后加载(带图像),这会导致相当大的延迟。

我担心,require.js和普通脚本有什么区别,包括然后将它们连接成一个文件?

我的代码如下,供参考:

require.js脚本结构:

|- main.r.js
|- lib/
   |- config.js
   |- require.js
   |- sliders.js

main.r.js:

require(['./lib/config'], function() {
  require([
    'jquery',
    'modernizr',
    './lib/sliders'
    ], function($, modernizr, sliders) {
      sliders.init();
 });
});

config.js:

require.config({
    baseUrl: 'scripts/',
  paths: {
    jquery: '../assets/jquery/jquery.min',
    modernizr: '../assets/modernizr/modernizr',
    bxslider: '../assets/bxslider-4/jquery.bxslider.min'
  },
  shim: {
    bxslider: {
      deps: ['jquery'],
      exports: 'jQuery.fn.bxSlider'
    }
  }
});

sliders.js:

define(['jquery', 'bxslider'], function($) {
  var maxiSlider = function() {
    var $mSlider = $('.maxi-slider');
    // init slider
    var slider = $mSlider.bxSlider({
      // auto: true,
      pager: false,
      onSliderLoad: function(currentIndex) {
        $mSlider.find('li').eq(currentIndex).addClass('banner-animation');
      },
      onSlideAfter: function($slideElement, oldIndex, newIndex) {
        $('.banner-animation').removeClass('banner-animation');
        $mSlider.find('li').eq(newIndex + 1).addClass('banner-animation');
      }
    });
 }
 return {
   init: function() {
     maxiSlider();
   }
 }
});

1 个答案:

答案 0 :(得分:1)

当您使用<script>标记并且未在其上设置async属性时,将同步加载脚本。基本上,浏览器会暂停它对HTML的解释,获取脚本并立即执行。您可以使用以下代码解析脚本之后的HTML:

<script>
    console.log(document.getElementById("foo"));
</script>
<div id="foo">blah</div>

假设id="foo"之前没有元素,控制台上打印的值将为null

现在,RequireJS异步加载数据 。 RequireJS只能提前加载东西。它可以要求浏览器加载一些数据但是如果浏览器决定完成解析DOM更重要的话,它几乎无法做到。实际上,在许多情况下,可能并不是浏览器决定任何东西:它只是解析DOM足够快以至于它在数据加载之前完成。并且考虑到如果您没有使用r.js优化您的应用程序,那么RequireJs会发现它需要以零散的方式加载:

  • 模块A是必需的。
  • RequireJS加载模块A,发现它依赖于B和C.
  • 它加载模块B,发现它依赖于D.
  • 加载模块C.
  • 加载模块D.

如果使用优化器,则所有这些加载(在最常见的情况下)将完成一次。所以使用优化器应该有助于使事情变得更加快捷。你可能想尝试一下。

在某些用例场景中,仅仅使用优化器仍然不够。对于这些情况,您可以使用杏仁以同步方式加载优化的捆绑包(请参阅此answer。)

您写道:

  

我认为[RequireJS]会帮助我管理脚本并加快页面加载速度,只添加必要的文件。

我们使用RequireJS的原因不是主要来加速加载,而是帮助管理我们的脚本。它允许我们模块化我们的代码库,这有助于隔离问题,设计可互换的组件等。确实在某些情况使用它加速加载,但这取决于每个应用程序的具体特征。例如,如果您有一个支持25种语言的应用程序,那么您的用户可能只使用一种语言,因此您只能为一种语言而不是25种语言加载特定于语言的文件。另一方面,我正在研究具有大量核心模块的应用程序,无论如何都必须始终加载。 RequireJS在这个的情况下不会让事情变得更快,它只是帮助我模块化我的代码。