¿Es realista utilizar el almacenamiento local HTML5 para almacenar CSS y JavaScript?

22

La idea es hacer uso del almacenamiento local HTML5 para almacenar CSS y JavaScript a los que se accede con frecuencia.

Por ejemplo (pseudocódigo):

var load_from_cdn = verdadero;
if (detectar almacenamiento local)  
{
  if (caché de css, js encontrado)
  {
     cargar el caché de almacenamiento local
     load_from_cdn = false;
  }
}
if (load_from_cdn)
{
   document.write ('<script> ...');
}

¿Es esto posible o realista?

Hago memoria caché del navegador al tanto, habrá todavía algunas comprobaciones de acceso de cabecera,
que suponiendo que no hay acceso HTTP es mejor (en mi pensamiento )

PD: Parece que el almacenamiento local solo admite pares clave-valor , ¿alguien puede probarlo?
(mejor con algunos ejemplos)

ajreal
fuente
1
esa es mi idea de hace 2 años ... :)
ajreal
Tu pregunta fue lo primero que encontré cuando busqué en Google. Hubo mucha discusión aquí sobre si era una buena idea o no, ¡así que pensé en proporcionar alguna evidencia anecdótica a favor!
Dave
1
Esa imagen es engañosa. Si se desplaza más hacia abajo, puede ver que la gran caída no fue en realidad porque el almacenamiento local era mejor que el almacenamiento en caché, sino más bien un error en su configuración de almacenamiento en caché: " Resultó ser menos espectacular :(. El gráfico es de tráfico interno, caída debida al error de almacenamiento en caché de almacenamiento local "- twitter.com/catrope/status/408110382599782400
Jamie Barker

Respuestas:

11

Está absolutamente bien usar el almacenamiento local para almacenar JS y CSS. Sin embargo, el almacenamiento local tiene una limitación de 5M por dominio. Puede que tenga que reconsiderar esta estrategia.

Para la web de escritorio, puede aprovechar la memoria caché predeterminada del navegador para hacer el truco. Simplemente configure la respuesta HTTP JS y CSS para que se pueda almacenar en caché. Es sencillo y fácil.

Para la web móvil, la latencia es alta. Por lo tanto, reducir las solicitudes HTTP es fundamental. Por lo tanto, tener JS y CSS en URL externas es óptimo. Sería mucho mejor tener JS y CSS en línea. Esto reduce las solicitudes HTTP, pero hincha el contenido HTML. ¿Y que? Tal como dijiste, ¡usa el almacenamiento local!

Cuando un navegador visita el sitio por primera vez, JS y CSS se ponen en línea. El JS también tiene dos trabajos más: 1) Almacenar JS y CSS en el almacenamiento local; 2) Configure la cookie para marcar que JS y CSS están en el almacenamiento local.

Cuando el navegador accede al sitio por segunda vez, el servidor recibe la cookie y sabe que el navegador ya tiene JS y CSS relacionados. Entonces, el HTML de renderizado tiene JS en línea para leer JS y CSS del almacenamiento local e insertarlo en el árbol DOM.

Esta es una idea básica de cómo se crea la versión móvil de bing.com. Es posible que deba tener en cuenta el control de versiones JS y CSS al implementarlo en producción.

Gracias

Morgan Cheng
fuente
Sí, bastante cerca de lo que pienso.
ajreal
Google desarrolló un módulo para Page Speed ​​Mod que hace lo mismo. Aquí está la página donde hablan sobre los productos, los malos y los no desarrolladores.google.com/speed/pagespeed/module/…
tacone
votó a favor, pero wtf significa "en línea" en este caso. "en línea" tiene como 5 significados diferentes.
Alexander Mills
1
En realidad, se aumentó a 10 MB para escritorio y 5 MB para dispositivos móviles
Roko C. Buljan
1
Usted no necesita ninguna cookie. simplemente puede leer si el almacenamiento local tiene la clave / valor que está buscando, además debe proporcionar una versión (para obvios propósitos de invalidación). Este truco solo es bueno después de la segunda vez que se accede al sitio y también si los activos no están en caché (por alguna razón)
vsync
33

¿El navegador ya no hace esto por usted, y probablemente mejor?

Bryan Boettcher
fuente
2
uno podría esperar
Alexander Mills
23

¿Cuál es el punto de?

Ya existe una técnica bien establecida llamada almacenamiento en caché del lado del cliente. ¿Qué aporta el almacenamiento local HTML5 en este caso qué almacenamiento en caché falta?

Es posible que tenga algún tipo de aplicación extraña que debe cargar trozos de código JavaScript dinámicamente para que no pueda usar la caché de manera efectiva, pero es un caso extremadamente raro.

