Mis amigos y yo estamos trabajando en un sitio web donde nos gustaría almacenar en caché ciertas imágenes para mostrarlas más rápido en el futuro. Tengo dos preguntas principales:
- ¿Cómo se almacena en caché una imagen?
- ¿Cómo se usa una imagen una vez que se ha almacenado en caché? (y solo para verificar, si una imagen está almacenada en caché en la página A, es posible llamarla desde la caché para usarla en la página B, ¿verdad?)
Además, ¿es posible establecer cuándo caducará la versión en caché de la imagen?
Se agradecería mucho si se incluyera un ejemplo y / o un enlace a una página que describa esto con más detalle.
Estamos bien usando Javascript sin formato o la versión jQuery.
javascript
jquery
image
caching
browser-cache
Logan Besecker
fuente
fuente
Respuestas:
Una vez que una imagen se ha cargado de alguna manera en el navegador, estará en la caché del navegador y se cargará mucho más rápido la próxima vez que se use, ya sea que ese uso sea en la página actual o en cualquier otra página, siempre que la imagen sea utilizado antes de que expire de la caché del navegador.
Por lo tanto, para almacenar en caché las imágenes, todo lo que tiene que hacer es cargarlas en el navegador. Si desea almacenar en caché un montón de imágenes, probablemente sea mejor hacerlo con javascript, ya que generalmente no retendrá la carga de la página cuando se hace desde javascript. Puedes hacerlo así:
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"]);
Esta función se puede llamar tantas veces como desee y cada vez, solo agregará más imágenes al precaché.
Una vez que las imágenes se han precargado de esta manera a través de javascript, el navegador las tendrá en su caché y usted puede simplemente consultar las URL normales en otros lugares (en sus páginas web) y el navegador obtendrá esa URL de su caché en lugar de hacerlo a través del red.
Eventualmente, con el tiempo, el caché del navegador puede llenarse y deshacerse de las cosas más antiguas que no se han usado por un tiempo. Entonces, eventualmente, las imágenes se borrarán del caché, pero deberían permanecer allí por un tiempo (dependiendo de qué tan grande sea el caché y cuántas otras búsquedas se realicen). Cada vez que las imágenes se precargan de nuevo o se utilizan en una página web, actualiza su posición en la caché del navegador automáticamente para que sea menos probable que se vacíen de la caché.
La caché del navegador es entre páginas, por lo que funciona para cualquier página cargada en el navegador. Por lo tanto, puede almacenar previamente en un lugar de su sitio y la caché del navegador funcionará para todas las demás páginas de su sitio.
Al almacenar en caché como se indicó anteriormente, las imágenes se cargan de forma asincrónica para que no bloqueen la carga o visualización de su página. Pero, si su página tiene muchas imágenes propias, estas imágenes precaché pueden competir por ancho de banda o conexiones con las imágenes que se muestran en su página. Normalmente, este no es un problema notable, pero en una conexión lenta, este almacenamiento en caché podría ralentizar la carga de la página principal. Si estaba bien que las imágenes de precarga se cargaran en último lugar, entonces podría usar una versión de la función que esperaría para iniciar la precarga hasta que todos los demás recursos de la página ya estuvieran cargados.
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);
fuente
Image()
elemento de la lista cuando la imagen termina de cargarse. Es más seguro esperar hasta que la imagen haya terminado de cargarse.como @Pointy dijo que no almacena imágenes en caché con javascript, el navegador lo hace. así que esto puede ser lo que estás pidiendo y puede que no lo sea ... pero puedes precargar imágenes usando javascript. Al colocar todas las imágenes que desea precargar en una matriz y colocar todas las imágenes de esa matriz en elementos img ocultos, efectivamente precarga (o almacena en caché) las imágenes.
var images = [ '/path/to/image1.png', '/path/to/image2.png' ]; $(images).each(function() { var image = $('<img />').attr('src', this); });
fuente
Hay algunas cosas que puede ver:
Cargar previamente sus imágenes
Establecer un tiempo de caché en un archivo .htaccess Tamaño de
archivo de imágenes y codificarlas en base64.
Precarga: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/
Almacenamiento en caché: http://www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html
Hay un par de ideas diferentes para la codificación base64, algunos dicen que las solicitudes http atascan el ancho de banda, mientras que otros dicen que la carga "percibida" es mejor. Dejaré esto en el aire.
fuente
Aunque su pregunta dice "usando javascript", puede usar el
prefetch
atributo de una etiqueta de enlace para precargar cualquier activo. En el momento de escribir este artículo (10 de agosto de 2016) no es compatible con Safari, pero está prácticamente en cualquier otro lugar:<link rel="prefetch" href="(url)">
Más información sobre soporte aquí: http://caniuse.com/#search=prefetch
Tenga en cuenta que IE 9,10 no se enumeran en la
caniuse
matriz porque Microsoft ha descontinuado el soporte para ellos.Entonces, si estaba realmente atascado en el uso de JavaScript, también podría usar jquery para agregar dinámicamente estos elementos a su página ;-)
fuente
Agregar para completar las respuestas: precarga con HTML
<link rel="preload" href="bg-image-wide.png" as="image">
Existen otras características de precarga, pero ninguna es tan adecuada para su propósito como
<link rel="preload">
:<link rel="prefetch">
ha sido compatible con los navegadores durante mucho tiempo, pero está destinado a la obtención previa de recursos que se utilizarán en la siguiente navegación / carga de página (por ejemplo, cuando vaya a la página siguiente). Esto está bien, ¡pero no es útil para la página actual! Además, los navegadores darán menos prioridad a los recursos de captación previa que a los de precarga: la página actual es más importante que la siguiente. Consulte Preguntas frecuentes sobre la obtención previa de enlaces para obtener más detalles.<link rel="prerender">
renderiza una página web específica en segundo plano, acelerando su carga si el usuario navega hacia ella. Debido al potencial de desperdiciar el ancho de banda de los usuarios, Chrome trata el procesamiento previo como una captura previa NoState.<link rel="subresource">
era compatible con Chrome hace un tiempo, y estaba destinado a abordar el mismo problema que la precarga, pero tenía un problema: no había forma de determinar una prioridad para los elementos (ya que no existía en ese entonces), por lo que todos fue recuperado con una prioridad bastante baja.Hay varios cargadores de recursos basados en scripts, pero no tienen ningún poder sobre la cola de priorización de búsqueda del navegador y están sujetos a los mismos problemas de rendimiento.
Fuente: https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
fuente
Tengo una respuesta similar para imágenes de precarga asíncrona a través de JS. Cargarlos dinámicamente es lo mismo que cargarlos normalmente. almacenarán en caché.
en cuanto al almacenamiento en caché, no puede controlar el navegador, pero puede configurarlo a través del servidor. Si necesita cargar un recurso realmente nuevo bajo demanda, puede usar la técnica de cachebuster para forzar la carga de un recurso nuevo.
fuente
Utilizo una técnica similar para cargar imágenes de forma diferida, pero no puedo evitar notar que Javascript no accede al caché del navegador en la primera carga.
Mi ejemplo:
Tengo un banner giratorio en mi página de inicio con 4 imágenes, el control deslizante espera 2 segundos, luego el javascript carga la siguiente imagen, espera 2 segundos, etc.
Estas imágenes tienen URL únicas que cambian cada vez que las modifico, por lo que obtienen encabezados de almacenamiento en caché que se almacenarán en el navegador durante un año.
max-age: 31536000, public
Ahora, cuando abro Chrome Devtools y me aseguro de que la opción 'Desactivar caché' no esté activa y cargo la página por primera vez (después de borrar la caché), todas las imágenes se recuperan y tienen un estado 200. Después de un ciclo completo de todas las imágenes en el banner, las solicitudes de red se detienen y se utilizan las imágenes en caché.
Ahora, cuando realizo una actualización regular o voy a una subpágina y hago clic en Atrás, las imágenes que están en el caché parecen ignorarse. Esperaría ver un mensaje gris "desde la memoria caché del disco" en la pestaña Red de las herramientas de desarrollo de Chrome. En cambio, veo que las solicitudes pasan cada dos segundos con un círculo de estado verde en lugar de gris, veo que se transfieren datos, por lo que tengo la impresión de que no se accede a la caché desde javascript. Simplemente obtiene la imagen cada vez que se carga la página.
Entonces, cada solicitud a la página de inicio desencadena 4 solicitudes independientemente de la política de almacenamiento en caché de la imagen.
Teniendo en cuenta lo anterior en conjunto y el nuevo estándar http2 que la mayoría de los navegadores y servidores web ahora admiten, creo que es mejor dejar de usar la carga diferida ya que http2 cargará todas las imágenes casi simultáneamente.
Si esto es un error en Chrome Devtools, realmente sorprende que nadie lo haya notado todavía. ;)
Si esto es cierto, el uso de la carga diferida solo aumenta el uso del ancho de banda.
Por favor corrígeme si estoy equivocado. :)
fuente
Sí, el navegador almacena en caché las imágenes automáticamente.
Sin embargo, puede configurar una caché de imágenes para que caduque. Echa un vistazo a estas preguntas de Stack Overflow y responde:
Caducidad de la caché en imágenes estáticas
fuente
Siempre prefiero usar el ejemplo mencionado en Konva JS: Image Events para cargar imágenes.
Necesita tener una lista de URL de imagen como objeto o matriz, por ejemplo:
var sources = { lion: '/assets/lion.png', monkey: '/assets/monkey.png' };
Defina la definición de la función, donde recibe la lista de URL de la imagen y una función de devolución de llamada en su lista de argumentos, para que cuando termine de cargar la imagen, pueda comenzar a excutar en su página web:
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]; } }
$(document).ready(function (){ loadImages(sources, buildStage); });
fuente
Hoy en día, hay una nueva técnica sugerida por Google para almacenar en caché y mejorar su proceso de representación de imágenes:
<script src="lazysizes.min.js" async></script>
lazyload
clase a tu imagen:<img data-src="images/flower3.png" class="lazyload" alt="">
fuente