我看到有一些选择可以缓解这种情况。
增强并保留 retina.js 的 HTTP 调用结果缓存
对于任何设置为替换“1x”版本的给定“2x”图像,retina.js 首先通过以下方式验证图像的可用性:XMLHttpRequest
要求。成功响应的路径将缓存在数组中并下载图像。
以下更改可能会提高效率:
Failed XMLHttpRequest
验证尝试可以被缓存:目前,只有先前成功的“2x”路径验证尝试才会被跳过。因此,失败的尝试可能会再次发生。实际上,这并不重要,因为验证过程是在页面最初加载时发生的。但是,如果结果持续存在,跟踪故障将防止 404 错误再次出现。
保留“2x”路径验证结果localStorage
:在初始化期间,retina.js可以检查localStorage
用于结果缓存。如果找到,则可以绕过已遇到的“2x”图像的验证过程,并且可以下载或跳过“2x”图像。可以验证新遇到的“2x”图像路径并将结果添加到缓存中。理论上,虽然localStorage
可用时,每个浏览器上的图像只会出现一次 404 错误。这将适用于域上任何页面的跨页面。
这是一个快速检查。可能需要添加过期功能。
https://gist.github.com/4343101/revisions https://gist.github.com/4343101/revisions
使用 HTTP 重定向标头
我必须指出,我对“服务器端”问题的掌握是spotty, 最好。请收下这个FWIW
另一种选择是服务器使用重定向代码响应具有以下内容的图像请求:@2x
字符且不存在。看这个相关答案 https://stackoverflow.com/a/3778511/1888292.
尤其:
如果您重定向图像并且它们是可缓存的,那么您最好为遥远的将来的某个日期设置 HTTP Expires 标头(以及相应的 Cache-Control 标头),这样至少在后续访问该页面时用户不会再次进行重定向。
使用重定向响应将消除 404 错误,并导致浏览器跳过后续访问不存在的“2x”图像路径的尝试。
retina.js 可以变得更有选择性
可以修改 retinajs 以排除某些图像。
与此相关的拉取请求:https://github.com/imulus/retinajs/commit/e7930be https://github.com/imulus/retinajs/commit/e7930be
根据拉取请求,而不是查找<img>
元素通过标签名称,可以使用 CSS 选择器,这可以是 retina.js 的可配置选项之一。可以创建一个 CSS 选择器来过滤掉用户上传的图像(以及预计不存在“2x”变体的其他图像)。
另一种可能性是向可配置选项添加过滤功能。该函数可以在每个匹配的<img>
元素; Areturn true
会导致下载“2x”变体,其他任何情况都会导致<img>
被跳过。
基本的默认配置将从当前版本 https://github.com/imulus/retinajs/blob/5671145d8a8adf3d72b6b62d8927799f8dd97863/src/retina.js#L5像这样的东西:
var config = {
check_mime_type: true,
retinaImgTagSelector: 'img',
retinaImgFilterFunc: undefined
};
The Retina.init()
函数将从当前版本 https://github.com/imulus/retinajs/blob/5671145d8a8adf3d72b6b62d8927799f8dd97863/src/retina.js#L22像这样的东西:
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
增强。