Además, tenga en cuenta otra cosa. Los navegadores tienen políticas específicas para el caché, y la mayoría de los navegadores son bastante buenos para administrar bien el caché (eliminar solo el contenido anterior, etc.). Al implementar su caché casera, evita que los navegadores la administren correctamente. No solo puede ser criticado por sí solo, sino que también te hará daño tarde o temprano. Ejemplo: cuando los usuarios de una aplicación web informan de errores, a menudo respondes pidiéndoles que borren su caché. No estoy seguro de lo que preguntará en su caso, ya que borrar el caché nunca resolverá problemas con su aplicación web.


En respuesta a su primera edición (su segunda edición está fuera de tema):

Conozco la memoria caché del navegador, todavía habrá alguna comprobación de acceso al encabezado

Parece que le falta algo de comprensión del almacenamiento en caché del navegador. Es por eso que es esencial comprender cómo funciona primero, antes de comenzar a implementar su propio mecanismo de almacenamiento en caché casero . Reinvente su propia rueda solo cuando comprenda lo suficiente las ruedas existentes y tenga una buena razón para no usarlas. Vea el punto 1 de mi respuesta a la pregunta "Reinventar la rueda y NO arrepentirse" .

Al proporcionar algunos datos a través de HTTP, puede especificar algunos encabezados relacionados con el caché:

  • Last-Modified especifica cuándo se cambió el contenido,
  • Expiresespecifica cuándo el navegador debe preguntar al servidor si el contenido cambió .

Esos dos encabezados permiten que el navegador:

  • Evite descargar el contenido una y otra vez. Si Last-Modifiedestá configurado para el último mes, y el contenido ya fue descargado hoy unas horas antes, no hay necesidad de descargarlo nuevamente.
  • Evite consultar la fecha en que se modificó el archivo por última vez. Si Expiresde una entidad caché es de 5 de mayo de XX de 2014, que no tiene que emitir ninguna petición GET ni en 2011, ni en 2012 o 2013, ya que usted sabe que la memoria caché está en marcha hasta la fecha.

El segundo es esencial para las CDN. Cuando Google sirve JQuery a un visitante de Stack Overflow o cdn.sstatic.netsirve imágenes u hojas de estilo utilizadas por Stack Overflow, no quieren que los navegadores consulten una nueva versión cada vez. En cambio, están sirviendo esos archivos una vez, establecen la fecha de vencimiento en algo lo suficientemente largo, y eso es todo.

Aquí, por ejemplo, una captura de pantalla de lo que sucede cuando llego a la página de inicio de Stack Overflow:

Una captura de pantalla de la línea de tiempo de desbordamiento de pila en Chrome muestra 15 archivos, 3 solicitados, 12 servidos directamente desde la caché sin solicitudes a servidores remotos

Hay 15 archivos para servir. ¿Pero dónde están todas esas 304 Not Modifiedrespuestas? Solo tiene tres solicitudes de contenido que cambiaron. Para todo lo demás, el navegador utiliza la versión en caché sin realizar ninguna solicitud a ningún servidor .


Para concluir, realmente necesita pensarlo dos veces antes de implementar su propio mecanismo de caché, y especialmente encontrar un buen escenario en el que esto pueda ser útil . Como dije al principio de mi respuesta, no puedo encontrar una sola: en la que está sirviendo trozos de JavaScript para utilizarlos a través, OMG, eval(). Pero en este caso, estoy bastante seguro de que hay mejores enfoques que son:

  • Más eficaz utilizando las técnicas de caché estándar, o
  • Más fácil de mantener.
Arseni Mourzenko
fuente
+1 para este. Es absolutamente inútil. Casi en todos los casos absolutamente. El almacenamiento en caché mediante una clave única basada en hash es mucho mejor.
shabunc
1
No tiene toda la razón sobre el caché del navegador. Una actualización completa pasará por alto toda la comprobación de caché del navegador.
ajreal
1
El enlace a reinventing the wheel and not regretting itestá muerto: '(
Esailija
44
El almacenamiento en caché de Bowser no es tan sencillo como puede pensar, ni es coherente en todos los navegadores. Por ejemplo, algunos navegadores deciden al azar cargar fuentes web (independientemente de los encabezados; no puedo encontrar el artículo sobre esto en este momento, pero creo que fue Dave Rupert quien descubrió esto). Además, los ETAG obligan a los navegadores a verificar si un recurso se ha actualizado ... y, a veces, no puede eliminar ETAG (por ejemplo, Amazon S3), por lo que si su archivo CSS envía un encabezado ETAG, siempre se buscará actualizaciones (304s siguen siendo una carga útil). Para evitar solicitudes innecesarias, se requiere el almacenamiento en caché personalizado.
Ryan Wheale
7

