jQuery .js加载延迟时间长

3

使用 jquery.load() 来替换一个 div 的内容,一切都很好,但是存在重大性能问题。加载到 div 中的页面包含一些外部 JavaScript 文件,使用 HttpWatch 我观察到以下情况:

0   0   GET (Cache) text/javascript <host>/js/file1.js
0   0   GET (Cache) text/javascript <host>/js/file2.js
0   0   GET (Cache) text/javascript <host>/js/file3.js
...
etc.

稍微往下一点(在相同的load()期间):

571 129862  GET 200 text/javascript <host>/js/file1.js?_=1263399258240
569 26439   GET 200 text/javascript <host>/js/file2.js?_=1263399258365
572 14683   GET 200 text/javascript <host>/js/file3.js?_=1263399258396
...
etc.

由于某种原因,似乎同样的脚本再次被加载。更糟糕的是,在文件再次获取之前,浏览器似乎会冻结。

我能否防止jQuery重新加载文件?整个问题导致我的页面延迟约5秒。另外,_=1263399258240的含义是什么?


你能发布一下加载脚本的代码吗?_=1263399258xxx 似乎是一个时间戳(我想是自1970年1月1日以来的当前毫秒数),附加到查询中以避免缓存。 - Andy E
页面已加载: jQuery(div).load(targetPage, function(){callback()});时间戳可能会被添加以避免缓存,但我不认为在我的情况下它不应该被缓存。我更喜欢能够关闭它并使用先前加载的内容。 - heeboir
是的没错。通过在javascript文件的url上添加查询字符串?<something random or unique>,浏览器被强制重新加载该文件,服务器将忽略?及其后面的所有内容,仅发送javascript文件。建议查看jQuery文档,了解是否有“允许缓存”或类似选项的ajax选项,这可能会防止发送url查询字符串。如果存在这样的选项并且它恰好是全局的,请在发送AJAX请求后将其恢复为默认设置。 - Graza
1
好的,我发现 jQuery 文档只能帮你完成一半,所以我也查看了代码(实际上我正在做类似的事情,所以花时间查看并不是问题)。我在下面的答案中包含了一些方法。 - Graza
2个回答

2
jQuery有三种不同的缓存选项。默认值null允许所有请求进行缓存,但脚本和JSON请求除外,而truefalse适用于所有请求。据我所知,在load()方法中无法提供选项参数,因此您需要更改全局jQuery ajax选项。
以下是我提供的不同方法:
  1. 第一种方法尝试在请求完成后保留先前的全局选项(但存在其缺点)。
  2. 第二种方法忽略默认设置,并仅设置选项,以便您始终允许使用缓存来处理ajax结果(如果这对您不是问题,我建议您选择这个,因为它是最简单的,没有隐藏的陷阱),并且
  3. 第三个示例是如果您想允许脚本的缓存,但不允许其他ajax请求。
示例1: 我的第一个示例展示了如何在load()请求后恢复正常设置:
    //first store defaults (we may want to revert to them)
 1: var prevCacheVal = $.ajaxSettings.cache; 
    //then tell jQuery that you want ajax to use cache if possible
 2: $.ajaxSetup({cache: true}); 
    //then call the load method with a callback function 
 3: $(myDiv).load(myURL,function(){
      /* revert back to previous settings. Note that jQuery makes 
         a distinction between false and null (null means never
         cache scripts, false means never cache anything). so it's
         important that the triple-equals operators are used, to
         check for "false" and not just "falsey" */
 4:   if (prevCacheVal === false) $.ajaxSetup({cache: false})
 5:   else if (prevCacheVal !== true) $.ajaxSetup({cache: null});
      //else prev was true, so we need not change anything
 6: });

重要提示:在进行上述操作时,需要小心确保每次只发送一个请求,因为每次存储和切换“默认”可能会导致竞争条件。如果您需要上述功能以及能够发送并行请求的能力,则最好编写自己的jQuery.ajax()方法包装器,以便您可以按照每个请求的基础传递cache选项。这类似于Andres下面建议的方法,但是使用了我建议的修复程序来指定cache: true并使用jQuery.html();而不是innerHTML。但是,情况比这更加复杂,因为内部jQuery.html();使用全局选项请求脚本,因此您还需要覆盖一些深入函数调用内部的内部功能,html();使 - 不要轻率地做出这样的事情,但肯定是可能的。
示例2:(推荐给原问题提问者)
现在,如果您不关心恢复默认值,并且希望缓存对于所有ajax请求都打开,那么您可以简单地调用$.ajaxSetup({cache: true});并像以前一样调用load()
 $.ajaxSetup({cache: true}); 
 $(myDiv).load(myURL);

示例3:

如果你不想从缓存中加载myURL(例如,它是动态的),但是又希望缓存脚本,那么你需要在myURL中添加一个独特或随机查询参数,如:

 $.ajaxSetup({cache: true}); 
 $(myDiv).load(myURL + "?myuniquetime=" + Date.getTime()); 
 /* getTime() is milliseconds since 1970 - should be unique enough, 
    unless you are firing of many per second, in which case you could
    use Math.random() instead. Also note that if myURL already includes
    a URL querystring, you'd want to replace '?' with '&' */

0

解决这个问题的一个可能方案是做一些事情:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
    <title>test</title>
</head>
<body>
    <div id="load1"></div>
</body>
</html>
<script>
$(function(){

    $.ajax({
        type: "GET",
        cache: false,
        url: "load1.html",
        success: function(data){
            $("#load1")[0].innerHTML = data;
        }
    });

});
</script>

load1.html:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js1.js"></script> 
</head>
<body>
    <div>html 1</div>   
</body>
</html>

1
这个方法会起作用,但是有两个问题:A)他想要cache: true(猜测只是打字错误),和B)它绕过了jQuery的.html()方法通常进行的所有清理工作,而是使用了.innerHTML。实际上,这是将所有内容添加到一个div中,包括<html>标签、<body>标签和其他不必要的内容。 - Graza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接