Web性能:循环访问相同的4 img src会产生太多请求

时间:2018-05-16 09:40:52

标签: javascript html

为了学习,我正在尝试构建一个简单的图像轮播。

当前代码有一个循环的网址数组,用于更新div的背景图像

var urls = [
    ‘/assets/img/topcatchimage/top-catiimg01.jpg’,
    ‘/assets/img/topcatchimage/top-catiimg02.jpg’,
    ‘/assets/img/topcatchimage/top-catiimg03.jpg’,
    ‘/assets/img/topcatchimage/top-catiimg04.jpg’
];

setInterval(changeBackground, 3000);

var i = 0
function changeBackground () {
    if (i == 4) { i = 0 }
    document.getElementById('mainvisual').style.background = `url(${urls[i]})`
    i++
}

由于我不知道的某些原因,这导致总共6-8个请求;每个图像的两个ish。图像被请求两次后,不再发送新请求。

有没有办法将这些图像加载到内存中并且每次都不使用它们就使用它们?

2 个答案:

答案 0 :(得分:2)

在我的情况下,每个图像只需要一个。

示例



var urls = [
  'https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/68dd54ca-60cf-4ef7-898b-26d7cbe48ec7/10-dithering-opt.jpg',
  'https://www.wonderplugin.com/videos/demo-image0.jpg',
  'https://www.samcodes.co.uk/project/geometrize-haxe-web/assets/images/xseagull.jpg.pagespeed.ic.iK66EGA15-.jpg',
  'https://www.elastic.co/assets/bltada7771f270d08f6/enhanced-buzz-1492-1379411828-15.jpg'
];

setInterval(changeBackground, 500);

var i = 0;

function changeBackground() {
  if (i == 4) {
    i = 0;
  }
  document.getElementById('mainvisual').style.backgroundImage = `url(${urls[i]})`;
  i++;
}

#mainvisual {
  width: 400px;
  height: 400px;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  border: 1px solid #DDD;
}

<div id="mainvisual"></div>
&#13;
&#13;
&#13;

但是如果在你的情况下它被加载不止一次,而不是改变背景,只需创建一个div并显示和隐藏它。

以下是一个工作示例

&#13;
&#13;
var urls = [
    'https://cloud.netlifyusercontent.com/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/68dd54ca-60cf-4ef7-898b-26d7cbe48ec7/10-dithering-opt.jpg',
    'https://www.wonderplugin.com/videos/demo-image0.jpg',
    'https://www.samcodes.co.uk/project/geometrize-haxe-web/assets/images/xseagull.jpg.pagespeed.ic.iK66EGA15-.jpg',
    'https://www.elastic.co/assets/bltada7771f270d08f6/enhanced-buzz-1492-1379411828-15.jpg'
];

setInterval(changeBackground, 500);

var i = 0
function changeBackground () {
    if (i == 4) {
      i = 0;
    }
    var images = document.getElementsByClassName("image");
    for (var x of images) {
      x.style.display = "none";
    }
    var image = images[i];
    if (typeof image === "undefined") {
      var newImage = document.createElement("div");
      newImage.className = "image";
      newImage.style.backgroundImage = `url(${urls[i]})`;
      document.getElementById("mainvisual").appendChild(newImage);
    } else {
      image.style.display = "block";
    }
    
    i++;
}
&#13;
.image {
  width: 400px;
  height: 400px;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  border: 1px solid #DDD;
}
&#13;
<div id="mainvisual"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

你可以创建一个预加载器函数,然后在加载所有函数后传递一个回调来执行:

function preload(arr,callback){
    var img = new Image();
    img._count = 0;
    img.onload = function(){
        if(++this._count === arr.length){
            callback && callback();
        } else {
            img.src = arr[this._count];
        }
    }
    img.src = arr[0];
}

一旦预先加载了urls(arr)和回调(你的函数),你就提供这个函数。所以一起:

var urls =[
"https://raw.githubusercontent.com/IbrahimTanyalcin/LEXICON/master/lexiconLogo.png",
"https://raw.githubusercontent.com/IbrahimTanyalcin/LEXICON/master/img/distribute.gif",
"https://raw.githubusercontent.com/IbrahimTanyalcin/LEXICON/master/img/dash.gif"
];

//callpreloader
preload(urls,callback);

//preloader
function preload(arr,callback){
    var img = new Image();
    img._count = 0;
    img.onload = function(){
        if(++this._count === arr.length){
            callback && callback();
        } else {
            img.src = arr[this._count];
        }
    }
    img.src = arr[0];
}

//your function
function callback(){
    setInterval(changeBackground, 3000);
    var i = 0
    function changeBackground () {
        if (i == 4) { i = 0 }
        document.getElementById('mainvisual').style.background = `url(${urls[i]})`
        i++
    }
}

小提琴:https://jsfiddle.net/ibowankenobi/L347w43y/

我还应该提一下,你不能完全控制浏览器的缓存行为。在客户端,chrome具有meta - 标记,允许您指定cache-control标题。但是例如在我发布的jsfiddle中,检查请求和响应标头,您将看到小提琴请求标头包含Cache-Control no-cache。由于缓存控制头是单向的,因此来自github的响应头也在返回的图像上指定300秒。所以底线:我建议的解决方案是有效的,只要标题不会覆盖所需的行为。

要验证我说的内容,请制作脚本的本地html副本并在那里运行。除了失败的请求之外,成功的请求将被缓存(因为github也会发送缓存控制头,因此会持续5分钟)