é realista usar o armazenamento local HTML5 para armazenar CSS e JavaScript

22

A idéia é usar o armazenamento local HTML5 para armazenar CSS e JavaScript acessados ​​com frequência.

Por exemplo (pseudo-código):

var load_from_cdn = true;
if (detectar armazenamento local)  
{
  if (cache de css, js encontrado)
  {
     carregar o cache de armazenamento local
     load_from_cdn = false;
  }
}
if (load_from_cdn)
{
   document.write ('<script> ...');
}

Isso é possível ou realista?

Eu sei o cache do navegador, ainda haverá alguma verificação de acesso ao cabeçalho,
assumindo que nenhum acesso HTTP seja melhor (no meu pensamento )

PS: Parece que o armazenamento local suporta apenas par de valores-chave , alguém pode provar isso?
(melhor com alguns exemplos)

ajreal
fonte
1
A Wikipedia aparentemente tentou isso com grande efeito: twitter.com/catrope/status/408018210529615872 twitter.com/catrope/status/408018210529615872/photo/1
Dave
1
Essa é a minha 2 anos ideia ... :)
ajreal
Sua pergunta foi a primeira coisa que encontrei quando pesquisei sobre isso. Houve muita discussão aqui sobre se era uma boa ideia ou não, então pensei em fornecer alguma evidência anedótica a favor!
Dave
1
Essa imagem é enganosa. Se você rolar mais para baixo, poderá ver que a grande queda não foi de fato porque o armazenamento local era melhor do que o armazenamento em cache, mas sim um bug em sua configuração de armazenamento em cache: " Acabou sendo menos espetacular :(. O gráfico é de tráfego interno, queda devido para localStorage esconderijo caching bug "- twitter.com/catrope/status/408110382599782400
Jamie Barker

Respostas:

11

Não há problema em usar o armazenamento local para armazenar JS e CSS. No entanto, o armazenamento local tem 5M por limitação de domínio. Você pode ter que reconsiderar essa estratégia.

Para a Web de desktop, você pode aproveitar o cache padrão do navegador para executar o truque. Basta definir a resposta HTTP JS & CSS para ser armazenável em cache. É simples e fácil.

Para web móvel, a latência é alta. Portanto, reduzir solicitações de HTTP é fundamental. Portanto, ter JS e CSS em URLs externas é ideal. Seria muito melhor ter JS e CSS embutidos. Isso reduz as solicitações HTTP, mas sobrecarrega o conteúdo HTML. Então o que? Como você disse, use armazenamento local!

Quando um navegador visita o site pela primeira vez, JS e CSS são colocados em linha. O JS também possui mais dois trabalhos: 1) Armazene JS & CSS no armazenamento local; 2) Configure o cookie para sinalizar que JS e CSS estão no armazenamento local.

Quando o navegador acessa o site pela segunda vez, o servidor recebe o cookie e sabe que o navegador já possui JS & CSS relacionados. Portanto, o HTML de renderização possui JS embutido para ler JS e CSS do armazenamento local e inserir na árvore DOM.

Essa é a ideia básica de como a versão móvel do bing.com é criada. Pode ser necessário levar em consideração o controle de versão JS & CSS ao implementá-lo na produção.

obrigado

Morgan Cheng
fonte
Sim, bem perto do que estou pensando.
ajreal
O Google desenvolveu um módulo para o Page Speed ​​Mod que faz a mesma coisa. Aqui está a página onde eles falam sobre os bens, bads e dontknows developers.google.com/speed/pagespeed/module/...
Tacone
votado, mas wtf significa "inline" nesse caso. "inline" tem 5 significados diferentes.
Alexander Mills
1
É realmente aumentou para 10MB para Desktop e 5 MB para celular
Roko C. Buljan
1
Você não precisa de nenhum cookie. você pode simplesmente ler se o armazenamento local tem a chave / valor que procura, além de fornecer uma versão (para fins óbvios de invalidação). Esse truque só é bom após a segunda vez que o site é acessado e também se os ativos não estiverem em cache (por algum motivo)
vsync
33

O navegador já não faz isso por você e provavelmente melhor?

