est-il réaliste d'utiliser le stockage local HTML5 pour stocker CSS et JavaScript

22

L'idée est d'utiliser le stockage local HTML5 pour stocker les CSS et JavaScript fréquemment consultés.

Par exemple (pseudo-code):

var load_from_cdn = true;
if (détecter le stockage local)  
{
  if (cache de css, js trouvé)
  {
     charger le cache de stockage local
     load_from_cdn = false;
  }
}
if (load_from_cdn)
{
   document.write ('<script> ...');
}

Est-ce possible ou réaliste?

Je connais le cache du navigateur, il y aura encore une vérification de l'accès aux en-têtes,
je suppose qu'aucun accès HTTP n'est meilleur (dans ma pensée )

PS: Il semble que le stockage local ne supporte que la paire clé-valeur , quelqu'un peut-il le prouver?
(mieux avec quelques exemples)

ajreal
la source
1
c'est mon idée d'il y a 2 ans ... :)
ajreal
Votre question a été la première chose que j'ai trouvée lorsque j'ai fait une recherche sur Google. Il y a eu beaucoup de discussions ici pour savoir si c'était une bonne idée ou non, alors j'ai pensé apporter des preuves anecdotiques en faveur!
Dave
1
Cette image est trompeuse. Si vous faites défiler vers le bas, vous pouvez voir que l'énorme baisse n'était pas en fait parce que le stockage local était meilleur que la mise en cache, mais plutôt un bug dans leur configuration de mise en cache: " s'est avéré moins spectaculaire :(. Le graphique est du trafic interne, baisse due to localStorage hiding cacheing bug "- twitter.com/catrope/status/408110382599782400
Jamie Barker
consultez addyosmani.com/basket.js
xhh

Réponses:

11

Il est absolument correct d'utiliser le stockage local pour stocker JS et CSS. Cependant, le stockage local a une limitation de 5 Mo par domaine. Vous devrez peut-être reconsidérer cette stratégie.

Pour le Web de bureau, vous pouvez utiliser le cache du navigateur par défaut pour faire l'affaire. Définissez simplement la réponse HTTP JS & CSS pour qu'elle puisse être mise en cache. C'est simple et facile.

Pour le Web mobile, la latence est élevée. Il est donc essentiel de réduire les demandes HTTP. Donc, avoir JS & CSS dans les URL externes est optimal. Il serait préférable d'avoir JS & CSS en ligne. Cela réduit les requêtes HTTP, mais gonfle le contenu HTML. Alors quoi? Comme vous l'avez dit, utilisez le stockage local!

Lorsqu'un navigateur visite le site pour la première fois, JS & CSS sont mis en ligne. Le JS a également deux autres tâches: 1) Stocker JS et CSS dans le stockage local; 2) Définissez un cookie pour signaler que JS et CSS sont dans le stockage local.

Lorsque le navigateur accède au site pour la deuxième fois, le serveur a obtenu le cookie et sait que le navigateur a déjà associé JS & CSS. Ainsi, le rendu HTML a JS en ligne pour lire JS et CSS à partir du stockage local et l'insérer dans l'arborescence DOM.

C'est l'idée de base de la création de la version mobile de bing.com. Vous devrez peut-être prendre en compte le contrôle de version JS et CSS lors de son implémentation en production.

Merci

Morgan Cheng
la source
Oui, assez proche de ce à quoi je pense.
ajreal
Google a développé un module pour Page Speed ​​Mod qui fait exactement la même chose. Voici la page où ils parlent des biens, des maux et des choses dont les développeurs ne sont
speed
voté, mais wtf signifie "en ligne" dans ce cas. "inline" a comme 5 significations différentes.
Alexander Mills
1
Il est en fait passé à 10 Mo pour le bureau et à 5 Mo pour les mobiles
Roko C. Buljan
1
Vous n'avez pas besoin de cookie. vous pouvez simplement lire si le stockage local a la clé / valeur que vous recherchez et vous devez fournir une version (à des fins d'invalidation évidentes). Cette astuce n'est bonne qu'après la deuxième
connexion
33

Le navigateur ne le fait-il pas déjà pour vous, et probablement mieux?

Bryan Boettcher
la source
2
on pourrait espérer
Alexander Mills
23

À quoi ça sert?

