Сначала загрузите фоновое изображение с низким разрешением, затем с высоким разрешением
Я пытаюсь оптимизировать размер моего сайта, когда он выводится клиенту. Я до 1,9 МБ и 29 КБ при кешировании. Проблема в том, что первая загрузка содержит изображение, которое очень неоптимизировано для мобильных устройств; он имеет разрешение 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
использовать min.bg.jpg
для первой загрузки, а затем что-то вроде этого:
jQuery(function(){
jQuery("body").[...]
});
В каком порядке я буду асинхронно загружать новый фон, а затем вставлять его в качестве нового фонового изображения CSS?
Чтобы показать некоторые отличия, вот пример основной и мини-версии, которую я использую для тестирования:
[email protected] ~/Work/BIRD3/cdn/theme/images $ file *.jpg
bg.jpg: JPEG image data, EXIF standard
min.bg.jpg: JPEG image data, JFIF standard 1.01
[email protected] ~/Work/BIRD3/cdn/theme/images $ du -h *.jpg
1,0M bg.jpg
620K min.bg.jpg
Ответы
Ответ 1
Здесь используется метод...
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 с версией с высоким разрешением.
PURE JS VERSION
Этот пример будет эффективным для изменения одного или нескольких элементов.
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 отличным моментом, что мое решение приводит к тому, что путь изображения указан в трех местах. Хотя я не использовал метод 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
настройки фонового изображения. (Обратите внимание, что CSS также устанавливает div в
размеры.)
- Тем временем фотографии с более высоким разрешением
загружаются как скрытые изображения (все используют имя класса img_highres).
- Функция jQuery запускается каждый раз, когда фото img_highres
завершает загрузку.
- Функция jQuery считывает путь изображения src и
изменяет фоновое изображение соответствующего div. в
пример выше, соглашение об именах является "div_ [name]" для видимых divs
и "img_ [то же имя]" для изображений с высоким разрешением, загруженных в
фон.
Ответ 2
Попробуем простой:
<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
- версия с низким разрешением, а XOYra.jpg
- версия с высоким разрешением.
Если есть способ организовать загрузку, поэтому сначала отображается фоновое изображение, это может быть самым простым, о котором я могу думать.
где низкое разрешение 44k:
![низкое разрешение 44k:]()
а высокое разрешение - 1,16 М
![высокое разрешение - 1,16M]()
результат:
jsFiddled здесь (для загрузки сравнения требуется большее изображение.)
Ответ 3
Немного поздно, но вы можете использовать это чрезвычайно простое решение: вы можете поместить два изображения в фоновом режиме css:
background-image: url("high-res.jpg"),url("low-res.jpg");
Браузер отобразит изображение с низким разрешением, а затем отобразит высокое разрешение по сравнению с низким разрешением, когда оно будет загружено.
Ответ 4
Я бы обычно оптимизировал изображение с помощью 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, упомянутый в статье, выглядит следующим образом:
<script type="text/javascript" async>
function init() {
var imgDefer = document.getElementsByTagName('img');
for (var i=0; i<imgDefer.length; i++) {
if(imgDefer[i].getAttribute('data-src')) {
imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
}
}
}
window.onload = init;
</script>
Надеюсь, это поможет.
Ответ 5
Все ответы, приведенные выше, в основном работают с небольшой корректировкой, но вот способ, который я считаю коротким и простым, чтобы начать.
Замечания:
- Раскомментируйте код, загрузите изображение с высоким разрешением для использования, функция сна просто для имитации медленной сети.
- На самом деле, этот метод не загружает 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>
Ответ 6
В Ubuntu/Chrome 71 ответ Milche не работает для меня согласованно, и изображение с более высоким разрешением (через img src
) часто загружается и разрешается до того, как изображение с более низким разрешением (через background
CSS) даже начинает загружаться.
Мое решение начать с более низким разрешением изображения в качестве src
и использовать Image
класса для создания незакрепленного <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
}
Скрипка: https://jsfiddle.net/25aqmd67/
Этот подход работает для изображений с низким разрешением, которые также просто уменьшаются.
Ответ 7
Вы пробовали использовать спрайты CSS, чтобы помочь получить то, что вы хотите? http://css-tricks.com/css-sprites/