El almacenamiento en caché local del lado del cliente debería estar mucho más optimizado que el uso del almacenamiento local HTML5. Solo asegúrese de que su JavaScript y CSS estén en archivos externos que se puedan almacenar en caché y que su página se cargue mucho más rápido a través de la memoria caché del navegador que intentar extraerlos del almacenamiento local y ejecutarlos usted mismo.

Además, el navegador puede comenzar a cargar recursos externos a medida que la página comienza a cargarse, antes de que pueda comenzar a ejecutar javascript en esa página para luego obtener sus recursos del almacenamiento local HTML5.

Además, necesita código en la página de todos modos para cargar desde el almacenamiento local HTML5, así que simplemente coloque todos sus JS en un archivo JS externo y almacenable en caché.

jfriend00
fuente
2

Obtendrá un rendimiento mucho mejor utilizando una red de entrega de contenido (CDN) como la biblioteca de códigos de Google . Planificado cuidadosamente, la mayoría de sus JS y CSS deben estar en el caché de cada visitante antes de que lleguen a su sitio por primera vez. Minificar el resto.

Siempre puede comparar el almacenamiento en caché del navegador con su solución HTML5 enrollada a mano. Pero mi apuesta es que el almacenamiento en caché nativo va a vencer a los pantalones.

cczona
fuente
2

¡Usar localStorage es rápido (er)! Mi prueba mostró

  • Cargando jQuery desde CDN: Chrome 268ms , FireFox: 200ms
  • Carga de jQuery desde localStorage: Chrome 47ms , FireFox 14ms

Supongo que guardar la solicitud HTTP ya trae una gran ventaja de velocidad. Todo el mundo aquí parece estar convencido de lo contrario, así que demuéstrame que estoy equivocado.

Si quieres probar mis resultados, creé una pequeña biblioteca que almacena scripts en localStorage. Compruébelo en Github https://github.com/webpgr/cached-webpgr.js o simplemente cópielo del siguiente ejemplo.

La biblioteca completa:

function _cacheScript(c,d,e){var a=new XMLHttpRequest;a.onreadystatechange=function(){4==a.readyState&&(200==a.status?localStorage.setItem(c,JSON.stringify({content:a.responseText,version:d})):console.warn("error loading "+e))};a.open("GET",e,!0);a.send()}function _loadScript(c,d,e,a){var b=document.createElement("script");b.readyState?b.onreadystatechange=function(){if("loaded"==b.readyState||"complete"==b.readyState)b.onreadystatechange=null,_cacheScript(d,e,c),a&&a()}:b.onload=function(){_cacheScript(d,e,c);a&&a()};b.setAttribute("src",c);document.getElementsByTagName("head")[0].appendChild(b)}function _injectScript(c,d,e,a){var b=document.createElement("script");b.type="text/javascript";c=JSON.parse(c);var f=document.createTextNode(c.content);b.appendChild(f);document.getElementsByTagName("head")[0].appendChild(b);c.version!=e&&localStorage.removeItem(d);a&&a()}function requireScript(c,d,e,a){var b=localStorage.getItem(c);null==b?_loadScript(e,c,d,a):_injectScript(b,c,d,a)};

Llamando a la biblioteca

requireScript('jquery', '1.11.2', 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', function(){
    requireScript('examplejs', '0.0.3', 'example.js');
});
seleccionar
fuente
3
Tus medidas son irrelevantes. (1) Si el usuario es nuevo en el sitio web, de todos modos no tiene jQuery en el almacenamiento local. (2) Si, por otro lado, el usuario ya visitó su sitio web, tiene jQuery en caché, lo que significa que no se cargará desde CDN. Esto también lleva a un tercer punto: (3) el almacenamiento local es apropiado para un sitio determinado, mientras que jQuery en el CDN de Google es compartido por muchos sitios, lo que significa que un usuario que visitó, por ejemplo, Stack Overflow pero es nuevo en su sitio ganó No necesita volver a cargar jQuery desde CDN si usa la misma versión de jQuery.
Arseni Mourzenko
@MainMa Quizás esta medida no sea buena, lo veo ahora, pero para que la memoria caché del navegador funcione, debe enviarse una solicitud a un servidor que luego devuelve un 304. Esta solicitud lleva más tiempo que obtener directamente el archivo del almacenamiento local. . Corrígeme si me equivoco.
seleccione
@MainMa, compruebe también los comentarios de programmers.stackexchange.com/a/105526/195684. Hay más problemas con el caché, como la comparación ETAG que hace que este almacenamiento en caché personalizado sea más rápido
seleccione el