【问题标题】:Function keeps requesting images from server instead of the cache函数不断从服务器而不是缓存请求图像
【发布时间】:2017-09-04 01:31:15
【问题描述】:

我使用 JQuery“幻灯片”创建了一个动画。该函数以 100 毫秒的速度翻转 62 张图像。问题在于,Chrome 开发者工具显示,该函数在每个周期内一遍又一遍地从服务器请求图像,而不是使用缓存。 这些图片都具有相同的 32.2 KB 大小,并且也具有相同的尺寸。网站上有大约 20 个这样的动画,您可以在此处查看测试版本:link。动画是 20 个小指标,位于页面中间的蓝色大区域。

代码如下:

<script type="text/javascript">      

function slideShow(id, index, imagePath, lastImage, fadeTime) {

     $('#slideShowBack'+id).show();
     index = (index == lastImage) ? 1 : index + 1;
     $("#slideShowBack"+id).attr("src", imagePath + "/" + index + ".png")
     setTimeout('slideShow(' + '"'+ id + '"' + ',' + index + ',' + '"'+ imagePath + '"' +', ' + lastImage + ', ' +  fadeTime + ')', fadeTime);
  }

   $(document).ready(function() {
     slideShow('SovSeng', 1, 'images', 62, 100);
    });
</script>
</head>
<body>
  <img id="slideShowBackSovSeng"  src="" />

我还尝试了一种不同的方法这成功地仅在第一个周期期间从服务器请求图像,但在执行第一个周期时,它在图像之间闪烁/闪烁非常明显。

   <script type="text/javascript"> 

     var imagePath = "images";
     var lastImage = 62;
     var removeAfter = 100;

     function slideShow(index) {
        var url = imagePath + "/" + index + ".png";
        $("#slideShow").prepend($("<img/>").attr("src",url));
        $("#slideShow img:last").remove();
           setTimeout(function() {
              slideShow((index % lastImage) + 1)
           }, removeAfter);
     }

     $(document).ready(function() {
        setTimeout(function() { slideShow(1); }, removeAfter);
     });

  </script>
  </head>
  <body>
       <div id="slideShow">
          <img id="slideShow" src="images/1.png" />
       </div>

然后我尝试使用一个函数来预加载图像,这在 Chrome 中大部分时间都可以正常工作,但是在页面刚刚加载后,幻灯片功能有时会随机开始直接从服务器获取图像,而不是预加载它们。我已将预加载放在幻灯片代码之前。预加载永远无法在 Firefox、Internet Explorer 或 Edge 上运行。我没试过 Safari。

<script type="text/javascript"> 

function preloadImages(array) {
   if (!preloadImages.list) {
      preloadImages.list = [];
   }
   var list = preloadImages.list;
   for (var i = 0; i < array.length; i++) {
      var img = new Image();
      img.onload = function() {
         var index = list.indexOf(this);
         if (index !== -1) {
            list.splice(index, 1);
         }
      }
      list.push(img);
      img.src = array[i];
   }
}

preloadImages(["images/1.png", "images/2.png", "images/3.png", etc.. ]); 

</script>

所以我的问题是我可以在第一个代码示例中停止我的函数向服务器发出无限请求,或者我可以在我的第二个示例中改进我的代码,使其在第一次运行时停止闪烁/闪烁吗?

编辑:来自第一个代码示例中的函数的图像请求的 HTTP 标头。

我不再完全确定请求会绕过缓存,因为 Chrome 开发工具显示在动画第一次运行后传输的​​数据量实际上并没有增加。我在这里缺少什么,http 请求是否被重定向到缓存?

    {
    "startedDateTime": "2017-04-11T21:05:11.260Z",
    "time": 0,
    "request": {
      "method": "GET",
      "url": "http://fiskervej.com/tody/images/31.png",
      "httpVersion": "unknown",
      "headers": [],
      "queryString": [],
      "cookies": [],
      "headersSize": -1,
      "bodySize": 0
    },
    "response": {
      "status": 200,
      "statusText": "OK",
      "httpVersion": "unknown",
      "headers": [
        {
          "name": "Date",
          "value": "Tue, 11 Apr 2017 21:02:44 GMT"
        },
        {
          "name": "Last-Modified",
          "value": "Wed, 05 Apr 2017 04:49:17 GMT"
        },
        {
          "name": "Server",
          "value": "Apache"
        },
        {
          "name": "Accept-Ranges",
          "value": "bytes"
        },
        {
          "name": "Content-Length",
          "value": "33266"
        },
        {
          "name": "Content-Type",
          "value": "image/png"
        }
      ],
      "cookies": [],
      "content": {
        "size": 33266,
        "mimeType": "image/png"
      },
      "redirectURL": "",
      "headersSize": -1,
      "bodySize": 0,
      "_transferSize": 0
    },
    "cache": {},
    "timings": {
      "blocked": -1,
      "dns": -1,
      "connect": -1,
      "send": 0,
      "wait": 0,
      "receive": 0,
      "ssl": -1
    },
    "serverIPAddress": "144.208.78.49",
    "pageref": "page_1"
  },

【问题讨论】:

  • 您能否向我们展示浏览器未缓存的图像请求和响应的 HTTP 标头?您可以使用 Chrom DevTools Copy All as HAR
  • 嗨@LeonidVasilyev 感谢您的回复。我添加了一个图像请求的示例。我使用了 Chrome DevTools “全部复制为 HAR”。
  • 这可能会有所帮助stackoverflow.com/questions/3712234/…

标签: jquery browser-cache


【解决方案1】:

您是否尝试过服务器端和客户端缓存?我会调查他们两个。

在执行任何 javascript 之前,DOM 将首先加载所有方式,因此您可以做的是加载图像并使用 CSS 将它们从视图中隐藏,然后在执行脚本时加载所有图像。

我查看了缓存动态加载的图像并遇到了new Image()here

【讨论】:

    【解决方案2】:

    您误解了网络信息。图像被正确缓存。但是看看我们所说的动画,基于 DOM 的 JavaScript 动画可能不是最好的选择。

    尽管缺少像Cache-ControlExpires HTTP 标头作为响应的显式新鲜度信息,但浏览器仍然使用启发式新鲜度对其进行缓存。响应的bodySize 等于 0 表示它来自缓存。可能您可以在 Chrome 开发工具网络选项卡的大小列中看到(从磁盘缓存)标签。还有一些请求可能会命中所谓的List of available images 或内存缓存。

    在我看来,在您的情况下,所有这些 DOM 操作都可以替换为单个动画 GIF 文件和单个 img 节点。还有许多其他方法可以为 Web 制作动画。您可能需要查看 What's the best way to animate an illustration for the web? Graphic Design Stack Exchange 上的讨论。

    更多信息请查看:

    【讨论】:

    • 感谢@Leonid 的帮助。我将动画更改为 gif,效果更好。
    猜你喜欢
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    相关资源
    最近更新 更多