it-swarm.com.ru

Как вы кешируете изображение в Javascript?

Я и мои друзья работаем над веб-сайтом, на котором мы хотели бы кэшировать определенные изображения, чтобы быстрее их отображать в будущем. У меня есть два основных вопроса:

  1. Как вы кешируете изображение?
  2. Как вы используете изображение после его кэширования? (и просто для проверки, если изображение кэшируется на странице A, его можно вызвать из кэша, чтобы использовать его на странице B, верно?)

Кроме того, возможно ли установить когда срок хранения кэшированной версии образа истечет?

Было бы очень полезно, если бы был включен пример и/или ссылка на страницу, которая описывает это далее.

Мы в порядке, используя либо сырой Javascript, либо версию jQuery.

60
Logan Besecker

Как только изображение каким-либо образом загружено в браузер, оно будет в кеше браузера и будет загружаться намного быстрее при следующем использовании, независимо от того, используется ли оно на текущей странице или на любой другой странице, если изображение используется до истечения срока его действия из кэша браузера.

Таким образом, для предварительного кэширования изображений все, что вам нужно сделать, это загрузить их в браузер. Если вы хотите предварительно кэшировать кучу изображений, вероятно, лучше всего сделать это с помощью javascript, так как обычно он не задерживает загрузку страницы, когда это делается из javascript. Вы можете сделать это так:

function preloadImages(array) {
    if (!preloadImages.list) {
        preloadImages.list = [];
    }
    var list = preloadImages.list;
    for (var i = 0; i < array.length; i++) {
        var img = new Image();
        img.onload = function() {
            var index = list.indexOf(this);
            if (index !== -1) {
                // remove image from the array once it's loaded
                // for memory consumption reasons
                list.splice(index, 1);
            }
        }
        list.Push(img);
        img.src = array[i];
    }
}

preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"]);

Эту функцию можно вызывать столько раз, сколько вы хотите, и каждый раз она просто добавляет больше изображений в предварительный кеш.

Как только изображения были предварительно загружены с помощью javascript, браузер будет иметь их в своем кэше, и вы можете просто ссылаться на обычные URL-адреса в других местах (на ваших веб-страницах), и браузер будет получать этот URL из своего кэша, а не поверх сеть.

Со временем кеш браузера может заполниться и выбросить самые старые вещи, которые не использовались некоторое время. Таким образом, в конечном итоге изображения будут выгружаться из кэша, но они должны оставаться там некоторое время (в зависимости от размера кэша и объема выполняемого просмотра). Каждый раз, когда изображения на самом деле снова загружаются или используются на веб-странице, они автоматически обновляют свою позицию в кеше браузера, поэтому они с меньшей вероятностью будут выгружены из кеша.

Кэш браузера является межстраничным, поэтому он работает для любой страницы, загруженной в браузер. Таким образом, вы можете предварительно кэшировать в одном месте на вашем сайте, и кеш браузера будет работать для всех других страниц вашего сайта.


При предварительном кэшировании, как описано выше, изображения загружаются асинхронно, поэтому они не будут блокировать загрузку или отображение вашей страницы. Но если на вашей странице много собственных изображений, эти изображения с предварительным кэшированием могут конкурировать за пропускную способность или соединения с изображениями, отображаемыми на вашей странице. Обычно это не заметная проблема, но при медленном соединении такое предварительное кэширование может замедлить загрузку главной страницы. Если все в порядке с предварительно загруженными изображениями, которые загружаются последними, вы можете использовать версию функции, которая будет ждать начала предварительной загрузки до тех пор, пока все другие ресурсы страницы не будут уже загружены.

function preloadImages(array, waitForOtherResources, timeout) {
    var loaded = false, list = preloadImages.list, imgs = array.slice(0), t = timeout || 15*1000, timer;
    if (!preloadImages.list) {
        preloadImages.list = [];
    }
    if (!waitForOtherResources || document.readyState === 'complete') {
        loadNow();
    } else {
        window.addEventListener("load", function() {
            clearTimeout(timer);
            loadNow();
        });
        // in case window.addEventListener doesn't get called (sometimes some resource gets stuck)
        // then preload the images anyway after some timeout time
        timer = setTimeout(loadNow, t);
    }

    function loadNow() {
        if (!loaded) {
            loaded = true;
            for (var i = 0; i < imgs.length; i++) {
                var img = new Image();
                img.onload = img.onerror = img.onabort = function() {
                    var index = list.indexOf(this);
                    if (index !== -1) {
                        // remove image from the array once it's loaded
                        // for memory consumption reasons
                        list.splice(index, 1);
                    }
                }
                list.Push(img);
                img.src = imgs[i];
            }
        }
    }
}

preloadImages(["url1.jpg", "url2.jpg", "url3.jpg"], true);
preloadImages(["url99.jpg", "url98.jpg"], true);
108
jfriend00

как сказал @Pointy, вы не кэшируете изображения с помощью javascript, это делает браузер. так что это может быть тем, о чем вы просите, а может и не быть ... но вы можете предварительно загрузить изображения с помощью JavaScript. Помещая все изображения, которые вы хотите предварительно загрузить в массив, и помещая все изображения в этом массиве в скрытые элементы img, вы эффективно предварительно загружаете (или кэшируете) изображения.