Il existe déjà une technique bien établie appelée mise en cache côté client. Qu'est-ce que le stockage local HTML5 apporte dans ce cas quel cache est manquant?

Vous pouvez avoir une sorte d'application étrange qui doit charger dynamiquement des morceaux de code JavaScript afin que vous ne puissiez pas utiliser efficacement le cache, mais c'est un cas extrêmement rare.

Soyez également conscient d'une autre chose. Les navigateurs ont des politiques spécifiques pour le cache, et la plupart des navigateurs sont assez bons pour bien gérer le cache (supprimer uniquement le contenu plus ancien, etc.). En implémentant votre cache fait maison, vous empêchez les navigateurs de le gérer correctement. Non seulement elle peut être critiquée seule, mais elle vous blessera aussi tôt ou tard. Exemple: lorsque les utilisateurs d'une application Web signalent des bogues, vous répondez souvent en leur demandant de vider leur cache. Je ne sais pas ce que vous demanderez dans votre cas, car l'effacement du cache ne résoudra jamais les problèmes avec votre application Web.


En réponse à votre premier montage (votre deuxième montage étant hors sujet):

Je connais le cache du navigateur, il y aura encore une vérification de l'accès aux en-têtes

Vous semblez manquer de compréhension de la mise en cache du navigateur. C'est pourquoi il est essentiel de comprendre comment cela fonctionne avant de commencer à mettre en œuvre votre propre mécanisme de mise en cache fait maison . Réinventez votre propre roue uniquement lorsque vous comprenez suffisamment les roues existantes et que vous avez une bonne raison de ne pas les utiliser. Voir point 1 de ma réponse à la question "Réinventer la roue et ne pas la regretter" .

Lorsque vous fournissez des données via HTTP, vous pouvez spécifier quelques en-têtes liés au cache:

  • Last-Modified précise quand le contenu a été modifié,
  • Expiresspécifie quand le navigateur doit demander au serveur si le contenu a changé .

Ces deux en-têtes permettent au navigateur de:

  • Évitez de télécharger le contenu encore et encore. Si Last-Modifiedest défini sur le mois dernier et que le contenu a déjà été téléchargé aujourd'hui quelques heures auparavant, il n'est pas nécessaire de le télécharger à nouveau.
  • Évitez d'interroger la date de dernière modification du fichier. Si Expiresd'une entité de cache est le 5 mai e 2014, vous n'avez pas d'émettre une requête GET ni en 2011, ni en 2012 ou 2013, puisque vous savez que le cache est mise à jour.

Le second est essentiel pour les CDN. Lorsque Google diffuse JQuery à un visiteur de Stack Overflow ou cdn.sstatic.netdiffuse des images ou des feuilles de style utilisées par Stack Overflow, il ne souhaite pas que les navigateurs recherchent une nouvelle version à chaque fois. Au lieu de cela, ils servent ces fichiers une fois, définissent la date d'expiration sur quelque chose d'assez longtemps, et c'est tout.

Voici par exemple une capture d'écran de ce qui se passe lorsque j'arrive sur la page d'accueil de Stack Overflow:

Une capture d'écran de la chronologie de Stack Overflow dans Chrome montre 15 fichiers, 3 étant demandés, 12 étant servis directement depuis le cache sans demandes aux serveurs distants

Il y a 15 fichiers à servir. Mais où sont toutes ces 304 Not Modifiedréponses? Vous n'avez que trois demandes de contenu qui ont changé. Pour tout le reste, le navigateur utilise la version mise en cache sans faire de demande à aucun serveur .


Pour conclure, vous devez vraiment réfléchir à deux fois avant d'implémenter votre propre mécanisme de cache, et surtout trouver un bon scénario où cela peut être utile . Comme je l' ai dit au début de ma réponse, je peux trouver une seule: où vous servez des morceaux de JavaScript afin de les utiliser à travers, OMG, eval(). Mais dans ce cas, je suis presque sûr qu'il existe de meilleures approches qui sont soit:

  • Plus efficace en utilisant les techniques de cache standard, ou
  • Plus facile à entretenir.
