Armazenando Dados de Imagem para Aplicativo da Web Off-line (Banco de Dados de Armazenamento do Cliente)

Eu tenho um aplicativo da web off-line usando o appcaching. Eu preciso fornecer cerca de 10MB – 20MB de dados que serão salvos (lado do cliente) consistindo principalmente de arquivos de imagem PNG. A operação é a seguinte:

  1. Downloads de aplicativos da Web e instalações no appcache (usa manifesto)
  2. Solicitações de aplicativos da Web de arquivos de dados PNG do servidor (como? – veja as alternativas abaixo)
  3. Ocasionalmente, o aplicativo da Web faz a reanálise com o servidor e faz pequenas atualizações / exclusões / adições parciais no database PNG
  4. 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ário

VER ATUALIZAÇÃO no fundo

  • AppCache (via manifesto adicionar todo o PNG e, em seguida, atualizar sob demanda)
    • CON: qualquer alteração de um item de database PNG significará o download completo de todos os itens no manifesto (Notícia realmente ruim!)
  • Armazenamento web
    • CON: projetado para armazenamento JSON
    • CON: só pode armazenar blobs via codificação base64 (falha provavelmente 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: Patrocinador irá rejeitá-lo como um aplicativo nativo que exige certificação
  • Arquivo ZIP
    • Servidor cria um arquivo zip, coloca-o em wwwroot e notifica o cliente
    • o usuário precisa descompactar manualmente (pelo menos é assim que eu vejo) e salvar no sistema de arquivos do cliente
    • 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 o sandbox (acho que sim)
  • USB ou cartão SD (de volta à idade da pedra ….)
    • O usuário será local para o servidor antes de ficar off-line
    • Para que possamos inserir 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 o sandbox (acho que sim)
  • WebSQL
    • CON: w3c abandonou (muito ruim)
    • Eu poderia considerar um wrapper Javascript que usa IndexedDB e WebSQL como um fall-back
  • API FileSystem
    • O Chrome suporta leitura / gravação de blobs
    • CON: não é claro sobre o IE e FireFox (IE10, tem msSave não padrão)
    • caniuse.com relata suporte IOS e Android (mas, novamente, isso é apenas r / w de JSON ou inclui a API de blob completa para gravação?
    • CON: FireFox pessoas não gostam FileSystem API e não está claro se eles estão apoiando salvando blobs: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
    • PRO: Muito mais rápido que o IndexedDB para blobs de acordo com o 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 no IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CON: Confirmei que o Chrome ainda não suporta a gravação de blob (bug atual, mas não está claro quando será corrigido)
    • ATUALIZAÇÃO: os desenvolvedores do Chrome confirmam que estão trabalhando nisso tanto para computadores quanto para android! ainda não há cronograma.
  • LawnChair JavaScript wrapper http://brian.io/lawnchair/
    • PRO: wrapper muito limpo para IndexedDB, WebSQL ou qualquer database que você tem (pense polyfill)
    • CON: não é possível armazenar blobs binários, apenas dados: uri (codificação base64) (falha provavelmente fatal devido ao custo de decodificação)
  • IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuram escreveu um ótimo wrapper JQUERY para a interface raw do IndexedDB
    • PRO: simplifica bastante o uso do IndexedDB, eu estava esperando adicionar um shim / polyfill para o Chrome FileSystemAPI
    • CON: Ele deve lidar com blobs, mas não consegui fazê-lo 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 na API FileSystem que usa o Indexed DB como um fallback
    • PRO: FileSystem API é bem adequado para armazenar blobs
    • PRO: funciona muito bem no FireFox e no Chrome
      • PRO: ótimo para sincronizar com o CouchDB baseado em nuvem
    • CON: não claro porque, mas não está funcionando no IE10
  • Biblioteca JavaScript PouchDB http://pouchdb.com/
    • ótimo para sincronizar um CouchDB com um database local (usa WebSQL ou IndexedDB (não é problema meu)
    • CON: NO CONS, o PouchDB agora suporta blobs binários para todos os navegadores recentes (IE, Chrome, Firefox, Chrome no celular, etc.), além de muitos navegadores mais antigos. Esse não foi o caso quando eu fiz este post.

NOTA: para ver um dado: uri codificação do PNG Eu criei um exemplo em: http://jsbin.com/ivefak/1/edit

Recursos desejados / úteis / não aproveitados

  • Nenhum aplicativo nativo (EXE, PhoneGap, ObjectiveC, etc) no cliente (aplicativo web puro)
  • Só precisa ser executado no último Chrome, FireFox, IE10 para laptops
  • Fortemente quero a mesma solução para Android Tablet (IOS seria bom também), mas só precisa de um navegador para trabalhar (FF, Chrome, etc.)
  • População DB inicial rápida
  • REQUISITO: Recuperação muito rápida de imagens por aplicativo da Web a partir do armazenamento (DB, arquivo)
  • Não é para os consumidores. Podemos restringir navegadores e pedir ao usuário para fazer configurações e tarefas especiais, mas vamos minimizar isso

Implementações IndexedDB

  • Existe um excelente artigo sobre como o IE, FF e o Chrome implementam internamente isso em: http://www.aaron-powell.com/web/indexeddb-storage
  • Em resumo:
    • IE usa o mesmo formato de database que o Exchange e o Active Directory para IndexedDB
    • O Firefox está usando o SQLite, então estamos implementando um database NoSQL no database SQL
    • O Chrome (e o WebKit) estão usando um armazenamento Key / Value que tem inheritance no BigTable

Meus resultados atuais

  • Eu escolhi usar uma abordagem do IndexedDB (e polyfill com FileSystemAPI para Chrome até que eles enviem suporte blob)
  • Para buscar os tiles, eu tive um dilema já que o pessoal do JQUERY está pesquisando sobre adicionar isso ao AJAX
  • Eu fui com XHR2-Lib por 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).
  • Eu não consegui fazer com que nenhum dos wrappers do IndexedDB funcionasse para blobs (lawnchair, PouchDB, jquery-indexeddb, etc.)
  • Eu rolei meu próprio wrapper e desempenho é (IE10 2s, Chrome 3s, FireFox 10s)
  • Com o FF, presumo que estamos vendo o problema de desempenho de usar um database relacional (sqllite) para um armazenamento não-sql
  • OBSERVAÇÃO, o Chrome possui ferramentas de debugging pendentes (guia do desenvolvedor, resources) 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 foi o caso quando eu fiz este post.

Resultados Cache de blob off-line para mapas PNG escorregadios

Testando

  • 171 arquivos PNG (total de 3.2MB)
  • Plataformas testadas: Chrome v24, FireFox 18, IE 10
  • Também deve trabalhar com o Chrome & FF para Android

Buscar do servidor da web

  • usando XHR2 (suportado em quase todos os navegadores) para download de blob do servidor web
  • Eu fui com XHR2-Lib por Phil Parsons, que é muito parecido com JQUERY .ajax ()

Armazenamento

Exibição

  • Eu estou usando o Leaflet http://leafletjs.com/ para mostrar os blocos do mapa
  • Eu usei o plugin de camada de bloco funcional por Ishmael Smyrnow para buscar a camada de mosaico do DB
  • Eu comparei a camada de blocos baseada em database com um armazenamento puramente local (localhost: //)
  • Não há diferença perceptível no desempenho! entre usando IndexedDB e arquivos locais!

Resultados

  • Chrome: busca (6.551s), loja (8.247s), tempo decorrido total: (13.714s)
  • FireFox: busca (0,422s), armazenamento (31,519s), tempo total decorrido: (32,836s)
  • IE 10: buscar (0,668 s), armazenar: (0,896 s), tempo decorrido total: (3,758 s)

Para suas necessidades, sugiro que o desenvolvimento de um novo polyfill baseado em dois outros: API FileSystem para IndexedDB e IndexedDB para WebSQL – seja a melhor opção.

O primeiro permitirá o suporte ao armazenamento de blobs no Chrome (FileSystem API) e no Firefox (IndexedDB), enquanto o segundo deverá fornecer o suporte para Android e iOS ( WebSQL ). O que é necessário é apenas fazer esses polyfills funcionarem juntos, e suponho que não seja difícil.

Nota: Como não encontrei nenhuma informação na Web sobre isso, você deve testar se o armazenamento de blobs usando o polyfill WebSQL funcionará em iOS e Android. Parece que deve funcionar embora:

var sql = ["CREATE TABLE", idbModules.util.quote(storeName), "(key BLOB", createOptions.autoIncrement ? ", inc INTEGER PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY", ", value BLOB)"].join(" ") 

Fonte

Alguns anos atrás (não exatamente a idade da pedra), eu estava usando um applet java assinado que consultaria seu servidor para os requisitos de synchronization / atualização, baixaria os arquivos apropriados do servidor e os salvaria no sistema de arquivos do usuário (não em um database). Essa solução pode funcionar para você, embora você precise de alguém para escrever o applet e assiná-lo. Para soluções de database, tal applet pode usar o jdbc disponível para a maioria dos bancos de dados usando localhost em uma porta adequada (por exemplo, 3306 para MySQL). Eu acredito que a tag do applet está obsoleta no Html5, mas ainda funciona. Nenhuma experiência em tablets Android, por isso não é possível comentar essa parte.

Eu tenho exemplos de cache de mapas (exemplo aberto, descobrir regiões e zooms, alternar off-line e regiões descobertas serão disponibilizadas).

map.js – camada de mapa para blocos offline, storage.js – implementação de armazenamento baseada em IndexedDb e WebSQL (mas isso apenas testa a implementação com desempenho ruim).

  • Para arquivos de site (html, css, js e etc.) eu prefiro usar o cache de aplicativos.
  • Para armazenamento, prefiro usar DB indexado (blob de suporte), Web SQL (somente base64), FileWriter (blob de suporte, mas apenas chrome). Francamente, o armazenamento é um grande problema para isso. Você precisa da solução de valor de chave mais rápida que irá misturá-los. Eu acho que é uma boa decisão usar a solução existente.
  • Para buscar usei canvas com o CORS. Mas eu penso no WebWorkers e no XHR2 e isso pode ser melhor em vez do canvas porque o canvas tem alguns problemas com o CORS em navegadores diferentes e outros (por exemplo, esse título foi armazenado de maneira ruim na ópera ).

Informações adicionais sobre tamanhos para 2 bilhões de cidades ( Minsk ):

  • Zoom – 9, ladrilhos – 2, tamanho – 52 kb, com anterior – 52 kb;
  • Zoom – 10, ladrilhos – 3, tamanho – 72 kb, com anterior – 124 kb;
  • Zoom – 11, telhas – 7, tamanho – 204 kb, com anterior – 328 kb;
  • Zoom – 12, ladrilhos – 17, tamanho – 348 kb, com anterior – 676 ​​kb;
  • Zoom – 13, ladrilhos – 48, tamanho – 820 kb, com anterior – 1,5 mb;
  • Zoom – 14, ladrilhos – 158, tamanho – 2,2 mb, com anterior – 3,7 mb;
  • Zoom – 15, ladrilhos – 586, tamanho – 5,5 mb, com anterior – 9,3 mb;
  • Zoom – 16, telhas – 2264, tamanho – 15 mb, com anterior – 24,3 mb;
    Intereting Posts