var images = [
'/path/to/image1.png',
'/path/to/image2.png'
];

$(images).each(function() {
var image = $('<img />').attr('src', this);
});
10
Trav McKinney

Есть несколько вещей, на которые вы можете посмотреть:

Предварительная загрузка ваших изображений
Установка времени кеширования в файле .htaccess
Размер файла изображений и их кодировка base64. 

Предварительная загрузка: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

Кэширование: http://www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html

Есть несколько разных соображений относительно кодировки base64, некоторые говорят, что http-запросы замедляют пропускную способность, в то время как другие говорят, что «воспринимаемая» загрузка лучше. Я оставлю это в воздухе.

2
Tim

Даже несмотря на то, что ваш вопрос говорит «использование javascript», вы можете использовать атрибут prefetch тега ссылки для предварительной загрузки любого ресурса. На момент написания статьи (10 августа 2016 г.) он не поддерживается в Safari, но практически везде:

<link rel="prefetch" href="(url)">

Подробнее о поддержке здесь: http://caniuse.com/#search=prefetch

Обратите внимание, что IE 9,10 не перечислены в матрице caniuse, потому что Microsoft прекратила их поддержку.

Так что, если вы действительно застряли на использовании javascript, вы можете использовать jquery для динамического добавления этих элементов на свою страницу ;-)

1
Brad Parks

Я использую подобную технику для отложенной загрузки изображений, но не могу не заметить, что Javascript не обращается к кешу браузера при первой загрузке.

Мой пример:

У меня есть вращающийся баннер на моей домашней странице с 4 изображениями, слайдер ждет 2 секунды, затем JavaScript загружает следующее изображение, ждет 2 секунды и т.д.

Эти изображения имеют уникальные URL, которые меняются каждый раз, когда я их изменяю, поэтому они получают заголовки для кэширования, которые будут кэшироваться в браузере в течение года.

max-age: 31536000, public

Теперь, когда я открываю Chrome Devtools и убеждаюсь, что опция «Отключить кеш» не активна и загружает страницу в первый раз (после очистки кеша), все изображения получают выборку и имеют статус 200. После полного цикла всех изображений в баннере сетевые запросы останавливаются и используются кэшированные изображения. 

Теперь, когда я делаю регулярное обновление или перехожу на подстраницу и нажимаю назад, изображения, которые находятся в кеше, похоже, игнорируются. Я ожидаю увидеть серое сообщение «из дискового кэша» на вкладке «Сеть» Chrome devtools. Вместо этого я вижу, что запросы проходят каждые две секунды с зеленым кружком статуса вместо серого, я вижу, что данные передаются, поэтому создается впечатление, что кеш вообще не доступен из javascript. Он просто выбирает изображение каждый раз, когда страница загружается.

Таким образом, каждый запрос к домашней странице запускает 4 запроса независимо от политики кэширования изображения.

Учитывая вышеизложенное и новый стандарт http2, который теперь поддерживают большинство веб-серверов и браузеров, я думаю, что лучше прекратить lazyloading, поскольку http2 будет загружать все изображения почти одновременно.

Если это ошибка в Chrome Devtools, это действительно удивляет, что никто еще не заметил этого. ;)

Если это правда, использование отложенной загрузки только увеличивает пропускную способность.

Пожалуйста, поправьте меня, если я ошибаюсь. :)

1
Jean-Paul Ladage

У меня есть аналогичный ответ для асинхронной предварительной загрузки изображений через JS. Динамическая загрузка - это то же самое, что и обычная загрузка. они будут кешироваться.

что касается кеширования, вы не можете управлять браузером, но вы можете установить его через сервер. если вам нужно загрузить действительно новый ресурс по требованию, вы можете использовать метод кеширования кеша , чтобы принудительно загрузить новый ресурс.

1
Joseph

Я всегда предпочитаю использовать пример, упомянутый в Konva JS: Image Events для загрузки изображений.

  1. Вам необходимо иметь список URL-адресов изображений в виде объекта или массива, например:

    var sources = { lion: '/assets/lion.png', monkey: '/assets/monkey.png' };

  2. Определите определение функции, где он получает список URL-адресов изображений и функцию обратного вызова в своем списке аргументов, поэтому, когда он завершит загрузку изображения, вы можете запустить excution на своей веб-странице:

    function loadImages(sources, callback) {
                var images = {};
                var loadedImages = 0;
                var numImages = 0;
                for (var src in sources) {
                    numImages++;
                }
                for (var src in sources) {
                    images[src] = new Image();
                    images[src].onload = function () {
                        if (++loadedImages >= numImages) {
                            callback(images);
                        }
                    };
                    images[src].src = sources[src];
                }
            }
  1. Наконец, вам нужно вызвать функцию. Вы можете назвать это, например, из jQuery Документ готов

$(document).ready(function (){ loadImages(sources, buildStage); });

0
Mahdi Alkhatib

Да, браузер автоматически кеширует изображения для вас.

Однако вы можете установить срок действия кэша изображений. Проверьте эти вопросы переполнения стека и ответ:

Срок действия кэша на статических изображениях

0
magzalez