è realistico utilizzare l'archiviazione locale HTML5 per archiviare CSS e JavaScript


22

L'idea è di utilizzare l'archiviazione locale HTML5 per memorizzare CSS e JavaScript a cui si accede frequentemente.

Ad esempio (pseudo-codice):

var load_from_cdn = true;
if (rileva memoria locale)  
{
  if (cache di css, js trovata)
  {
     caricare la cache di archiviazione locale
     load_from_cdn = false;
  }
}
if (load_from_cdn)
{
   document.write ( '<script> ...');
}

È possibile o realistico?

Faccio cache del browser a conoscenza, ci sarà ancora qualche controllo di accesso di testa,
io parto dal presupposto accesso HTTP è meglio (nel mio pensiero )

PS: sembra che l'archiviazione locale supporti solo coppie chiave-valore , qualcuno può dimostrarlo?
(meglio con alcuni esempi)


1
Wikipedia apparentemente ha provato questo con grande efficacia: twitter.com/catrope/status/408018210529615872 twitter.com/catrope/status/408018210529615872/photo/1
Dave

1
questa è la mia idea di 2 anni fa ... :)
Ajreal

La tua domanda è stata la prima cosa che ho scoperto quando ho cercato su Google. Ci sono state molte discussioni qui sul fatto che fosse una buona idea o meno, quindi ho pensato di fornire alcune prove aneddotiche a favore!
Dave,

1
Quella foto è fuorviante. Se scorri più in basso puoi vedere che l'enorme calo non era in realtà perché localstorage era meglio della memorizzazione nella cache, ma piuttosto un bug nella loro configurazione della cache: "Si è rivelato essere meno spettacolare :(. Il grafico è del traffico interno, drop dovuto a localStorage nascondendo bug della cache "- twitter.com/catrope/status/408110382599782400
Jamie Barker

Risposte:


11

È assolutamente OK utilizzare l'archiviazione locale per archiviare JS e CSS. Tuttavia, l'archiviazione locale ha una limitazione di 5 milioni per dominio. Potrebbe essere necessario riconsiderare questa strategia.

Per il Web desktop, puoi sfruttare la cache del browser predefinita per fare il trucco. Basta impostare la risposta HTTP JS e CSS per essere memorizzabile nella cache. È semplice e facile.

Per il Web mobile, la latenza è alta. Pertanto, ridurre le richieste HTTP è fondamentale. Quindi, avere JS e CSS in URL esterni è ottimale. Sarebbe molto meglio avere JS e CSS in linea. Ciò riduce le richieste HTTP, ma gonfia il contenuto HTML. Allora cosa? Proprio come hai detto, usa l'archiviazione locale!

Quando un browser visita il sito per la prima volta, JS e CSS vengono messi in linea. JS ha anche altri due lavori: 1) Memorizza JS e CSS nella memoria locale; 2) Imposta cookie per segnalare che JS e CSS sono nella memoria locale.

Quando il browser accede al sito per la seconda volta, il server ha ricevuto il cookie e sa che il browser ha già JS e CSS correlati. Quindi il rendering HTML ha in linea JS per leggere JS e CSS dalla memoria locale e inserirli nell'albero DOM.

Questa è l'idea di base su come viene creata la versione mobile di bing.com. Potrebbe essere necessario prendere in considerazione il controllo della versione JS e CSS quando lo si implementa in produzione.

Grazie


Sì, abbastanza vicino a quello che sto pensando.
Ajj

Google ha sviluppato un modulo per Page Speed ​​Mod che fa la stessa cosa. Ecco la pagina in cui parlano di beni, cose cattive e insoddisfatte developer.google.com/speed/pagespeed/module/…
tacone

votato, ma in questo caso wtf significa "inline". "inline" ha 5 significati diversi.
Alexander Mills,

1
In realtà è aumentato a 10 MB per desktop e 5 MB per dispositivi mobili
Roko C. Buljan,

1
Lei non è necessario alcun biscotto. puoi semplicemente leggere se il localstorage ha la chiave / il valore che stai cercando e in più devi fornire una versione (per ovvi scopi di invalidazione). Questo trucco è valido solo dopo la seconda volta che si accede al sito e anche se le risorse non sono nella cache (per qualche motivo)
vsync,