Bryan Boettcher
fonte
2
seria espero
Alexander Mills
23

Qual é o objetivo?

Já existe uma técnica bem estabelecida chamada cache do lado do cliente. O que o armazenamento local HTML5 traz nesse caso, que falta ao cache?

Você pode ter algum tipo de aplicativo estranho que deve carregar blocos de código JavaScript dinamicamente, para não poder usar efetivamente o cache, mas é um caso extremamente raro.

Além disso, esteja ciente de outra coisa. Os navegadores têm políticas específicas para cache, e a maioria dos navegadores é muito boa em gerenciar bem o cache (removendo apenas o conteúdo antigo etc.). Ao implementar seu cache caseiro, você evita que os navegadores o gerenciem corretamente. Não apenas pode ser criticado por si próprio, mas também o machucará mais cedo ou mais tarde. Exemplo: quando os usuários de um aplicativo Web estão relatando erros, geralmente você responde solicitando que limpem o cache. Não tenho certeza do que você perguntará no seu caso, pois a limpeza do cache nunca resolverá problemas com seu aplicativo Web.


Em resposta à sua primeira edição (sua segunda edição está fora do tópico):

Estou ciente do cache do navegador, ainda haverá alguma verificação de acesso ao cabeçalho

Parece que você não conhece o cache do navegador. É por isso que é essencial entender como funciona primeiro, antes de começar a implementar seu próprio mecanismo de cache caseiro . Reinvente sua própria roda somente quando você entender o suficiente as rodas existentes e tiver um bom motivo para não usá-las. Veja o ponto 1 da minha resposta à pergunta "Reinventando a roda e NÃO lamentando" .

Ao fornecer alguns dados por HTTP, você pode especificar alguns cabeçalhos relacionados ao cache:

  • Last-Modified especifica quando o conteúdo foi alterado,
  • Expiresespecifica quando o navegador deve perguntar ao servidor se o conteúdo foi alterado .

Esses dois cabeçalhos permitem que o navegador:

  • Evite baixar o conteúdo repetidamente. Se Last-Modifiedestiver definido para o último mês e o conteúdo já tiver sido baixado hoje algumas horas antes, não será necessário fazer o download novamente.
  • Evite consultar a data em que o arquivo foi modificado pela última vez. Se Expiresde uma entidade cache é 05 de maio th , 2014, você não tem que emitir qualquer pedido GET nem em 2011, nem em 2012 ou 2013, desde que você sabe que o cache é up-to-date.

O segundo é essencial para as CDNs. Quando o Google exibe o JQuery para um visitante do Stack Overflow ou cdn.sstatic.netexibe imagens ou folhas de estilo usadas pelo Stack Overflow, ele não deseja que os navegadores consultem sempre uma nova versão. Em vez disso, eles estão servindo esses arquivos uma vez, defina a data de validade para algo por tempo suficiente, e isso é tudo.

Aqui está, por exemplo, uma captura de tela do que está acontecendo quando chego à página inicial do Stack Overflow:

Uma captura de tela da linha do tempo do Stack Overflow no Chrome mostra 15 arquivos, 3 sendo solicitados e 12 sendo veiculados em cache diretamente, sem solicitações para servidores remotos

Existem 15 arquivos para servir. Mas onde estão todas essas 304 Not Modifiedrespostas? Você tem apenas três solicitações de conteúdo que foram alteradas. Para todo o resto, o navegador usa a versão em cache sem fazer nenhuma solicitação a nenhum servidor .


Para concluir, você realmente precisa pensar duas vezes antes de implementar seu próprio mecanismo de cache e, principalmente, encontrar um bom cenário em que isso possa ser útil . Como eu disse no começo da minha resposta, posso encontrar apenas uma: onde você está servindo pedaços de JavaScript para usá-los através do OMG eval(). Mas, neste caso, tenho certeza de que existem abordagens melhores que são:

  • Mais eficaz usando as técnicas de cache padrão ou
  • Mais fácil de manter.
