首先加载低分辨率背景图像,然后加载高分辨率背景图像
Load a low-res background image first, then a high-res one
我正在尝试在将网站输出到客户端时优化网站的大小。缓存时我下降到 1.9MB 和 29KB。问题是第一次加载包含的图像对于移动设备来说是非常不优化的;它具有 1080p 分辨率。
所以我正在寻找一种方法,允许我首先加载低分辨率版本 (min.bg.jpg
),一旦网站加载完毕,使用高分辨率版本 - 甚至是具有分辨率的版本靠近正在使用的设备(NNNxNNN.bg.jpg
或 bg.jpg
)。
背景是使用 CSS 设置的,正如大家所期望的那样。它应用于正文,整个语句如下所示:
body {
background: url("/cdn/theme/images/bg.jpg");
color: white;
height: 100%;
width: 100%;
background-repeat: no-repeat;
background-position: 50% 50%;
background-attachment: fixed;
}
现在,我想将其更改为使用 min.bg.jpg
而不是第一次加载,然后是这样的:
jQuery(function(){
jQuery("body").[...]
});
我应该用哪种方式继续异步下载新背景,然后将其作为新 CSS 背景图片插入?
为了显示一些差异,这里是我用于测试的主要版本和迷你版本的示例:
Ingwie@Ingwies-Macbook-Pro.local ~/Work/BIRD3/cdn/theme/images $ file *.jpg
bg.jpg: JPEG image data, EXIF standard
min.bg.jpg: JPEG image data, JFIF standard 1.01
Ingwie@Ingwies-Macbook-Pro.local ~/Work/BIRD3/cdn/theme/images $ du -h *.jpg
1,0M bg.jpg
620K min.bg.jpg
这是我使用的方法...
CSS:
#div_whatever {
position: whatever;
background-repeat: no-repeat;
background-position: whatever whatever;
background-image: url(dir/image.jpg);
/* image.jpg is a low-resolution at 30% quality. */
}
#img_highQuality {
display: none;
}
HTML:
<img id="img_highQuality" src="dir/image.png">
<!-- img.png is a full-resolution image. -->
<div id="div_whatever"></div>
JQUERY:
$("#img_highQuality").off().on("load", function() {
$("#div_whatever").css({
"background-image" : "url(dir/image.png)"
});
});
// Side note: I usually define CSS arrays because
// I inevitably want to go back and add another
// property at some point.
发生了什么:
- 快速加载背景的低分辨率版本。
- 同时,高分辨率版本作为隐藏图像加载。
- 加载高分辨率图像时,jQuery 将 div 的低分辨率图像替换为高分辨率版本。
纯 JS 版本
此示例对于更改一对多元素非常有效。
CSS:
.hidden {
display: none;
}
#div_whatever {
position: whatever;
background-repeat: no-repeat;
background-position: whatever whatever;
background-image: url(dir/image.jpg);
/* image.jpg is a low-resolution at 30% quality. */
}
HTML:
<div id="div_whatever"></div>
<img id="img_whatever" class="hidden" src="dir/image.png" onload="upgradeImage(this);">
JAVASCRIPT:
function upgradeImage(object) {
var id = object.id;
var target = "div_" + id.substring(4);
document.getElementById(target).style.backgroundImage = "url(" + object.src + ")";
}
更新/增强(1/31/2017)
此增强功能受到 gdbj's excellent point that my solution results in the image path being specified in three locations. Although I didn't use gdbj 的 addClass() 技术的启发,修改了以下 jQuery 代码以提取图像路径(而不是硬连线到 jQuery代码)。更重要的是,此版本允许将多个低分辨率图像替换为高分辨率图像。
CSS
.img_highres {
display: none;
}
#div_whatever1 {
width: 100px;
height: 100px;
background-repeat: no-repeat;
background-position: center center;
background-image: url(PATH_TO_LOW_RES_PHOTO_1);
}
#div_whatever2 {
width: 200px;
height: 200px;
background-repeat: no-repeat;
background-position: center center;
background-image: url(PATH_TO_LOW_RES_PHOTO_2);
}
HTML
<div id="div_whatever1"></div>
<img id="img_whatever1" class="img_highres" src="PATH_TO_HIGH_RES_PHOTO_1">
<div id="div_whatever2"></div>
<img id="img_whatever2" class="img_highres" src="PATH_TO_HIGH_RES_PHOTO_2">
JQUERY
$(function() {
$(".img_highres").off().on("load", function() {
var id = $(this).attr("id");
var highres = $(this).attr("src").toString();
var target = "#div_" + id.substring(4);
$(target).css("background-image", "url(" + highres + ")");
});
});
发生了什么:
- 根据 CSS 为每个 div 加载低分辨率图像
背景图像设置。 (请注意,CSS 还将 div 设置为预期的
尺寸。)
- 与此同时,正在处理更高分辨率的照片
作为隐藏图像加载(全部共享 class 名称 img_highres)。
- 每张img_highres张照片触发一个jQuery函数
完成加载。
- jQuery函数读取图片src路径,并
更改相应 div 的背景图像。在里面
上面的例子,可见的 divs 的命名约定是 "div_[name]"
和 "img_[same name]" 用于加载在
背景。
我通常会使用 Grunt 或 Tiny PNG 等在线工具优化图像以减小文件大小。
然后你可以选择延迟加载图像,我发现以下文章对延迟图像很有帮助 - https://www.feedthebot.com/pagespeed/defer-images.html
本文讨论了使用 base64 图像进行初始加载,然后延迟加载高质量图像。文中提到的图片标注如下...
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="your-image-here">
文中提到的JavaScript如下...
window.addEventListener("load", () => {
const images = document.querySelectorAll("img");
for (let img of images)
if (img.hasAttribute("data-src"))
img.src = imgDefer[i].getAttribute("data-src");
});
希望对您有所帮助。
让我们试试基本的:
<img border="0"
style="background:url(http://i.stack.imgur.com/zWfJ5.jpg) no-repeat;
width:1920px;
height:1200px"
src="http://i.stack.imgur.com/XOYra.jpg" width="1920" height="1200" />
zWfJ5.jpg
是low-resolution版本,XOYra.jpg
是high-resolution版本。
如果有一种方法可以安排加载以便 background-image 先显示,这可能是我能想到的最简单的方法。
其中低分辨率 44k:
高分辨率为1.16M
结果:
jsFiddled here(加载比较需要更大的图片。)
有点晚了,但您可以使用这个极其简单的解决方案:
您可以将两张图片放在css背景中:
background-image: url("high-res.jpg"),url("low-res.jpg");
浏览器会先显示 low-res 图片,然后在加载后在 low-res 上显示 high-res。
上面的所有答案大多都需要稍作调整,但这是我认为简短而简单的开始方式。
注:
- 取消注释代码加载高分辨率图像以供使用,休眠功能仅用于模拟慢速网络。
- 实际上,此方法不会同时加载 2 个资源(低和高),但这是可以接受的,因为低资源不会花费太多时间来加载。
- 只需复制整个代码并运行进行快速检查。
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<style type="text/css">
</style>
</head>
<body>
<!-- Load low res image first -->
<img style="width: 400px; height: auto;" alt="" src="https://s3-ap-southeast-1.amazonaws.com/wheredat/banner-low-quality/banner_20180725_123048.jpg" onload="upgrade(this)">
</body>
<script type="text/javascript">
function upgrade(image){
// After load low res image, remove onload listener.
// Remove onload listener.
$(image).prop("onload", null);
// Load high resolution image.
// $(image).attr('src', 'https://s3-ap-southeast-1.amazonaws.com/wheredat/banner/banner_20180725_123048.jpeg');
// Simulate slow network, after 1.5s, the high res image loads.
sleep(1500).then(() => {
// Do something after the sleep!
// Load a high resolution image.
$(image).attr('src', 'https://s3-ap-southeast-1.amazonaws.com/wheredat/banner/banner_20180725_123048.jpeg');
});
}
// Sleep time expects milliseconds
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
</script>
</html>
在 Ubuntu / Chrome 71 上,Milche 的回答对我来说并不一致,高分辨率图像(通过 img src
)经常在较低分辨率图像之前加载和解析( via css background
) 甚至开始下载。
我的解决方案是从低分辨率图像开始作为 src
并使用 Image
class 创建一个带有高分辨率图像的独立 <img>
实例.加载后,使用高分辨率图像源更新现有 <img>
源。
HTML:
<img id='my-image' src='low-res.png' alt='Title' width='1920px' height='1200px'>
JavaScript:
window.addEventListener('load', function() {
loadHighResImage(document.getElementById('my-image'), 'high-res.png')
})
function loadHighResImage(elem, highResUrl) {
let image = new Image()
image.addEventListener('load', () => elem.src = highResUrl)
image.src = highResUrl
}
Fiddle: https://jsfiddle.net/25aqmd67/
这种方法也适用于简单缩小的低分辨率图像。
我正在尝试在将网站输出到客户端时优化网站的大小。缓存时我下降到 1.9MB 和 29KB。问题是第一次加载包含的图像对于移动设备来说是非常不优化的;它具有 1080p 分辨率。
所以我正在寻找一种方法,允许我首先加载低分辨率版本 (min.bg.jpg
),一旦网站加载完毕,使用高分辨率版本 - 甚至是具有分辨率的版本靠近正在使用的设备(NNNxNNN.bg.jpg
或 bg.jpg
)。
背景是使用 CSS 设置的,正如大家所期望的那样。它应用于正文,整个语句如下所示:
body {
background: url("/cdn/theme/images/bg.jpg");
color: white;
height: 100%;
width: 100%;
background-repeat: no-repeat;
background-position: 50% 50%;
background-attachment: fixed;
}
现在,我想将其更改为使用 min.bg.jpg
而不是第一次加载,然后是这样的:
jQuery(function(){
jQuery("body").[...]
});
我应该用哪种方式继续异步下载新背景,然后将其作为新 CSS 背景图片插入?
为了显示一些差异,这里是我用于测试的主要版本和迷你版本的示例:
Ingwie@Ingwies-Macbook-Pro.local ~/Work/BIRD3/cdn/theme/images $ file *.jpg
bg.jpg: JPEG image data, EXIF standard
min.bg.jpg: JPEG image data, JFIF standard 1.01
Ingwie@Ingwies-Macbook-Pro.local ~/Work/BIRD3/cdn/theme/images $ du -h *.jpg
1,0M bg.jpg
620K min.bg.jpg
这是我使用的方法...
CSS:
#div_whatever {
position: whatever;
background-repeat: no-repeat;
background-position: whatever whatever;
background-image: url(dir/image.jpg);
/* image.jpg is a low-resolution at 30% quality. */
}
#img_highQuality {
display: none;
}
HTML:
<img id="img_highQuality" src="dir/image.png">
<!-- img.png is a full-resolution image. -->
<div id="div_whatever"></div>
JQUERY:
$("#img_highQuality").off().on("load", function() {
$("#div_whatever").css({
"background-image" : "url(dir/image.png)"
});
});
// Side note: I usually define CSS arrays because
// I inevitably want to go back and add another
// property at some point.
发生了什么:
- 快速加载背景的低分辨率版本。
- 同时,高分辨率版本作为隐藏图像加载。
- 加载高分辨率图像时,jQuery 将 div 的低分辨率图像替换为高分辨率版本。
纯 JS 版本
此示例对于更改一对多元素非常有效。
CSS:
.hidden {
display: none;
}
#div_whatever {
position: whatever;
background-repeat: no-repeat;
background-position: whatever whatever;
background-image: url(dir/image.jpg);
/* image.jpg is a low-resolution at 30% quality. */
}
HTML:
<div id="div_whatever"></div>
<img id="img_whatever" class="hidden" src="dir/image.png" onload="upgradeImage(this);">
JAVASCRIPT:
function upgradeImage(object) {
var id = object.id;
var target = "div_" + id.substring(4);
document.getElementById(target).style.backgroundImage = "url(" + object.src + ")";
}
更新/增强(1/31/2017)
此增强功能受到 gdbj's excellent point that my solution results in the image path being specified in three locations. Although I didn't use gdbj 的 addClass() 技术的启发,修改了以下 jQuery 代码以提取图像路径(而不是硬连线到 jQuery代码)。更重要的是,此版本允许将多个低分辨率图像替换为高分辨率图像。
CSS
.img_highres {
display: none;
}
#div_whatever1 {
width: 100px;
height: 100px;
background-repeat: no-repeat;
background-position: center center;
background-image: url(PATH_TO_LOW_RES_PHOTO_1);
}
#div_whatever2 {
width: 200px;
height: 200px;
background-repeat: no-repeat;
background-position: center center;
background-image: url(PATH_TO_LOW_RES_PHOTO_2);
}
HTML
<div id="div_whatever1"></div>
<img id="img_whatever1" class="img_highres" src="PATH_TO_HIGH_RES_PHOTO_1">
<div id="div_whatever2"></div>
<img id="img_whatever2" class="img_highres" src="PATH_TO_HIGH_RES_PHOTO_2">
JQUERY
$(function() {
$(".img_highres").off().on("load", function() {
var id = $(this).attr("id");
var highres = $(this).attr("src").toString();
var target = "#div_" + id.substring(4);
$(target).css("background-image", "url(" + highres + ")");
});
});
发生了什么:
- 根据 CSS 为每个 div 加载低分辨率图像 背景图像设置。 (请注意,CSS 还将 div 设置为预期的 尺寸。)
- 与此同时,正在处理更高分辨率的照片 作为隐藏图像加载(全部共享 class 名称 img_highres)。
- 每张img_highres张照片触发一个jQuery函数 完成加载。
- jQuery函数读取图片src路径,并 更改相应 div 的背景图像。在里面 上面的例子,可见的 divs 的命名约定是 "div_[name]" 和 "img_[same name]" 用于加载在 背景。
我通常会使用 Grunt 或 Tiny PNG 等在线工具优化图像以减小文件大小。
然后你可以选择延迟加载图像,我发现以下文章对延迟图像很有帮助 - https://www.feedthebot.com/pagespeed/defer-images.html
本文讨论了使用 base64 图像进行初始加载,然后延迟加载高质量图像。文中提到的图片标注如下...
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="your-image-here">
文中提到的JavaScript如下...
window.addEventListener("load", () => {
const images = document.querySelectorAll("img");
for (let img of images)
if (img.hasAttribute("data-src"))
img.src = imgDefer[i].getAttribute("data-src");
});
希望对您有所帮助。
让我们试试基本的:
<img border="0"
style="background:url(http://i.stack.imgur.com/zWfJ5.jpg) no-repeat;
width:1920px;
height:1200px"
src="http://i.stack.imgur.com/XOYra.jpg" width="1920" height="1200" />
zWfJ5.jpg
是low-resolution版本,XOYra.jpg
是high-resolution版本。
如果有一种方法可以安排加载以便 background-image 先显示,这可能是我能想到的最简单的方法。
其中低分辨率 44k:
高分辨率为1.16M
结果:
jsFiddled here(加载比较需要更大的图片。)
有点晚了,但您可以使用这个极其简单的解决方案: 您可以将两张图片放在css背景中:
background-image: url("high-res.jpg"),url("low-res.jpg");
浏览器会先显示 low-res 图片,然后在加载后在 low-res 上显示 high-res。
上面的所有答案大多都需要稍作调整,但这是我认为简短而简单的开始方式。
注:
- 取消注释代码加载高分辨率图像以供使用,休眠功能仅用于模拟慢速网络。
- 实际上,此方法不会同时加载 2 个资源(低和高),但这是可以接受的,因为低资源不会花费太多时间来加载。
- 只需复制整个代码并运行进行快速检查。
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<style type="text/css">
</style>
</head>
<body>
<!-- Load low res image first -->
<img style="width: 400px; height: auto;" alt="" src="https://s3-ap-southeast-1.amazonaws.com/wheredat/banner-low-quality/banner_20180725_123048.jpg" onload="upgrade(this)">
</body>
<script type="text/javascript">
function upgrade(image){
// After load low res image, remove onload listener.
// Remove onload listener.
$(image).prop("onload", null);
// Load high resolution image.
// $(image).attr('src', 'https://s3-ap-southeast-1.amazonaws.com/wheredat/banner/banner_20180725_123048.jpeg');
// Simulate slow network, after 1.5s, the high res image loads.
sleep(1500).then(() => {
// Do something after the sleep!
// Load a high resolution image.
$(image).attr('src', 'https://s3-ap-southeast-1.amazonaws.com/wheredat/banner/banner_20180725_123048.jpeg');
});
}
// Sleep time expects milliseconds
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
</script>
</html>
在 Ubuntu / Chrome 71 上,Milche 的回答对我来说并不一致,高分辨率图像(通过 img src
)经常在较低分辨率图像之前加载和解析( via css background
) 甚至开始下载。
我的解决方案是从低分辨率图像开始作为 src
并使用 Image
class 创建一个带有高分辨率图像的独立 <img>
实例.加载后,使用高分辨率图像源更新现有 <img>
源。
HTML:
<img id='my-image' src='low-res.png' alt='Title' width='1920px' height='1200px'>
JavaScript:
window.addEventListener('load', function() {
loadHighResImage(document.getElementById('my-image'), 'high-res.png')
})
function loadHighResImage(elem, highResUrl) {
let image = new Image()
image.addEventListener('load', () => elem.src = highResUrl)
image.src = highResUrl
}
Fiddle: https://jsfiddle.net/25aqmd67/
这种方法也适用于简单缩小的低分辨率图像。