Eu tenho um aplicativo da web offline usando appcaching. Preciso fornecer cerca de 10 MB a 20 MB de dados que ele salvará (do lado do cliente) consistindo principalmente de arquivos de imagem PNG. A operação é a seguinte:
- Download e instalação de aplicativos da Web em appcache (usa manifesto)
- Solicitações de aplicativos da web de arquivos de dados PNG do servidor (como? - veja alternativas abaixo)
- Ocasionalmente, o aplicativo da web é sincronizado novamente com o servidor e faz pequenas atualizações / exclusões / adições parciais ao banco de dados PNG
- FYI: Server é um servidor JSON REST, que pode colocar arquivos em wwwroot para coleta
Aqui está minha análise atual de "bancos de dados" baseados em cliente que lidam com armazenamento de blob binários
VER ATUALIZAÇÃO na parte inferior
- AppCache (por meio de manifesto, adicione todos os PNG e, em seguida, atualize sob demanda)
- CON: qualquer alteração de um item do banco de dados PNG significará o download completo de todos os itens no manifesto (notícias realmente ruins!)
- Armazenamento web
- CON: Projetado para armazenamento JSON
- CON: só pode armazenar blobs via codificação base64 (provavelmente falha fatal devido ao custo de decodificação)
- CON: limite rígido de 5 MB para webStorage http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
- PhoneGap e SQLLite
- CON: O patrocinador irá rejeitá-lo como um aplicativo nativo que requer certificação
- Arquivo zip
- O servidor cria um arquivo zip, coloca-o em wwwroot e notifica o cliente
- o usuário tem que descompactar manualmente (pelo menos é assim que eu vejo) e salvar no sistema de arquivos do cliente
- O aplicativo da Web usa a API FileSystem para fazer referência a arquivos
- CON: ZIP pode ser muito grande (zip64?), Muito tempo para criar
- CON: Não tenho certeza se a API FileSystem sempre pode ler do sandbox (acho que sim)
- USB ou cartão SD (de volta à idade da pedra ....)
- O usuário estará local no servidor antes de ficar offline
- Então, poderíamos fazer com que ele insira um cartão SD, deixe o servidor preenchê-lo com arquivos PNG
- Em seguida, o usuário irá conectá-lo ao laptop, tablet
- O aplicativo da Web usará a API FileSystem para ler os arquivos
- CON: Não tenho certeza se a API FileSystem sempre pode ler do sandbox (acho que sim)
- WebSQL
- CON: w3c abandonou (muito ruim)
- Eu posso considerar um wrapper Javascript que usa IndexedDB e WebSQL como uma alternativa
- API FileSystem
- Chrome suporta leitura / gravação de blobs
- CON: não está claro sobre IE e FireFox (IE10, tem msSave não padrão)
- caniuse.com relata suporte a IOS e Android (mas, novamente, isso é apenas r / w de JSON ou inclui a API de blob completa para gravação?
- CON: o pessoal do FireFox não gosta da API FileSystem e não está claro se eles oferecem suporte para salvar blobs: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
- PRO: muito mais rápido do que IndexedDB para blobs de acordo com jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (página 2)
- IndexedDB
- Bom suporte no IE10, FireFox (salvar, ler blobs)
- Boa velocidade e gerenciamento mais fácil do que um sistema de arquivos (exclusões, atualizações)
- PRO: veja os testes de velocidade: http://jsperf.com/indexeddb-vs-localstorage/15
- Veja este artigo sobre armazenamento e exibição de imagens em IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
- CON: Confirmei que o Chrome ainda não oferece suporte à escrita de blob (bug atual, mas não está claro quando será corrigido)
- ATUALIZAÇÃO: os desenvolvedores do Chrome confirmam que estão trabalhando nisso para desktop e Android! sem cronograma ainda.
- Wrapper JavaScript LawnChair http://brian.io/lawnchair/
- PRO: wrapper muito limpo para IndexedDB, WebSQL ou qualquer banco de dados que você tenha (pense em polyfill)
- CON: não é possível armazenar blobs binários, apenas dados: uri (codificação base64) (provavelmente falha fatal devido ao custo de descodificação)
- IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
- Parashuram escreveu um bom wrapper JQUERY para a interface bruta do IndexedDB
- PRO: simplifica muito o uso de IndexedDB, eu esperava adicionar um shim / polyfill para Chrome FileSystemAPI
- CON: Deve lidar com blobs, mas não consegui fazer funcionar
- idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
- Eric Bidelman @ Google escreveu um PolyFill bem testado, a API FileSystem que usa o banco de dados indexado como uma alternativa
- PRO: FileSystem API é bem adequada para armazenar blobs
- PRO: funciona muito bem no FireFox e Chrome
- PRO: ótimo para sincronização com CouchDB baseado em nuvem
- CON: não está claro por que, mas não está funcionando no IE10
- Biblioteca PouchDB JavaScript http://pouchdb.com/
- ótimo para sincronizar um CouchDB com um banco de dados local (usa WebSQL ou IndexedDB (mas não é problema meu)
- CON: SEM CONTRAS, PouchDB agora suporta blobs binários para todos os navegadores recentes (IE, Chrome, Firefox, Chrome no celular, etc.), bem como muitos navegadores mais antigos. Esse não era o caso quando fiz este post pela primeira vez.
NOTA: para ver a codificação data: uri do PNG criei um exemplo em: http://jsbin.com/ivefak/1/edit
Recursos desejados / úteis / desnecessários
- Nenhum aplicativo nativo (EXE, PhoneGap, ObjectiveC, etc) no cliente (aplicativo web puro)
- Só precisa ser executado no Chrome, FireFox, IE10 mais recente para laptops
- Desejo muito a mesma solução para tablet Android (IOS também seria bom), mas só precisa de um navegador para funcionar (FF, Chrome, etc.)
- População de banco de dados inicial rápida
- REQUISITO: recuperação muito rápida de imagens por aplicativo da web do armazenamento (banco de dados, arquivo)
- Não se destina aos consumidores. Podemos restringir os navegadores e pedir ao usuário para fazer configurações e tarefas especiais, mas vamos minimizar isso
Implementações IndexedDB
- Há um excelente artigo sobre como IE, FF e Chrome implementam isso internamente em: http://www.aaron-powell.com/web/indexeddb-storage
- Em resumo:
- O IE usa o mesmo formato de banco de dados do Exchange e Active Directory para IndexedDB
- O Firefox está usando SQLite, então está implementando um banco de dados NoSQL no banco de dados SQL
- Chrome (e WebKit) estão usando um armazenamento de chave / valor que tem herança em BigTable
Meus resultados atuais
- Eu escolhi usar uma abordagem IndexedDB (e polyfill com FileSystemAPI para Chrome até que eles forneçam suporte a blob)
- Para obter os tiles, eu tive um dilema, já que o pessoal do JQUERY está pensando em adicionar isso ao AJAX
- Eu optei pelo XHR2-Lib de Phil Parsons, que é muito parecido com JQUERY .ajax () https://github.com/pmp/xhr2-lib
- Desempenho para downloads de 100 MB (IE10 4s, Chrome 6s, FireFox 7s).
- Não consegui fazer com que nenhum dos wrappers IndexedDB funcionasse para blobs (gramado, PouchDB, jquery-indexeddb etc.)
- Enrolei meu próprio invólucro e o desempenho é (IE10 2s, Chrome 3s, FireFox 10s)
- Com o FF, suponho que estamos vendo o problema de desempenho de usar um banco de dados relacional (sqllite) para um armazenamento não sql
- NOTA, o Chrome tem excelentes ferramentas de depuração (guia do desenvolvedor, recursos) para inspecionar o estado do IndexedDB.
Resultados FINAIS postados abaixo como resposta
Atualizar
O PouchDB agora suporta blobs binários para todos os navegadores recentes (IE, Chrome, Firefox, Chrome no celular, etc.), bem como muitos navegadores mais antigos. Esse não era o caso quando fiz este post pela primeira vez.