我看到有几个选项可以缓解这种情况。
增强和持久化retina.js 的HTTP 调用结果缓存
对于设置为换出“1x”版本的任何给定“2x”图像,retina.js 首先通过XMLHttpRequest
请求验证图像的可用性。成功响应的路径被缓存在一个数组中并下载图像。
以下更改可能会提高效率:
XMLHttpRequest
可以缓存失败的验证尝试:目前,仅当先前成功时才跳过“2x”路径验证尝试。因此,失败的尝试可能会再次发生。实际上,这并不重要,因为验证过程发生在页面最初加载时。但是,如果结果保持不变,跟踪失败将防止重复出现 404 错误。
Persist '2x' 路径验证结果localStorage
:在初始化期间,retina.js 可以检查localStorage
结果缓存。如果找到,则可以绕过对已经遇到的“2x”图像的验证过程,并且可以下载或跳过“2x”图像。可以验证新遇到的“2x”图像路径并将结果添加到缓存中。理论上,虽然localStorage
可用,但对于每个浏览器的图像,404 只会出现一次。这将适用于域上任何页面的页面。
这是一个快速检查。可能需要添加过期功能。
https://gist.github.com/4343101/revisions
使用 HTTP 重定向标头
我必须指出,我对“服务器端”问题的理解充其量是参差不齐的。请收下这个 FWIW
另一种选择是让服务器使用重定向代码响应具有@2x
字符但不存在的图像请求。请参阅此相关答案。
尤其:
如果您重定向图像并且它们是可缓存的,那么理想情况下,您会为遥远的将来的某个日期设置一个 HTTP Expires 标头(以及相应的 Cache-Control 标头),因此至少在用户后续访问该页面时不会有再次通过重定向。
使用重定向响应将摆脱 404 并导致浏览器跳过后续尝试访问不存在的“2x”图像路径。
可以使retina.js 更具选择性
可以修改retinajs 以排除某些图像。
与此相关的拉取请求:https ://github.com/imulus/retinajs/commit/e7930be
根据拉取请求,<img>
可以使用 CSS 选择器,而不是按标签名称查找元素,这可以是 Retina.js 的可配置选项之一。可以创建一个 CSS 选择器来过滤掉用户上传的图像(以及其他预期不存在“2x”变体的图像)。
另一种可能性是将过滤器功能添加到可配置选项中。可以在每个匹配的<img>
元素上调用该函数;areturn true
将导致下载“2x”变体,其他任何内容都会导致<img>
跳过。
基本的默认配置将从当前版本更改为:
var config = {
check_mime_type: true,
retinaImgTagSelector: 'img',
retinaImgFilterFunc: undefined
};
该Retina.init()
功能将从当前版本更改为:
Retina.init = function(context) {
if (context == null) context = root;
var existing_onload = context.onload || new Function;
context.onload = function() {
// uses new query selector
var images = document.querySelectorAll(config.retinaImgTagSelector),
retinaImages = [], i, image, filter;
// if there is a filter, check each image
if (typeof config.retinaImgFilterFunc === 'function') {
filter = config.retinaImgFilterFunc;
for (i = 0; i < images.length; i++) {
image = images[i];
if (filter(image)) {
retinaImages.push(new RetinaImage(image));
}
}
} else {
for (i = 0; i < images.length; i++) {
image = images[i];
retinaImages.push(new RetinaImage(image));
}
}
existing_onload();
}
};
为了将其付诸实践,在window.onload
火灾之前,请致电:
window.Retina.configure({
// use a class 'no-retina' to prevent retinajs
// from checking for a retina version
retinaImgTagSelector : 'img:not(.no-retina)',
// or, assuming there is a data-owner attribute
// which indicates the user that uploaded the image:
// retinaImgTagSelector : 'img:not([data-owner])',
// or set a filter function that will exclude images that have
// the current user's id in their path, (assuming there is a
// variable userId in the global scope)
retinaImgFilterFunc: function(img) {
return img.src.indexOf(window.userId) < 0;
}
});
更新:清理和重组。添加了localStorage
增强功能。