23

Qual e il punto?

Esiste già una tecnica consolidata chiamata memorizzazione nella cache lato client. Cosa porta in questo caso l'archiviazione locale HTML5 in ciò che manca nella cache?

Potresti avere una sorta di strana applicazione che deve caricare in modo dinamico blocchi di codice JavaScript in modo da non poter utilizzare efficacemente la cache, ma è un caso estremamente raro.

Inoltre, sii consapevole di un'altra cosa. I browser hanno criteri specifici per la cache e la maggior parte dei browser è abbastanza brava a gestire bene la cache (rimuovendo solo i contenuti più vecchi, ecc.). Implementando la cache fatta in casa, si impedisce ai browser di gestirla correttamente. Non solo può essere criticato da solo, ma ti farà male anche prima o poi. Esempio: quando gli utenti di un'applicazione web segnalano bug, spesso rispondi chiedendo loro di svuotare la cache. Non sono sicuro di ciò che chiederai nel tuo caso, poiché svuotare la cache non risolverà mai i problemi con la tua app web.


In risposta alla tua prima modifica (la tua seconda modifica è fuori tema):

Conosco la cache del browser, ci sarà ancora qualche controllo di accesso all'intestazione

Sembra che tu non abbia una certa comprensione della memorizzazione nella cache del browser. Ecco perché è essenziale capire come funziona prima, prima di iniziare a implementare il proprio meccanismo di cache fatto in casa . Reinventa la tua ruota solo quando hai capito abbastanza le ruote esistenti e hai una buona ragione per non usarle. Vedi il punto 1 della mia risposta alla domanda "Reinventare la ruota e NON pentirla" .

Quando si forniscono alcuni dati tramite HTTP, è possibile specificare alcune intestazioni relative alla cache:

  • Last-Modified specifica quando il contenuto è stato modificato,
  • Expiresspecifica quando il browser deve chiedere al server se il contenuto è cambiato .

Queste due intestazioni consentono al browser di:

  • Evita di scaricare il contenuto ancora e ancora. Se Last-Modifiedè impostato sull'ultimo mese e il contenuto è stato già scaricato oggi poche ore prima, non è necessario scaricarlo di nuovo.
  • Evitare di eseguire una query per la data in cui il file è stato modificato l'ultima volta. Se Expiresdi un'entità di cache è 5 maggio ° 2014, non c'è bisogno di emettere qualsiasi richiesta GET né nel 2011, né nel 2012 o 2013, poiché si sa che la cache è up-to-date.

Il secondo è essenziale per i CDN. Quando Google fornisce JQuery a un visitatore di Stack Overflow o pubblica cdn.sstatic.netimmagini o fogli di stile utilizzati da Stack Overflow, non desidera che i browser richiedano sempre una nuova versione. Invece, stanno servendo quei file una volta, impostano la data di scadenza su qualcosa di abbastanza lungo, e questo è tutto.

Ecco ad esempio uno screenshot di ciò che sta accadendo quando arrivo alla home page di Stack Overflow:

Uno screenshot della sequenza temporale di StackTranslate.it in Chrome mostra 15 file, 3 richiesti, 12 offerti dalla cache direttamente senza richieste ai server remoti

Ci sono 15 file da servire. Ma dove sono tutte quelle 304 Not Modifiedrisposte? Hai solo tre richieste di contenuto che sono cambiate. Per tutto il resto, il browser utilizza la versione memorizzata nella cache senza effettuare alcuna richiesta a nessun server .


Per concludere, devi davvero pensarci due volte prima di implementare il tuo meccanismo di cache e soprattutto trovare un buon scenario in cui questo può essere utile . Come ho detto all'inizio della mia risposta, posso trovare una sola: dove si sta servendo pezzi di JavaScript per utilizzare loro attraverso, OMG, eval(). Ma in questo caso, sono abbastanza sicuro che ci siano approcci migliori che sono:

  • Più efficace utilizzando le tecniche di cache standard, o
  • Più facile da mantenere.

+1 per questo. È assolutamente inutile. Quasi sempre assolutamente. La memorizzazione nella cache con una chiave unica basata su hash è molto meglio.
Shabunc,

