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


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.