Arseni Mourzenko
la source
+1 pour celui-ci. C'est absolument inutile. Presque dans tous les cas absolument. La mise en cache par une clé unique basée sur le hachage est bien meilleure.
shabunc
1
Vous n'avez pas entièrement raison sur le cache du navigateur. Une actualisation matérielle passera toute la vérification du cache du navigateur.
ajreal
1
Le lien vers reinventing the wheel and not regretting itest mort: '(
Esailija
4
La mise en cache Bowser n'est pas aussi simple que vous ne le pensez, ni cohérente dans tous les navigateurs. Par exemple, certains navigateurs décident au hasard de charger des polices Web (indépendamment des en-têtes - je ne trouve pas l'article à ce sujet pour le moment, mais je pense que c'est Dave Rupert qui l'a découvert). De plus, les ETAG forcent les navigateurs à vérifier si une ressource a été mise à jour ... et parfois vous ne pouvez pas supprimer ETAG (par exemple, Amazon S3) - donc si votre fichier CSS envoie un en-tête ETAG, il sera toujours vérifié pour les mises à jour (304s sont toujours une charge utile). Afin d'éviter les demandes inutiles, une mise en cache personnalisée est requise.
Ryan Wheale
7

La mise en cache locale côté client devrait être bien plus optimisée que l'utilisation du stockage local HTML5. Assurez-vous simplement que votre javascript et CSS sont dans des fichiers externes et que votre page devrait se charger beaucoup plus rapidement via le cache du navigateur que d'essayer de les extraire du stockage local et de les exécuter vous-même.

En outre, le navigateur peut commencer à charger des ressources externes au fur et à mesure que la page commence à se charger, avant de pouvoir réellement commencer à exécuter javascript dans cette page pour ensuite obtenir vos ressources à partir du stockage local HTML5.

De plus, vous avez quand même besoin de code dans la page pour charger à partir du stockage local HTML5, alors mettez simplement tous vos JS dans un fichier JS externe et cachable.

jfriend00
la source
2

Vous obtiendrez de bien meilleures performances en utilisant un réseau de diffusion de contenu (CDN) comme la bibliothèque de codes de Google . Prévu de manière réfléchie, la majorité de vos JS et CSS devraient être dans le cache de chaque visiteur avant qu'ils ne visitent votre site pour la première fois. Réduisez le reste.

Vous pouvez toujours comparer la mise en cache du navigateur à votre solution HTML5 roulée à la main. Mais je parie que la mise en cache native va battre le pantalon.

cczona
la source
2

Utiliser localStorage est rapide (euh)! Mon test a montré

  • Chargement de jQuery à partir de CDN: Chrome 268 ms , FireFox: 200 ms
  • Chargement de jQuery depuis localStorage: Chrome 47ms , FireFox 14ms

Je suppose que l'enregistrement de la requête HTTP apporte déjà un gros avantage de vitesse. Tout le monde ici semble être convaincu du contraire, alors veuillez me prouver le contraire.

Si vous voulez tester mes résultats, j'ai créé une petite bibliothèque qui met en cache les scripts dans localStorage. Découvrez-le sur Github https://github.com/webpgr/cached-webpgr.js ou copiez-le simplement à partir de l'exemple ci-dessous.

La bibliothèque complète:

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)};

Appeler la bibliothèque

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');
});
sélectionner
la source
3
Vos mesures ne sont pas pertinentes. (1) Si l'utilisateur est nouveau sur le site Web, il n'a de toute façon pas de jQuery dans le stockage local. (2) Si, en revanche, l'utilisateur a déjà visité votre site Web, il a jQuery en cache, ce qui signifie qu'il ne sera pas chargé à partir de CDN. Cela conduit également à un troisième point: (3) le stockage local est propre à un site donné, tandis que jQuery sur le CDN de Google est partagé par de nombreux sites, ce qui signifie qu'un utilisateur qui a visité, disons, Stack Overflow mais est nouveau sur votre site a gagné pas besoin de recharger jQuery depuis CDN si vous utilisez la même version de jQuery.
Arseni Mourzenko
@MainMa Peut-être que cette mesure n'est pas bonne, je le vois maintenant, mais pour que le cache du navigateur fonctionne, une demande doit être envoyée à un serveur qui renvoie ensuite 304. Cette demande prend plus de temps que d'obtenir directement le fichier du localstorage . Corrige moi si je me trompe.
sélectionnez
@MainMa veuillez également vérifier les commentaires de programmers.stackexchange.com/a/105526/195684 il y a plus de problèmes avec le cache, comme la comparaison ETAG qui rend cette mise en cache personnalisée plus rapide
sélectionnez