你如何cachingJavascript中的图像

我和我的朋友正在一个网站上工作,我们想要caching某些图片,以便将来更快地展示它们。 我有两个主要问题:

  1. 你如何caching图像?
  2. 一旦它被caching,你如何使用一个图像? (只是为了validation,如果图像caching在页面A上,可以从caching中调用它来在页面B上使用它,对吗?)

另外,是否有可能设置图像的caching版本何时到期?

如果包含一个描述这一点的页面的例子和/或链接,那将是非常值得赞赏的。

我们很好地使用原始的JavaScript或jQuery版本。

一旦图像以任何方式被加载到浏览器中,它将在浏览器caching中,并且在下一次被使用时将加载得更快,无论该使用是在当前页面中还是在任何其他页面中,只要图像是在从浏览器caching到期之前使用。

因此,为了预caching图像,您只需将其加载到浏览器中即可。 如果你想预处理一堆图像,最好用JavaScript来做,因为它通常不会阻止从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) { // remove image from the array once it's loaded // for memory consumption reasons list.splice(index, 1); } } list.push(img); img.src = array[i]; } } preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"]); 

这个function可以多次调用,每次只需要在预caching中添加更多的图片。

一旦图像通过javascript被预加载,浏览器将会把它们放在caching中,你可以在其他地方(在你的网页中)引用正常的URL,浏览器会从caching中取出这个URL,而不是networking。

最终,随着时间的推移,浏览器caching可能会填满并抛弃一段时间内未使用的最古老的东西。 所以最终,图像会从caching中清除,但它们应该停留一段时间(取决于caching的大小以及其他浏览的大小)。 每次图像实际上再次预加载或在网页中使用,它会自动刷新其在浏览器caching中的位置,使其不太可能从caching中清除。

浏览器caching是跨页面的,所以它适用于加载到浏览器的任何页面。 因此,您可以在网站的某个位置进行预caching,然后浏览器caching将适用于您网站上的所有其他页面。


当像上面那样预先存储时,图像被asynchronous加载,所以它们不会阻止加载或显示你的页面。 但是,如果您的页面拥有大量自己的图像,则这些预caching图像可能会与您的页面中显示的图像竞争带宽或连接。 通常情况下,这不是一个明显的问题,但是在连接速度较慢的情况下,此预caching可能会减慢主页面的加载速度。 如果最后加载的是预加载图像,那么可以使用一个等待开始预加载的函数版本,直到所有其他页面资源已经加载完成。

 function preloadImages(array, waitForOtherResources, timeout) { var loaded = false, list = preloadImages.list, imgs = array.slice(0), t = timeout || 15*1000, timer; if (!preloadImages.list) { preloadImages.list = []; } if (!waitForOtherResources || document.readyState === 'complete') { loadNow(); } else { window.addEventListener("load", function() { clearTimeout(timer); loadNow(); }); // in case window.addEventListener doesn't get called (sometimes some resource gets stuck) // then preload the images anyway after some timeout time timer = setTimeout(loadNow, t); } function loadNow() { if (!loaded) { loaded = true; for (var i = 0; i < imgs.length; i++) { var img = new Image(); img.onload = img.onerror = img.onabort = function() { var index = list.indexOf(this); if (index !== -1) { // remove image from the array once it's loaded // for memory consumption reasons list.splice(index, 1); } } list.push(img); img.src = imgs[i]; } } } } preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"], true); preloadImages(["url99.jpg", "url98.jpg"], true); 

因为@Pointy表示你不用JavaScript来caching图片,浏览器就是这么做的。 所以这可能是你要求,可能不是…但你可以预装图像使用JavaScript。 通过将所有要预加载的图像放入数组中,并将该数组中的所有图像置于隐藏的img元素中,可以有效地预加载(或caching)图像。

 var images = [ '/path/to/image1.png', '/path/to/image2.png' ]; $(images).each(function() { var image = $('<img />').attr('src', this); }); 

有几件事你可以看看:

预加载您的图像
在.htaccess文件中设置caching时间
图像的文件大小和base64编码。

预加载: http : //perishablepress.com/3-ways-preload-images-css-javascript-ajax/

caching: http : //www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html

对于base64编码,有两种不同的想法,有人说http请求带宽枯竭,而另外一些人则认为“感知”加载更好。 我会把它留在空中。

我有一个类似的答案通过JSasynchronous预加载图像。 dynamic加载它们与正常加载它们相同。 他们会caching。

至于caching,你不能控制浏览器,但你可以通过服务器来设置它。 如果您需要按需加载真正新鲜的资源,则可以使用caching破坏技术强制加载新的资源。

即使您的问题显示为“使用JavaScript”,您也可以使用链接标记的prefetch属性预先加载任何资源。 截至撰写本文时(2016年8月10日),Safari并不支持,但几乎在其他地方:

<link rel="prefetch" href="(url)">

更多信息请访问http://caniuse.com/#search=prefetch

请注意,IE 9,10未在caniusematrix中列出,因为Microsoft已经停止了对它们的支持。

所以,如果你真的被困在使用JavaScript,你可以使用jQuery来dynamic地添加这些元素到您的网页以及;-)

我使用类似的技术来延迟加载图像,但不能不注意到Javascript在第一次加载时不能访问浏览器caching。

我的例子:

我在我的主页上有一个旋转的旗帜,4个图像滑块等待2秒,比JavaScript加载下一个图像,等待2秒,等等。

这些图像具有独特的URL,只要我修改它们就可以改变,所以他们得到caching标题,将caching在浏览器一年。

 max-age: 31536000, public 

现在,当我打开Chrome Devtools并确保“禁用caching”选项未激活并首次加载页面(清除caching后)时,所有图像都将获取并具有200状态。 在横幅中的所有图像的完整周期之后,networking请求停止并且使用高速caching的图像。

现在,当我进行常规刷新或转到子页面并点击后,caching中的图像似乎被忽略。 我期望在Chrome devtools的“networking”选项卡中看到一条灰色的“从磁盘caching”消息。 相反,我看到请求每两秒传递一个绿色的状态圈,而不是灰色的,我看到数据被传输,所以我得到的印象是从caching不被访问的JavaScript。 它只是每次页面加载时获取图像。

因此,无论图像的caching策略如何,对主页的每个请求都会触发4个请求。

考虑到上面的一起,现在大多数networking服务器和浏览器支持新的http2标准,我认为最好停止使用lazyloading,因为http2将几乎同时加载所有图像。

如果这是Chrome Devtools中的一个bug,那真的让人惊讶,我没有人注意到这一点。 ;)

如果这是真的,使用lazyloading只会增加带宽使用。

如果我错了,请纠正我。 🙂

是的,浏览器会自动为您caching图像。

但是,您可以将图像caching设置为过期。 看看这个堆栈溢出的问题和答案:

caching到期静态图像

我总是喜欢使用Konva JS中提到的示例:Image Events来加载图像。

  1. 您需要将图像URL列表作为对象或数组,例如:

    var sources = { lion: '/assets/lion.png', monkey: '/assets/monkey.png' };

  2. 定义函数定义,它在其参数列表中接收图像URL列表和callback函数,因此当它完成加载图像时,您可以开始在您的网页上执行:

  function loadImages(sources, callback) { var images = {}; var loadedImages = 0; var numImages = 0; for (var src in sources) { numImages++; } for (var src in sources) { images[src] = new Image(); images[src].onload = function () { if (++loadedImages >= numImages) { callback(images); } }; images[src].src = sources[src]; } }