I am trying to get our web app to cache and display images for offline mode, while the storage part is done (default to IndexedDB and fallback to WebSQL for certain device), I am unsure if:
Canvas or XHR is the better option to get image data.
Blob or ArrayBuffer is the better option to store image data.
Whether there are alternatives to these 2 questions I am not aware of.
There are many discussion on stackoverflow surrounding similar topics (Ref 1, 2). But a lot of them were asked in 2012, when FileSystem API was not deprecated and IndexedDB support were not widespread.
It's now 2014. I want to work towards a definitive/best practice answer for IndexedDB storage, with some considerations for WebSQL. Below are my research (as of 2014.09):
For Q1:
Canvas method has the advantage of no extra request, but
toBlob
method is not supported by most browser, conversion between dataUrl and Blob are likely CPU intensive. In addition we will lose image metadata and need to handle cross origin issues.XHR method avoid canvas's drawbacks but introduce an extra request for every image, unless they are already cached by browser. The main advantage being modern browsers with xhr2 support can return binary response as Blob or ArrayBuffer natively.
For Q2:
Generally speaking, if you are not working on manipulating binary data, then Blob is the better choice, especially for image caching and display, since you need to call
.createObjectURL
with Blob anyway.But Chrome has buggy support for Blob type in IndexedDB (fixed in Chrome 38, which is not released yet), and for WebSQL a common solution is to use base64. Both of which suggest ArrayBuffer might be the more compatible choice.
Notes on other potential solutions:
localStorage isn't a good fit for content image storage given its 5MB cap. Other problem including synchronous api (blocking IO) and no native support for binary content.
appcache would be great for static asset (where resource url are known), but for content image caching they are a headache to manage.
I haven't been able to locate a discussion/article that fully consider compatibility and performance of each choice. Can stackoverflow community help me out?
Update:
For what it's worth, I decide to go with XHR + Blob combination. My main reasoning:
Simplicity: with XHR2 retrieving blob is as easy as setting
xhr.responseType = 'blob'
Native: the entire process is based on native api, from XHR Blob, to storing Blob in IndexedDB, to generating Object URL for image display. It might not necessarily imply better performance, but it certainly reduce needs for data conversion in application code.
Design: image caching is not critical to our service, so I decide to support only browser with proper IndexedDB and XHR2.