为离线 Web 应用程序存储图像数据(客户端存储数据库) [英] Storing Image Data for offline web application (client-side storage database)
问题描述
我有一个使用 appcaching 的离线 Web 应用程序.我需要向它提供大约 10MB - 20MB 的数据,它将保存(客户端)主要由 PNG 图像文件组成.操作如下:
- Web 应用程序在 appcache 中下载和安装(使用清单)
- 来自服务器 PNG 数据文件的 Web 应用请求(如何? - 请参阅下面的替代方案)
- 偶尔 Web 应用会与服务器重新同步,并对 PNG 数据库进行小部分更新/删除/添加
- 仅供参考:Server 是一个 JSON REST 服务器,可以将文件放在 wwwroot 中以供提取
这是我目前对基于客户端的数据库"的分析处理二进制 blob 存储
见底部更新
AppCache(通过清单添加所有 PNG,然后按需更新)
- 缺点:对 PNG 数据库项目的任何更改都意味着完整下载清单中的所有项目(真是个坏消息!)
网络存储
- 缺点:专为 JSON 存储而设计
- CON:只能通过 base64 编码存储 blob(由于解编码的成本,这可能是致命的缺陷)
- 缺点:webStorage 的硬限制为 5MB http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
PhoneGap &SQLLite
- 缺点:赞助商将拒绝它作为需要认证的原生应用
ZIP 文件
- 服务器创建一个 zip 文件,将其放置在 wwwroot 中,并通知客户端
- 用户必须手动解压缩(至少我是这么看的)并保存到客户端文件系统
- Web 应用程序使用 FileSystem API 来引用文件
- 缺点:ZIP 可能太大(zip64?),需要很长时间才能创建
- 缺点:不确定 FileSystem API 是否总能从沙箱中读出(我认为是这样)
USB 或 SD 卡(回到石器时代......)
- 用户在离线前将位于服务器本地
- 这样我们就可以让他插入一张 SD 卡,让服务器用 PNG 文件填充它
- 然后用户将其插入笔记本电脑、平板电脑
- Web 应用程序将使用 FileSystem API 读取文件
- 缺点:不确定 FileSystem API 是否总能从沙箱中读出(我认为是这样)
WebSQL
- CON:w3c 已经放弃了(非常糟糕)
- 我可能会考虑使用 IndexedDB 和 WebSQL 作为后备的 Javascript 包装器
文件系统 API
- Chrome 支持 Blob 的读/写
- 缺点:不清楚 IE 和 FireFox(IE10,具有非标准的 msSave)
- caniuse.com 报告了 IOS 和 Android 支持(但同样,这只是 JSON 的 r/w,还是包含用于编写的完整 blob API?
- 缺点:FireFox 的人不喜欢 FileSystem API &不清楚他们是否支持保存 blob:https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
- PRO:根据 jsperf http://jsperf.com/indexeddb-vs-localstorage/15(第 2 页)
IndexedDB
- 对 IE10、FireFox 的良好支持(保存、读取 blob)
- 比文件系统(删除、更新)更快且更容易管理
- PRO:查看速度测试:http://jsperf.com/indexeddb-vs-localstorage/15
- 请参阅有关在 IndexedDB 中存储和显示图像的文章:https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
- 缺点:我确认 Chrome 尚不支持 blob 写入(当前错误,但不清楚何时修复)
- 更新:2014 年 6 月的一篇博文表明 Chrome 现在支持
IndexedDB
中的 blob - 更新:This caniuse/indexeddb 确认:Chrome 36 及以下版本不支持 Blob 对象作为 indexedDB 值.";建议 >Chrome36 支持 Blob 对象.
LawnChair JavaScript 包装器 http://brian.io/lawnchair/一个>
- PRO:非常干净的 IndexedDB、WebSQL 或您拥有的任何数据库的包装器(想想 polyfill)
- CON:无法存储二进制 blob,只能存储 data:uri(base64 编码)(由于解编码成本,可能是致命缺陷)
IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
- Parashuram 为原始 IndexedDB 接口编写了一个很好的 JQUERY 包装器
- PRO:极大地简化了 IndexedDB 的使用,我希望为 Chrome FileSystemAPI 添加一个 shim/polyfill
- 缺点:它应该可以处理斑点,但我无法让它工作
idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
- Eric Bidelman @ Google 编写了一个经过良好测试的 PolyFill FileSystem API,它使用索引数据库作为后备
- PRO:FileSystem API 非常适合存储 blob
- PRO:在 FireFox 和 Chrome 上运行良好
- PRO:非常适合与基于云的 CouchDB 同步
- 缺点:不清楚原因,但它不适用于 IE10
PouchDB JavaScript 库 http://pouchdb.com/>
- 非常适合将 CouchDB 与本地数据库同步(使用 WebSQL 或 IndexedDB(不过不是我的问题)
- 缺点:没有缺点,PouchDB 现在支持所有最新浏览器(IE、Chrome、Firefox、移动版 Chrome 等)以及许多旧版浏览器的二进制 blob.我第一次写这篇文章时情况并非如此.
注意:要查看 PNG 的 data:uri 编码,我在以下位置创建了一个示例:http://jsbin.com/ivefak/1/edit
想要/有用/不需要的功能
- 客户端上没有原生(EXE、PhoneGap、ObjectiveC 等)应用(纯网络应用)
- 只需要在最新的 Chrome、FireFox、IE10 笔记本电脑上运行
- 强烈希望为 Android 平板电脑提供相同的解决方案(IOS 也不错)但只需要一个浏览器即可工作(FF、Chrome 等)
- 快速初始数据库填充
- 要求:Web 应用程序从存储(数据库、文件)中快速检索图像
- 不适合消费者.我们可以限制浏览器,并要求用户做特殊的设置&任务,但让我们尽量减少
IndexedDB 实现
- 有一篇关于 IE、FF 和 Chrome 如何在内部实现这一点的优秀文章:http://www.aaron-powell.com/web/indexeddb-storage
- 简而言之:
- IE 对 IndexedDB 使用与 Exchange 和 Active Directory 相同的数据库格式
- Firefox 正在使用 SQLite,因此可以在 SQL 数据库中实现 NoSQL 数据库
- Chrome(和 WebKit)正在使用继承 BigTable 的键/值存储
我目前的成绩
- 我选择使用 IndexedDB 方法(并使用 FileSystemAPI for Chrome 进行 polyfill,直到它们提供 blob 支持)
- 为了获取磁贴,我遇到了难题,因为 JQUERY 的人正在犹豫要不要将其添加到 AJAX 中
- 我使用了 Phil Parsons 的 XHR2-Lib,它非常像 JQUERY .ajax() https://github.com/pmp/xhr2-lib
- 100MB 下载的性能(IE10 4s、Chrome 6s、FireFox 7s).
- 我无法让任何 IndexedDB 包装器用于 blob(lawnchair、PouchDB、jquery-indexeddb 等)
- 我推出了自己的包装器,性能是(IE10 2s、Chrome 3s、FireFox 10s)
- 对于 FF,我假设我们看到了将关系数据库 (sqllite) 用于非 sql 存储的性能问题
- 注意,Chrome 具有出色的调试工具(开发者选项卡、资源),用于检查 IndexedDB 的状态.
最终结果作为答案发布在下面
更新
PouchDB 现在支持所有最新浏览器(IE、Chrome、Firefox、移动版 Chrome 等)以及许多旧浏览器的二进制 blob.我第一次写这篇文章时情况并非如此.
结果 PNG 滑动贴图的离线 blob 缓存
测试
- 171 个 PNG 文件(共 3.2MB)
- 测试平台:Chrome v24、FireFox 18、IE 10
- 还应该与 Chrome & 一起使用FF 安卓版
从网络服务器获取
- 使用 XHR2(几乎所有浏览器都支持)从 Web 服务器下载 blob
- 我使用了 Phil Parsons 的 XHR2-Lib,它非常像 JQUERY .ajax()
存储
- 用于 IE 和 FireFox 的 IndexedDB
- Chrome:Polyfill(使用 FileSystem API 存储的 blob,引用保存在 IndexedDB 中)polyfill
- 一篇关于浏览器如何存储 IndexedDB 数据"的必读文章
- 注意:FireFox 将 SQLlite 用于 NOSQL IndexedDB.这可能是性能缓慢的原因.(Blob 单独存储)
- 注意:Microsoft IE 使用可扩展存储引擎:
- 注意:Chrome 使用 LevelDB http://code.google.com/p/leveldb/
显示
- 我正在使用 Leaflet http://leafletjs.com/ 来显示地图图块
- 我使用了 Ishmael Smyrnow 的功能瓦片层插件来从数据库中获取瓦片层
- 我将基于数据库的切片层与纯本地 (localhost://) 存储进行了比较
- 性能没有明显差异!使用 IndexedDB 和本地文件之间的区别!
结果
- Chrome:获取(6.551 秒)、存储(8.247 秒)、总耗时:(13.714 秒)
- FireFox:获取(0.422 秒)、存储(31.519 秒)、总耗时:(32.836 秒)
- IE 10:获取(0.668 秒),存储:(0.896 秒),总运行时间:(3.758 秒)
I have an offline web application using appcaching. I need to provide it about 10MB - 20MB of data that it will save (client-side) consisting mainly of PNG image files. The operation is as follows:
- Web application downloads and installs in appcache (uses manifest)
- Web app requests from server PNG data files (how? - see alternatives below)
- Occasionally web app resyncs with server, and does small partial updates/deletes/additions to PNG database
- FYI: Server is a JSON REST server, that can place files in wwwroot for pickup
Here is my current analysis of client-based "databases" that handle binary blob storage
SEE UPDATE at Bottom
AppCache (via manifest add all the PNG and then update on demand)
- CON: any change of a PNG database item will mean complete download of all items in manifest (Really bad news!)
WebStorage
- CON: Designed for JSON storage
- CON: can only store blobs via base64 encoding (probably fatal flaw due to cost of de-encoding)
- CON: Hard limit of 5MB for webStorage http://htmlui.com/blog/2011-08-23-5-obscure-facts-about-html5-localstorage.html
PhoneGap & SQLLite
- CON: Sponsor will reject it as a native app requiring certification
ZIP file
- Server creates a zip file, places it in wwwroot, and notifies client
- user has to manually unzip (At least that is how I see it) and save to client file system
- Web app uses FileSystem API to reference files
- CON: ZIP might be too large (zip64?), long time to create
- CON: Not sure if FileSystem API can always read out of the sandbox (I think so)
USB or SD card (back to the stone age....)
- The user will be local to the server before going offline
- So we could have him insert a SD card, let the server fill it with PNG files
- Then the user will plug it into the laptop, tablet
- Web app will use FileSystem API to read the files
- CON: Not sure if FileSystem API can always read out of the sandbox (I think so)
WebSQL
- CON: w3c has abandoned it (pretty bad)
- I might consider a Javascript wrapper that uses IndexedDB and WebSQL as a fall-back
FileSystem API
- Chrome supports read/write of blobs
- CON: not clear about IE and FireFox (IE10, has non-standard msSave)
- caniuse.com reports IOS and Android support (but again, is this just r/w of JSON, or does it include the full blob API for writing?
- CON: FireFox folks dislike FileSystem API & not clear if they are supporting saving blobs: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
- PRO: Much faster than IndexedDB for blobs according to jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (page 2)
IndexedDB
- Good support in IE10, FireFox (save, read blobs)
- Good speed and easier management than a file system (deletes, updates)
- PRO: see speed tests: http://jsperf.com/indexeddb-vs-localstorage/15
- See this article on storing and display of images in IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
- CON: I confirmed that Chrome does not yet support blob writing (current bug, but not clear when it will be fixed)
- UPDATE: A June 2014 blogpost suggests Chrome now supports blobs in
IndexedDB
- UPDATE: This caniuse/indexeddb confirms: "Chrome 36 and below did not support Blob objects as indexedDB values."; suggesting >Chrome36 supports Blob objects.
LawnChair JavaScript wrapper http://brian.io/lawnchair/
- PRO: very clean wrapper for IndexedDB, WebSQL or whatever database you have (think polyfill)
- CON: cannot store binary blobs, only data:uri (base64 encoding) (probably fatal flaw due to cost of de-encoding)
IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
- Parashuram has writtent a nice JQUERY wrapper for the raw IndexedDB interface
- PRO: greatly simplifies using IndexedDB, I was hoping to add a shim/polyfill for Chrome FileSystemAPI
- CON: It should handle blobs, but I was unable to get it to work
idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
- Eric Bidelman @ Google has written a well tested PolyFill the FileSystem API that uses Indexed DB as a fall back
- PRO: FileSystem API is well suited for storing blobs
- PRO: works great on FireFox and Chrome
- PRO: great for synchronizing with cloud based CouchDB
- CON: no clear why, but it is not working on IE10
PouchDB JavaScript Library http://pouchdb.com/
- great for syncing a CouchDB with a local DB (uses either WebSQL or IndexedDB (not my problem though)
- CON: NO CONS, PouchDB now supports binary blobs for all recent browsers (IE, Chrome, Firefox, Chrome on mobile, etc.) as well as many older browsers. That was not the case when I first did this post.
NOTE: to see a data:uri encoding of PNG I created an example at: http://jsbin.com/ivefak/1/edit
Desired/Usefull/Uneeded Features
- No native (EXE, PhoneGap, ObjectiveC, etc) app on client (pure web application)
- Only needs to run on latest Chrome, FireFox, IE10 for laptops
- Strongly want same solution for Android Tablet (IOS would be nice too) but only need one browser to work (FF, Chrome, etc.)
- Fast initial DB population
- REQUIREMENT: Very fast retrieval of images by web application from storage (DB, file)
- Not meant for consumers. We can restrict browsers, and ask user to do special setup & tasks, but let's minimize that
IndexedDB Implementations
- There is an excellent article on how IE,FF,and Chrome internally implement this at: http://www.aaron-powell.com/web/indexeddb-storage
- In short:
- IE uses the same database format as Exchange and Active Directory for IndexedDB
- Firefox is using SQLite so are kind of implementing a NoSQL database in to SQL database
- Chrome (and WebKit) are using a Key/ Value store which has heritage in BigTable
My Current Results
- I chose to use an IndexedDB approach (and polyfill with FileSystemAPI for Chrome until they ship blob support)
- For fetching the tiles, I had a dilemna since the JQUERY folks are kvetching about adding this to AJAX
- I went with XHR2-Lib by Phil Parsons, which is very much like JQUERY .ajax() https://github.com/p-m-p/xhr2-lib
- Performance for 100MB downloads (IE10 4s, Chrome 6s, FireFox 7s).
- I could not get any of the IndexedDB wrappers to work for blobs (lawnchair, PouchDB, jquery-indexeddb, etc.)
- I rolled my own wrapper, and performance is (IE10 2s, Chrome 3s, FireFox 10s)
- With FF, I assume we are seeing the performance issue of using a relational DB (sqllite) for a non-sql storage
- NOTE, Chrome has outstanding debug tools (developer tab, resources) for inspecting the state of the IndexedDB.
FINAL Results posted below as answer
Update
PouchDB now supports binary blobs for all recent browsers (IE, Chrome, Firefox, Chrome on mobile, etc.) as well as many older browsers. That was not the case when I first did this post.
Results Offline blob cache for PNG slippy maps
Testing
- 171 PNG files (total of 3.2MB)
- Platforms tested: Chrome v24, FireFox 18, IE 10
- Should also work with Chrome & FF for Android
Fetch from web server
- using XHR2 (supported on almost all browsers) for blob download from web server
- I went with XHR2-Lib by Phil Parsons, which is very much like JQUERY .ajax()
Storage
- IndexedDB for IE and FireFox
- Chrome: Polyfill (blob stored using FileSystem API, reference kept in IndexedDB) polyfill
- A Must read article on "How the browsers store IndexedDB data"
- Note: FireFox uses SQLlite for the NOSQL IndexedDB. That might be the reason for the slow performance. (blobs stored separately)
- Note: Microsoft IE uses the extensible storage engine:
- Note: Chrome uses LevelDB http://code.google.com/p/leveldb/
Display
- I am using Leaflet http://leafletjs.com/ to show the map tiles
- I used the functional tile layer plugin by Ishmael Smyrnow for fetching the tile layer from the DB
- I compared the DB-based tiles layer with a purely local (localhost://) storage
- There is no noticeable difference in performance! between using IndexedDB and local files!
Results
- Chrome: Fetch (6.551s), Store (8.247s), Total Elapsed Time: (13.714s)
- FireFox: Fetch (0.422s), Store (31.519s), Total Elapsed Time: (32.836s)
- IE 10: Fetch (0.668s), Store: (0.896s), Total Elapsed Time: (3.758s)
这篇关于为离线 Web 应用程序存储图像数据(客户端存储数据库)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!