当必须首先在服务器上生成图像时,将图像异步预加载到浏览器缓存中
Posted
技术标签:
【中文标题】当必须首先在服务器上生成图像时,将图像异步预加载到浏览器缓存中【英文标题】:Preload images asynchronously into the browser cache when the image has to be generated on the server first 【发布时间】:2015-02-12 08:27:05 【问题描述】:已经阅读 *** 几年了,但从未发布过。直到今天 - 遇到了一个我自己无法解决的问题,也没有找到解决方案。
场景:我有一个动态网页,基本上显示网站的截图。这些屏幕截图是为每个新用户动态生成的,并且他们的 URL 会发生变化。我想将这些图像预加载到浏览器缓存中,这样一旦用户单击链接,它们就可以在 0 毫秒内使用。我不希望页面的主观加载时间增加,所以它们必须在后台隐形加载。
我的方法: 我使用 jelastic 作为我的基础架构以便以后能够扩展,然后安装了带有 nginx、php 和 PhantomJS 的 centOS。我用PHP查询phantomJS做截图:
exec("phantomjs engine.js ".$source." ".$filez." > /dev/null &");
dev/null 用于不增加用户的加载时间。 我将链接输出到浏览器。到目前为止它有效。现在我想预加载这些图片:
for (var i = 0; i < document.links.length; i++)
imgArray[i] = new Image(1,1);
imgArray[i].visibility = 'hidden';
imgArray[i].src = (document.links[i].href.substr(7) + ".png");
document.links[i].href = 'javascript: showtouser("' + imgArray[i].src.substr(7) + '");';
我可能在这里做错了两件事:
我在服务器上生成图像之前启动图像预加载。我还没有找到一种方法来仅在 phantomJS 生成图像后才开始缓存。 Onload 事件显然在这里不起作用。 我认为我的方法并不是真正的异步,它会增加用户感受到的主观加载时间我做错了什么?我是 ISP 人,我很擅长 javascript :/
【问题讨论】:
【参考方案1】:你的方法是异步的。您需要一种机制来识别未加载的图像并重试。
此脚本将预加载图像,如果失败则重试,并隐藏重试后仍不存在的图像链接 (demo):
var links = Array.prototype.slice.call(document.links, 0); // Converting links to a normal array
links.forEach(prepareImageLink);
function prepareImageLink(link)
var retries = 3; // current image number of retries
var image = new Image();
/** option: hide all links then reveal those with preloaded image
link.style.visibility = 'hidden';
image.onload = function()
link.style.visibility = '';
;
**/
image.onerror = function()
if(retries === 0)
link.style.visibility = 'hidden'; // hide the link if image doesn't exist
//link.remove(); // option - remove the link if image doesn't exist
return;
retries--;
setTimeout(function()
image.src = image.src + '?' + Date.now(); // for image to reload by adding the current dateTime to url
, 1000); // the amount of time to wait before retry, change it to fit you're system
;
image.src = (link.href + ".png"); // add .substr(7) in your case
/** This is instead of 'javascript: showtouser("' + imgArray[i].src.substr(7) + '");'; which won't work on some browsers **/
link.addEventListener('mouseover', function()
document.getElementById('image').src = image.src; // change to your showtouser func
);
【讨论】:
以上是关于当必须首先在服务器上生成图像时,将图像异步预加载到浏览器缓存中的主要内容,如果未能解决你的问题,请参考以下文章