Зберігання графічних даних для офлайн-веб-застосунку (база даних для зберігання на клієнті)


105

У мене є офлайн-веб-додаток із використанням програми кешування. Мені потрібно надати приблизно 10 Мб - 20 МБ даних, які вони збережуть (на стороні клієнта), що складаються переважно з файлів зображень PNG. Операція полягає в наступному:

  1. Веб-додаток завантажує та встановлює в appcache (використовує маніфест)
  2. Запити веб-додатків із файлів даних PNG сервера (як? - див. Альтернативи нижче)
  3. Інколи веб-додаток перетворюється на сервер і робить невеликі часткові оновлення / видалення / доповнення до бази даних PNG
  4. FYI: Сервер - це сервер JSON REST, який може розміщувати файли в wwwroot для підбору

Ось мій поточний аналіз клієнтських "баз даних", які обробляють бінарне сховище даних

ДИВІТЬ ОНОВЛЕННЯ знизу

  • AppCache (через маніфест додайте всі PNG, а потім оновіть на вимогу)
    • CON: будь-яка зміна елемента бази даних PNG означатиме повне завантаження всіх елементів у маніфесті (Дійсно погані новини!)
  • WebStorage
    • CON: Призначений для зберігання JSON
    • CON: можна зберігати краплі тільки через кодування base64 (ймовірно, фатальний недолік через вартість декодування)
    • CON: жорсткий ліміт 5 Мб для веб-зберігання http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
  • PhoneGap & SQLLite
    • CON: Спонсор відхилить його як нативну програму, яка потребує сертифікації
  • ZIP-файл
    • Сервер створює zip-файл, розміщує його у wwwroot та повідомляє клієнта
    • користувачеві потрібно вручну розпакувати (принаймні, так я бачу) та зберегти у файловій системі клієнта
    • Веб-додаток використовує API FileSystem для посилання на файли
    • CON: ZIP може бути занадто великим (zip64?), І його довго створювати
    • CON: Не впевнений, чи API FileSystem завжди може зчитувати з пісочного ящика (я думаю, що так)
  • USB або SD-карта (назад до кам'яної доби ....)
    • Користувач буде локальним для сервера, перш ніж перейти в режим офлайн
    • Таким чином, ми могли б дати йому вставити SD-карту, нехай сервер заповнить її файлами PNG
    • Тоді користувач підключить його до ноутбука, планшета
    • Веб-додаток використовує API FileSystem для читання файлів
    • CON: Не впевнений, чи API FileSystem завжди може зчитувати з пісочного ящика (я думаю, що так)
  • WebSQL
    • CON: w3c відмовився від цього (досить погано)
    • Я міг би розглянути обгортку Javascript, яка використовує IndexedDB та WebSQL як резервну копію
  • API FileSystem
    • Chrome підтримує читання / запис крапок
    • CON: не зрозуміло про IE та FireFox (IE10, має нестандартний msSave)
    • caniuse.com повідомляє про підтримку IOS та Android (але знову ж таки, це лише r / w JSON, чи він включає повний API API для написання?
    • CON: FireFox людям не подобається API FileSystem і не зрозуміло, чи підтримують вони збереження крапок: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
    • PRO: Набагато швидше, ніж IndexedDB для крапель відповідно до jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (стор. 2)
  • ІндексованийDB
    • Хороша підтримка в IE10, FireFox (зберегти, читати краплі)
    • Хороша швидкість і легше управління, ніж файлова система (видалення, оновлення)
    • PRO: див. Тести на швидкість: http://jsperf.com/indexeddb-vs-localstorage/15
    • Дивіться цю статтю про зберігання та відображення зображень у IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CON: Я підтвердив, що Chrome ще не підтримує написання блобу (поточна помилка, але не зрозуміло, коли вона буде виправлена)
    • ОНОВЛЕННЯ: Розробники Chrome підтверджують, що працюють над цим як для робочого столу, так і для Android! ще немає термінів.
  • LawnChair JavaScript обгортка http://brian.io/lawnchair/
    • PRO: дуже чиста обгортка для IndexedDB, WebSQL або будь-якої іншої бази даних (подумайте polyfill)
    • CON: не можна зберігати двійкові краплі, лише дані: uri (кодування base64) (ймовірно, фатальний недолік через вартість декодування)
  • IndexedDB Jquery polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuram написав гарну оболонку JQUERY для необмеженого інтерфейсу IndexedDB
    • PRO: значно спрощує використання IndexedDB, я сподівався додати shim / polyfill для Chrome FileSystemAPI
    • КОН: Він повинен обробляти краплі, але мені не вдалося змусити його працювати
  • idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bring-the-html5-filesystem-api
    • Ерік Бідельман @ Google написав добре перевірений API PolyFill FileSystem API, який використовує індексовану БД як резервну копію
    • PRO: API FileSystem добре підходить для зберігання крапів
    • PRO: чудово працює на FireFox та Chrome
      • PRO: чудово підходить для синхронізації з хмарним CouchDB
    • CON: не зрозуміло чому, але він не працює на IE10
  • Бібліотека JavaScript PouchDB http://pouchdb.com/
    • відмінно підходить для синхронізації CouchDB з локальною БД (використовує або WebSQL, або IndexedDB (хоча це не моя проблема)
    • CON: NO CONS, PouchDB тепер підтримує бінарні краплі для всіх останніх веб-переглядачів (IE, Chrome, Firefox, Chrome для мобільних пристроїв тощо), а також багатьох старих браузерів. Це було не так, коли я вперше займав цю посаду.

ПРИМІТКА: щоб побачити дані: uri-кодування PNG, я створив приклад за адресою: http://jsbin.com/ivefak/1/edit

Бажані / корисні / непотрібні функції

  • Немає нативного (EXE, PhoneGap, ObjectiveC тощо) програми для клієнта (чистий веб-додаток)
  • Потрібно працювати лише на останніх версіях Chrome, FireFox, IE10 для ноутбуків
  • Дуже хочеться того ж рішення для Android планшетного ПК (IOS також було б непогано), але для роботи потрібен лише один браузер (FF, Chrome тощо)
  • Швидка початкова популяція БД
  • ВИМОГА: Дуже швидке завантаження зображень веб-додатком із сховища (БД, файл)
  • Не призначений для споживачів. Ми можемо обмежити веб-переглядачі та попросити користувача виконати спеціальні налаштування та завдання, але давайте мінімізуємо це

Реалізація індексованих банків

  • Є чудова стаття про те, як IE, FF і Chrome внутрішньо реалізують це за адресою: http://www.aaron-powell.com/web/indexeddb-storage
  • Коротко:
    • IE використовує той самий формат бази даних, що і Exchange та Active Directory для IndexedDB
    • Firefox використовує SQLite, тому вони реалізують базу даних NoSQL у базі даних SQL
    • Chrome (і WebKit) використовують магазин Key / Value, який має спадщину в BigTable

Мої поточні результати

  • Я вирішив використовувати підхід IndexedDB (і поліфунтування з FileSystemAPI для Chrome, поки вони не отримають підтримку blob)
  • Для отримання плиток у мене була дилема, оскільки люди JQUERY зворушливо додають це до AJAX
  • Я пішов з XHR2-Lib від Філа Парсонса, що дуже схоже на JQUERY .ajax () https://github.com/pmp/xhr2-lib
  • Продуктивність для завантаження 100MB (IE10 4s, Chrome 6s, FireFox 7s).
  • Я не зміг змусити жодної обгортки IndexedDB працювати для крапель (газон, гаманець, PouchDB, jquery-indexeddb тощо)
  • Я згорнув власну обгортку, і продуктивність (IE10 2s, Chrome 3s, FireFox 10s)
  • З FF, я припускаю, що ми бачимо проблеми продуктивності використання реляційного БД (sqllite) для не-sql сховища
  • ПРИМІТКА. У Chrome є видатні інструменти для налагодження (вкладка розробника, ресурси) для перевірки стану IndexedDB.

Фінальні результати, розміщені нижче як відповідь

Оновлення

PouchDB тепер підтримує двійкові краплі для всіх останніх веб-переглядачів (IE, Chrome, Firefox, Chrome для мобільних пристроїв тощо), а також багатьох старих браузерів. Це було не так, коли я вперше займав цю посаду.


1
webstorage не підтримує json, а рядки, тому ви можете base64 кодувати свій imagez і служити їм назад як dataurls.
mpm

Гаразд, але, мабуть, не оптимально (або в межах квоти) для 20 Мб зображень, що насправді є ковзаючими плитками карти, які потрібно швидко витягувати та відображати за допомогою програми LEAFLET на карті, коли ви збільшуєте та переміщуєте зображення.
Dr.YSG

Дослідження, які ви зробили, дуже корисні.
Богдан Кулинич

моя думка - вам не потрібно мати справу з двійковими краплями, якщо ви використовуєте зображення PNG.
mpm

Ви маєте рацію, чи не заперечуєте ви, якщо я оновлюю документ, щоб відобразити ваш внесок?
Dr.YSG

Відповіді:


25

Результати офлайн кеш-пам'яті для PNG слизьких карт

Тестування

  • 171 файл PNG (всього 3,2 МБ)
  • Тестовані платформи: Chrome v24, FireFox 18, IE 10
  • Також слід працювати з Chrome & FF для Android

Витягнути з веб-сервера

  • використання XHR2 (підтримується майже у всіх браузерах) для завантаження блобу з веб-сервера
  • Я пішов з XHR2-Lib від Філа Парсонса, що дуже схоже на JQUERY .ajax ()

Зберігання

  • IndexedDB для IE та FireFox
  • Chrome: Polyfill (блок зберігається за допомогою API FileSystem, посилання зберігається в IndexedDB) polyfill
  • Обов’язково прочитати статтю на тему "Як браузери зберігають дані IndexedDB"
  • Примітка: FireFox використовує SQLlite для NOSQL IndexedDB. Це може бути причиною повільної роботи. (краплі зберігаються окремо)
  • Примітка: Microsoft IE використовує розширюваний механізм зберігання даних:
  • Примітка: Chrome використовує LevelDB http://code.google.com/p/leveldb/

Дисплей

  • Я використовую листівку http://leafletjs.com/, щоб показати плитки карти
  • Я використовував плагін функціонального шару плитки від Ізмаїла Смирнова для отримання шару плитки з БД
  • Я порівняв шар плитки на основі БД із суто локальним сховищем (localhost: //)
  • Немає помітної різниці в продуктивності! між використанням IndexedDB та локальними файлами!

Результати

  • Chrome: Вибір (6.551s), Магазин (8.247s), Загальний минулий час: (13.714s)
  • FireFox: Fetch (0.422s), Store (31.519s), Total Elapsed Time: (32.836s)
  • IE 10: Вибір (0,668), Магазин: (0,896), Загальний час, що минув: (3,708)

4

Для ваших вимог я пропоную розробити нову полісистему на основі двох інших: API FileSystem для IndexedDB і IndexedDB для WebSQL - найкращий варіант.

Перший дозволить підтримувати зберігання крапів у Chrome (API FileSystem) та Firefox (IndexedDB), а другий повинен підтримувати Android та iOS ( WebSQL ). Що потрібно - це просто змусити ці поліфіли працювати разом, і я вважаю, що це не важко.

NB: Оскільки я не зміг знайти будь-якої інформації в Інтернеті з цього приводу, ви повинні перевірити, чи зберігання крапок за допомогою поліфікса WebSQL буде працювати на iOS та Android. Схоже, це має працювати, хоча:

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

Джерело


Я схиляюся до вашої пропозиції, але чекаю від інших. У мене немає зручного андроїда, але було б добре створити jsBin або jsFiddle і подивитися, що працює на Android.
Dr.YSG

1
Ці два краплі різні. Sqlite blob - це масив масиву в JavaScript, тоді як js blob не має еквівалента в sqlite. Blob не може перетворитись на масив буфера, хоча він може бути структурно клонований.
Kyaw Tun

2

У мене є приклади кешування карт (відкритий приклад, відкрийте для себе регіони та масштабування, доступ до переключення в офлайн та виявлені регіони буде доступний).

Є map.js- шар карти для офлайн-плиток, storage.js- реалізація пам’яті на основі IndexedDb та WebSQL (але це лише тестова реалізація з низькою продуктивністю).

  • Для файлів сайту (html, css, js та ін.) Я вважаю за краще використовувати кеш додатків.
  • Для зберігання я віддаю перевагу використовувати індексовану БД (підтримка blob), Web SQL (тільки base64), FileWriter (підтримка blob, але тільки хром). Відверто кажучи, зберігання - це велика проблема для цього. Вам потрібно найшвидше рішення ключового значення, яке змішить їх усі. Я думаю, що добре рішення використовувати існуюче рішення.
  • Для отримання я використовував полотно з CORS. Але я думаю про WebWorkers та XHR2, і це може бути краще, ніж полотно, тому що у полотна є деякі проблеми з CORS у різних браузерах та інші (наприклад, цей заголовок погано зберігався в опері ).

Додаткова інформація про розміри для 2 мільярдів міста ( Мінськ ):

  • Zoom - 9, плитка - 2, розмір - 52 kb, з попереднім - 52 kb;
  • Zoom - 10, плитка - 3, розмір - 72 kb, з попереднім - 124 kb;
  • Зум - 11, плитка - 7, розмір - 204 кб, з попереднім - 328 кб;
  • Зум - 12, плитка - 17, розмір - 348 кб, з попереднім - 676 ​​кб;
  • Зум - 13, плитка - 48, розмір - 820 кб, з попереднім - 1,5 мб;
  • Zoom - 14, плитка - 158, розмір - 2,2 mb, з попереднім - 3,7 mb;
  • Zoom - 15, плитка - 586, розмір - 5,5 mb, з попереднім - 9,3 mb;
  • Zoom - 16, плитка - 2264, розмір - 15 mb, з попереднім - 24.3 mb;

Я припускаю, що це JPG плитки у слизькому форматі EGPS3857, правда? так як я використовую листівку і роблю растрові накладки, мені довелося піти з PNG. також перегляньте мою демонстрацію використання PouchDB (який використовує IDB під ним). stackoverflow.com/questions/16721312 / ...
Dr.YSG

О так, ви кешуєте на льоту, але чи знаєте ви, куди я можу поїхати, щоб отримати заздалегідь вбудовану карту OSM (у всьому світі), щоб збільшити масштаб 10, 11 чи 12? Ми збережемо це на нашому автономному сервері.
Dr.YSG

Ні, використовується PNGдля проекції за замовчуванням (EGPS: 3857), але незалежно від того, JPEGабо PNGтому, що використовується imgтегом або canvas. З мого прикладу ви можете просто передзавантажити плитки, якщо ви знаєте клавіші плиток ( storage.add('x_y_z', 'data:image/png;base64,...')для кожної збереженої плитки), але ви завжди можете їх отримати, якщо знаєте лише межі (багатокутник) та масштабування.
tbicr

Я хочу переконатися, що у нас немає мовної проблеми. Чи є у вас якесь місце, де ми можемо отримати всесвітній набір OSM з слизьких плиток (PNG або JPG) для збільшення рівня 10?
Dr.YSG

Ви можете отримати форму плитки tile.osm.org(mapnik renderer). Наприклад http://tile.openstreetmap.org/10/590/329.png( zoom/ x/ y.png). Ці плитки мають Access-Control-Allow-Origin: *заголовки, тому ви можете отримати їх ajax або отримати дані uri (base64) полотном. Ви вже можете завантажити плитки з вашим manifest.json {id: 0-0-0}, але ви повинні впевнені , що є право zoom, x, yпослідовність.
tbicr

1

Кілька років тому (не зовсім кам'яний вік) я використовував підписаний аплет Java, який запитував би його сервер на вимоги синхронізації / оновлення, завантажував відповідні файли з сервера та зберігав їх у файловій системі користувача (не в базі даних). Це рішення може допомогти вам, хоча вам буде потрібно, щоб хтось написав аплет і підписав його. Для рішень бази даних такий аплет може використовувати jdbc, доступний для більшості баз даних, використовуючи localhost на відповідному порту (наприклад, 3306 для MySQL). Я вважаю, що тег аплета застарілий у Html5, але він все ще працює. Немає досвіду роботи з планшетами Android, тому не можу коментувати цю частину.


1
Я почав програмувати у FORTRAN в 1968 році за допомогою карт-перфоратора. Тож рішення з кам'яного віку для мене не є новими.
Dr.YSG
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.