【问题标题】:Jquery performance: what is better in most browsers, for loading and caching of js and css files?Jquery 性能:在大多数浏览器中,js 和 css 文件的加载和缓存哪个更好?
【发布时间】:2012-11-08 14:27:21
【问题描述】:

自从我从原型切换到 jquery 后,我遇到了很多以前从未知道存在的性能问题。

但这不是问题所在。问题是关于我正在使用的这个功能: (注意我们有一个巨大的网络应用程序) 我正在使用这个功能:

<!DOCTYPE html>
<html>
<head>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>


<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>



<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
  <div title="jquery ui exists" style="width: 500px; height: 500px; background-color: lightblue"  >hover me</div>
  <script>
  var MyApp ={
        loadJsNow: function(libFilename){
                //the synchronous call ensures the library is in fact loaded before this
          //(which does not work for crossdomain requests, just for docu)
                //function returns:     

                $.ajax({
                        url: libFilename,
                        dataType: "script",                     
                        type: "GET",
                        async: false,
                        cache: true,
                        complete: function(data){
                           $("div").tooltip();
                        }

                });


            }
    }


       MyApp.loadJsNow("http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js");


  </script>



</body>
</html>

所以这个函数是用来加载网页的某个元素需要的js文件。由于我们有很多页面,有时很少,有时会加载,这种方法似乎很有意义。但: 由于此功能按需加载,而不像标头中的标准那样加载,我不确定这是否会自行造成性能问题。 在 FF 10 我得到 200-600 毫秒 see here

看看这里在标题中使用硬编码值的不同方法:

Hardcoded head js links 我得到〜100-300毫秒

放弃对按需加载的所有支持? 你得到类似的结果吗?

编辑我想crossreference this question,因为它似乎相关,因为 jquery / firefox 似乎没有正确处理按需 javascript 加载的缓存。有时它可以工作,但在同一页面上它又不能工作了。

【问题讨论】:

  • 如果您知道页面上将需要它,那么动态加载脚本通常没有什么意义。不妨立即使用内联代码加载它并完成它。
  • 不从 Google CDN 指定确切的版本几乎可以确保您的 sripts 无论如何都不会被缓存,所以首先定义版本而不是 /1/ 来确保最新版本过期日期并被缓存。如果不需要,也尽量不要加载整个 UI 库。您可以使用 jQuery UI 站点中所需的方法来构建它。
  • 是的,把东西放在&lt;/body&gt; 上面,而不是放在你的脑海里。 CDN 的东西很大,不知道有多少人意识到最新版本的链接没有被缓存。
  • @ŠimeVidas 我认为&lt;script&gt; 链接曾经被注释掉。
  • @RichBradshaw - 我真的不明白为什么 Google 会提供这种方法,因为它违背了使用 CDN 的全部目的,其中主要优点是用户已经将脚本缓存在浏览器。他们应该用一个巨大的警告来标记它“这个方法很糟糕,因为不会启用缓存”!

标签: jquery performance dynamic-loading


【解决方案1】:

您是否考虑过使用 requirejs 代替?我不是回答问题并给出与问题不直接相关的答案的人,但在这种情况下,它可能真的对你有帮助。

我修改了您的脚本以使用 requirejs 并且仍然使用异步并在完成后触发事件。这将允许对多个脚本进行多个异步请求,但仍仅在所有脚本都准备好时才执行。

http://requirejs.org/docs/api.html

http://jsbin.com/oxekod/9/edit

<!DOCTYPE html>
<html>
<head>
  <script type="text/javascript">var startDate = new Date();</script>

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  <script src="http://requirejs.org/docs/release/2.1.1/comments/require.js"></script>
<!--
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
-->


<meta charset=utf-8 />
<title>JS Bin</title>

    <!-- make sure this is declared in head -->
    <script>
  var MyApp ={
     queue: []
     , loadJsNow: function(strScript)
    { // add to the queue, but don't start loading just yet...
                MyApp.queue.push(strScript);
    }
  };
  </script>
</head>
<body>
  <div title="jquery ui exists" style="width: 500px; height: 500px; background-color: lightblue"  >hover me</div>

  <!-- throughout your app, add scripts as needed -->
  <script>
    MyApp.loadJsNow("http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js");
  </script>

  <script>
    $(function()
      {
        // when everything's ready, run your scripts through require.
        // after require loads ALL scripts, let jquery trigger a custom event called, say, 'scriptsloaded'
        require(MyApp.queue, function() { $(document).trigger('scriptsloaded'); });
      });
  </script>

  <script>
    $(document).on('scriptsloaded', function()
      {
        // anything that needs to wait for dynamic scripts should wait for the custom event to fire on document
        // once fired, all scripts are loaded, and do what you want.
        $('div').tooltip();

        var endDate = new Date();
        alert('diff: ' + (endDate.getTime() - startDate.getTime()));
      });
  </script>

</body>
</html>

【讨论】:

  • +1 因为我无法想出在加载所有内容时触发我自己的事件的想法。但是:用你的方法我得到大约 300 毫秒。使用标题中的链接,我得到
  • @Toskan 我更新了上面的脚本以添加“tming”事件。要在 static 和 requirejs 之间切换,我只需取消注释 static 脚本行并将 // js 注释掉 MyApp.loadJsNow 行。对于这两种情况,在 jsbin 中一遍又一遍地单击“使用 JS 运行”时,我得到大约 300-400 毫秒。您看到了什么结果?
【解决方案2】:

正如 Eli Gassert 建议的那样,您可以使用第三方依赖加载器 要自己完成,请将您的功能更改为此

  loadJsNow: function(libFilename){

      var fileref=document.createElement('script');
      fileref.setAttribute("type","text/javascript");
      fileref.setAttribute("src", libFilename);
     }

这将加载文件,但它不会在 DOM 中。如果您愿意,可以将它们添加到标题中,将其添加到 MyApp 中:

headElementRef: document.getElementsByTagName("head")[0],

把这个放到方法里:

  this.headElementRef.appendChild(fileref);

【讨论】:

    猜你喜欢
    • 2011-04-23
    • 2014-02-03
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    相关资源
    最近更新 更多