Arseni Mourzenko
fonte
+1 para este. É absolutamente inútil. Quase em todos os casos absolutamente. O armazenamento em cache por alguma chave exclusiva baseada em hash é muito melhor.
shabunc
1
Você não está totalmente certo sobre o cache do navegador. Uma atualização definitiva passará por toda a verificação do cache do navegador.
ajreal
1
O link para reinventing the wheel and not regretting itestá morto: '(
Esailija 28/01
4
O cache do Bowser não é tão simples quanto você imagina, nem é consistente em todos os navegadores. Por exemplo, alguns navegadores decidem carregar fontes da Web aleatoriamente (independentemente dos cabeçalhos - não é possível encontrar o artigo sobre isso no momento, mas acho que foi Dave Rupert quem descobriu isso). Além disso, os ETAGs forçam os navegadores a verificar se um recurso foi atualizado ... e às vezes você não pode remover o ETAG (por exemplo, Amazon S3) - portanto, se seu arquivo CSS envia um cabeçalho ETAG, ele sempre será verificado quanto a atualizações (304s ainda são uma carga útil). Para evitar solicitações desnecessárias, é necessário cache personalizado.
Ryan Wheale
7

O cache local do lado do cliente deve ser muito mais otimizado do que usar o armazenamento local HTML5. Apenas verifique se seu javascript e CSS estão em arquivos capturáveis ​​externos e sua página deve carregar muito mais rápido via cache do navegador do que tentar extraí-los do armazenamento local e executá-los você mesmo.

Além disso, o navegador pode começar a carregar recursos externos à medida que a página começa a carregar, antes que você possa realmente começar a executar o javascript nessa página para obter seus recursos do armazenamento local HTML5.

Além disso, você precisa de código na página para carregar do armazenamento local HTML5; basta colocar todo o seu JS em um arquivo JS externo e configurável.

jfriend00
fonte
2

Você obterá um desempenho muito melhor usando uma rede de entrega de conteúdo (CDN) como a biblioteca de códigos do Google . Planejado cuidadosamente, a maioria do seu JS e CSS deve estar no cache de todos os visitantes antes que eles acessem seu site pela primeira vez. Minimize o restante.

Você sempre pode comparar o cache do navegador com a solução HTML5 rolada manualmente. Mas minha aposta é que o cache nativo vai acabar com ele.

cczona
fonte
2

O uso do localStorage é rápido (er)! Meu teste mostrou

  • Carregando jQuery a partir do CDN: Chrome 268ms , FireFox: 200ms
  • Carregar jQuery a partir do localStorage: Chrome 47ms , FireFox 14ms

Eu acho que salvar a solicitação HTTP já traz uma grande vantagem de velocidade. Todo mundo aqui parece convencido do contrário, então, por favor, prove que estou errado.

Se você quiser testar meus resultados, criei uma pequena biblioteca que armazena em cache scripts no localStorage. Confira no Github https://github.com/webpgr/cached-webpgr.js ou copie-o do exemplo abaixo.

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

Chamando a 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');
});
selecionar
fonte
3
Suas medidas são irrelevantes. (1) Se o usuário for novo no site, ele não possui jQuery no armazenamento local de qualquer maneira. (2) Se, por outro lado, o usuário já visitou seu site, ele possui o jQuery em cache, o que significa que ele não será carregado a partir da CDN. Isso também leva a um terceiro ponto: (3) o armazenamento local é adequado a um determinado site, enquanto o jQuery no CDN do Google é compartilhado por muitos sites, o que significa que um usuário que visitou, digamos, Stack Overflow, mas é novo no seu site, ganhou é necessário recarregar o jQuery da CDN se você usar a mesma versão do jQuery.
Arseni Mourzenko 8/03/15
@MainMa Talvez essa medida não seja boa, vejo isso agora, mas, para que o cache do navegador funcione, é necessário enviar uma solicitação a um servidor que retorne 304. Essa solicitação leva mais tempo do que a obtenção direta do arquivo no armazenamento local . Corrija-me se eu estiver errado.
selecione
@MainMa também verifique os comentários de programmers.stackexchange.com/a/105526/195684, há mais problemas com o cache, como a comparação ETAG que torna esse cache personalizado mais rápido
selecione