2009-05-13 33 views
6

No quiero saber cómo precargar imágenes, encontré mucho en la red, pero quiero saber cómo funciona. ¿Cómo es javascript capaz de precargar imágenes? Quiero decir, probé un fragmento de aquí, e incluso si funciona, parece que no precarga las imágenes.¿Cómo funciona la precarga de javascript?

Cuando verifico firebug, puedo ver que la imagen se carga dos veces, una mientras que la precarga, otra vez cuando se muestra.

Para mejorar este código, me gustaría saber cómo funciona.

Aquí es lo que hago:

function preload(arrayOfImages) { 
     $(arrayOfImages).each(function(){ 
      $('<img/>')[0].src = this; 
      //(new Image()).src = this; 
      alert(this +' && ' + i++); 

     }); 
    } 

entonces que hago algo así:

preloader = function() { 
    preload(myImages); 
} 

$(document).ready(preloader); 

Aquí es cómo visualizar/añadir la imagen:

$("li.works").click(function() { 
      $("#viewer").children().empty(); 
      $('#viewer').children().append('<img src=\'images/ref/'+this.firstChild.id+'.jpg\' alt="'+this.firstChild.id+'" \/>') 
      $("#viewer").children().fadeIn(); 
+0

¿Cómo está tratando de ver las imágenes? –

+0

Agregué el código en mi pregunta. Tal vez debería crear un elemento con DOM en lugar de simplemente agregar la cadena equivalente? –

Respuesta

11

Tu básica El preloader de Javascript hace esto:

var image = new Image(); 
image.src = '/path/to/the/image.jpg'; 

La forma en que funciona es simplemente creando un nuevo objeto de imagen y configurando el src del mismo, el navegador irá a tomar la imagen. No estamos agregando esta imagen particular al navegador, pero cuando llegue el momento de mostrar la imagen en la página a través de cualquier método que hayamos configurado, el navegador ya lo tendrá en su caché y no irá a buscarlo nuevamente. Realmente no puedo decirte por qué lo que sea que tengas no está funcionando de esta manera sin mirar el código.

Una Gotcha interesante que se discute in this question es lo que sucede cuando se tiene una serie de imágenes y tratar de precarga a todos ellos utilizando el mismo objeto Imagen:

var images = ['image1.jpg','image2.jpg']; 
var image = new Image(); 
for(var x = 0; x < images.length; x++) { 
    image.src = images[x]; 
} 

Esto sólo cargar previamente la última imagen que el resto no tendrá tiempo de precargar antes de que el ciclo vuelva a aparecer para cambiar la fuente del objeto. View an example of this. Debería poder ver instantáneamente la segunda imagen una vez que hace clic en el botón, pero la primera tendrá que cargarse, ya que no tuvo la oportunidad de precargarse cuando intenta verla.

Como tal, la forma correcta de hacer muchas a la vez sería:

var images = ['image1.jpg','image2.jpg']; 
for(var x = 0; x < images.length; x++) { 
    var image = new Image(); 
    image.src = images[x]; 
} 
+1

Creo que mi código es muy similar al suyo (he editado mi pregunta para agregarlo) Pero Firebug todavía me está mostrando que las imágenes se cargan cada vez que se muestra la imagen –

1

Simplemente consiste en hacer un nuevo objeto de imagen DOM y estableciendo el atributo src. Nada inteligente y AFAIK, siempre me ha funcionado.

¿Es posible que el segundo Firebug "carga" muestre que lo está cargando desde el caché?

+0

Acabo de probarlo y no se muestra una carga en esta página (http://www.rootspot.com/stackoverflow/preload.php) cuando hago clic en la imagen en caché. –

1

El índice en el bucle solo está mirando en la primera imagen. Cambiarlo a utilizar el índice:

function preload(arrayOfImages) { 
    $(arrayOfImages).each(function(i){ // Note the argument 
     $('<img/>')[i].src = this; // Note the i 
     //(new Image()).src = this; 
     alert(this +' && ' + i++); 

    }); 
} 

Editar: En retrospectiva, esto estaba mal y puedo ver que estamos tratando de crear elementos de imagen. No entiendo por qué el índice está allí, no es necesario que haya un índice.Creo que la función debe tener este aspecto:

function preload(arrayOfImages) { 
    $(arrayOfImages).each(function() { 
     $('<img/>').attr('src', this); 
    }); 
}  

Y para crear instancias de ella, ¿por qué no hacer esto:

$(function() { // Equivalent to $(document).ready() 
    preload(myImages); 
}); 

imagen JavaScript precarga obras porque cuando se crea un elemento DOM que contiene una imagen, la imagen se descarga y almacena en caché. Incluso si se realiza otra solicitud cuando la imagen se representa en realidad desde el HTML, el servidor enviará un 304 (no modificado), y el navegador simplemente cargará la imagen desde su caché.

Paolo sugiere utilizar la siguiente notación para crear un objeto de imagen:

var image = new Image(); 

Mientras que esto va a funcionar, la forma DOM-compatible de hacer esto es:

var image = document.createElement('img'); 
image.setAttribute('src', 'path/to/image.jpg'); 

¿Cuál es la forma en que se se está haciendo en el script, excepto que se usa la sintaxis literal de cadena HTML de jQuery para hacerlo. Además, la mayoría de los navegadores modernos ofrecen compatibilidad con el constructor Image() simplemente llamando a los métodos DOM estándar. Por ejemplo, si se abre la consola de Google Chrome JavaScript y el tipo Image, esto es lo que se obtiene:

function Image() { 
    return document.createElementNS('http://www.w3.org/1999/xhtml', 'img'); 
} 

Chrome simplemente utiliza los métodos DOM nativos para crear un elemento de imagen.

+1

¿Qué navegador se ahogará en la nueva imagen()? Además, la sugerencia inicial de cambiar 0 a i no es válida. Lo que hace al hacer eso es acceder directamente al elemento DOM que acaba de crear, que jQuery mantiene en [0] en ese caso. –

+0

No conozco ningún navegador que se ahogue en él, pero el DOM está diseñado para ser independiente del lenguaje. Dependiendo de la implementación, la implementación nativa que usa el navegador puede no ser el DOM. –

2

Puede confundirse con el concepto de "precarga". Si tiene un montón de imágenes en su HTML con <img src="...">, no pueden ser precargadas con Javascript, simplemente cargan con la página.

La precarga de imágenes con Javascript se trata de cargar imágenes que no están ya en el origen del documento, y luego mostrarlas más tarde. Se cargan después de que la página se haya procesado por primera vez. Están precargados para eliminar/minimizar el tiempo de carga cuando se trata de hacerlos aparecer, por ejemplo, cuando se cambia una imagen en el rollover del mouse.

Para la mayoría de las aplicaciones, generalmente es una mejor práctica usar "sprites CSS" como una forma de precarga, en lugar de Javascript. SO debería tener un montón de preguntas sobre esto.

+1

+1 - No pensé que tal vez solo intentaba cargar las imágenes que estaban inicialmente en el documento. Ciertamente espero que emitan dos solicitudes. –

5

La precarga de JavaScript funciona aprovechando el mecanismo de almacenamiento en caché utilizado por los navegadores.

La idea básica es que una vez que se descarga un recurso, se almacena durante un período de tiempo localmente en la máquina cliente para que el navegador no tenga que recuperar el recurso nuevamente desde la red, la próxima vez que se descargue. es requerido para mostrar/usar por el navegador.

Probablemente su código esté funcionando bien y usted está malinterpretando lo que Fire Bug está mostrando.

Para probar esta teoría solo tiene que acceder a www.google.com con un caché limpio. Es decir. borre su historial de descargas primero.

La primera vez en todo probablemente tenga un estado de 200 OK. Lo que significa que su navegador solicitó el recurso y el servidor lo envió. Si miras en la parte inferior de la ventana de Fire Bug, dirá qué tan grande era la página, digamos 195 Kb, y cuánto de eso fue sacado de la caché. En este caso 0Kb.

A continuación, vuelva a cargar la misma página sin borrar la caché, y aún verá la misma cantidad de solicitudes en FireBug.

La razón de esto es bastante simple. La página no ha cambiado y aún necesita todos los recursos que necesitaba antes.

Lo que es diferente es que para la mayoría de estas solicitudes el servidor devolvió un estado 304 no modificado, por lo que el navegador verificó su caché para ver si ya tenía el recurso almacenado localmente, que en este caso lo hizo desde el anterior carga de página Entonces, el navegador simplemente sacó el recurso del caché local.

Si mira en la parte inferior de la ventana Fire Bug, verá que el tamaño de página sigue siendo el mismo (195Kb) pero que la mayoría, en mi caso 188Kb, se extrajo localmente de la memoria caché.

Así que la memoria caché sí funcionó y la segunda vez que presioné Google guardé 188 Kb de descarga.

Estoy seguro de que encontrará lo mismo con la precarga de sus imágenes. La solicitud aún se realiza, pero si el servidor devuelve un estado de 304, verá que la imagen se ha extraído de la memoria caché local y no de la red.

Así que con el almacenamiento en caché, la ventaja NO es que elimine todas las solicitudes de recursos futuros, es decir, una búsqueda URI todavía se realiza en la red pero si es posible el navegador extraerá de la memoria caché local para satisfacer la necesidad del contenido, en lugar de correr alrededor de la red buscándolo.

+0

Gran respuesta. ¡Pensé que el almacenamiento en caché impidió que el navegador realizara una nueva solicitud por completo! –

Cuestiones relacionadas