1
Non hai del tutto ragione sulla cache del browser. Un duro aggiornamento passerà tutto il controllo della cache del browser.
Ajj

1
Il collegamento a reinventing the wheel and not regretting itè morto: '(
Esailija,

4
La memorizzazione nella cache di Bowser non è così semplice come si potrebbe pensare, né è coerente su tutti i browser. Ad esempio, alcuni browser decidono in modo casuale di caricare caratteri web (indipendentemente dalle intestazioni - non riesco a trovare l'articolo su questo in questo momento ma penso che sia stato Dave Rupert a scoprirlo). Inoltre, gli ETAG costringono i browser a verificare se una risorsa è stata aggiornata ... e talvolta non è possibile rimuovere ETAG (ad es. Amazon S3) - quindi se il file CSS invia un'intestazione ETAG, verrà sempre controllato per gli aggiornamenti (304s sono ancora un payload). Per evitare richieste non necessarie, è richiesta la memorizzazione nella cache personalizzata.
Ryan Wheale,

7

La memorizzazione nella cache locale sul lato client dovrebbe essere molto più ottimizzata rispetto all'utilizzo dell'archiviazione locale HTML5. Assicurati solo che javascript e CSS si trovino in file esterni memorizzabili e che la tua pagina si carichi molto più velocemente tramite la cache del browser rispetto al tentativo di estrarli dalla memoria locale ed eseguirli tu stesso.

Inoltre, il browser può iniziare a caricare risorse esterne quando la pagina inizia a caricarsi, prima che tu possa effettivamente iniziare a eseguire javascript in quella pagina per poi ottenere le tue risorse dall'archiviazione locale HTML5.

Inoltre, è necessario comunque il codice nella pagina per caricare dalla memoria locale HTML5, quindi è sufficiente mettere tutto il proprio JS in un file JS esterno e cachable.



2

Otterrai prestazioni molto migliori utilizzando una rete di distribuzione di contenuti (CDN) come la libreria di codici di Google . Pianificato attentamente, la maggior parte dei tuoi JS e CSS dovrebbe trovarsi nella cache di ogni visitatore prima che colpiscano il tuo sito per la prima volta. Minimizza il resto.

Puoi sempre confrontare la cache del browser rispetto alla tua soluzione HTML5 a rotazione manuale. Ma la mia scommessa è che la cache nativa sta per battere i pantaloni.


2

L'uso di localStorage è veloce (er)! Il mio test ha mostrato

  • Caricamento jQuery da CDN: Chrome 268ms , FireFox: 200ms
  • Caricamento di jQuery da localStorage: Chrome 47ms , FireFox 14ms

Immagino che il salvataggio della richiesta HTTP porti già un grande vantaggio di velocità. Tutti qui sembrano essere convinti del contrario, quindi per favore dimostrami che mi sbaglio.

Se vuoi testare i miei risultati ho creato una minuscola libreria che memorizza nella cache gli script in localStorage. Dai un'occhiata su Github https://github.com/webpgr/cached-webpgr.js o copialo dall'esempio seguente.

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

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

3
Le tue misure sono irrilevanti. (1) Se l'utente è nuovo nel sito Web, non ha comunque jQuery nella memoria locale. (2) Se, d'altra parte, l'utente ha già visitato il tuo sito Web, ha jQuery nella cache, il che significa che non verrà caricato da CDN. Questo porta anche a un terzo punto: (3) l'archiviazione locale è corretta per un determinato sito, mentre jQuery sulla CDN di Google è condiviso da molti siti, il che significa che un utente che ha visitato, diciamo, Stack Overflow ma è nuovo nel tuo sito ha vinto non è necessario ricaricare jQuery da CDN se si utilizza la stessa versione di jQuery.
Arseni Mourzenko

@MainMa Forse questa misura non va bene, lo vedo ora, ma per il funzionamento della cache del browser è necessario che sia presente una richiesta di invio a un server che quindi restituisca un 304. Questa richiesta richiede più tempo rispetto al recupero diretto del file dallo store locale . Correggimi se sbaglio.
seleziona il

@MainMa controlla anche i commenti da programmers.stackexchange.com/a/105526/195684 ci sono più problemi con la cache, come il confronto ETAG che rende più veloce questa memorizzazione personalizzata della cache
seleziona
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.