Syncronise Data For Webapps In Chrome

  • Post author:
  • Post category:Geral

If you need to implement offline capabilities for a webapp, there are primarily two main pain-points you need to workaround: The first is storage and and the second is data syncronisation (1).

Offline storage is particularly complex, as just looking at the web storage landscape (localStorage, IndexedDB, File System API, WebSQL, etc) you’ll quickly realize that compatibility and performance vary vastly between both browsers and devices.

Syncronisation is an even more challenging as there are currently no cross-browser solutions for syncronizing data cached locally to a remote host without opting for a library. Any solutions also need to take into account device connectivity status so you can correctly re-sync when the user returns online.

Going further with syncFileSystem

I was initially quite excited when I heard about the syncFileSystem API (2) that we landed in Canary. It offers straight-forward data syncronization for apps with Google Drive currently being the only supported backend (this will change later). If a user goes offline, changes continue to be saved locally and are re-synced with Drive when a connection returns.

sync FS is meant as a compliment to the File System API and isn’t supposed to be used for general data sync.

You can however hack this to use a single .json endpoint as your sync-store so that you’re saving to say, myData.json and syncronizing this database back up to Drive. This workflow basically means using a local myData.json file saved using the File System API, rather than say, something like localStorage. Note however that it will just work with sync in Chrome.

chrome.syncFileSystem.requestFileSystem(function(fs) {
fileSystem = fs;
fileSystem.root.getFile(‘myData.json’, {create: true}, function(file) {
myFile = file;

You also need to be careful if opting for syncFileSysetem because of concurrent editing i.e ensure that multiple people aren’t editing your myData.json file at the same time on different nodes. As syncFileSystem handles entries per file, one will overwrite the other and either can write the final version of the file.

You also need to factor in async editing where you don’t have internet access. If you are say, offline on a work machine and edit a file, then edit the same file on mobile which happens to be offline too, what happens when you’re home online? Then back at work online?. There are quite a few opportunities for syncing to just fall apart.

Chrome Sync

If syncFileSystem isn’t an option, you can also use Chrome Sync for your data syncronization needs over Google Drive. This is exposed via (3) and has the benefit of storing objects of any type (not just strings). Similar to syncFileSystem it is also async.{‘skill’: theSkill}, function() {
// Notify that we saved.
message(‘Config data saved’);

Chrome sync works well for those cases where you want to syncronize configuration data for apps, but doesn’t offer a way to persist this data to your own backend and has a hard limit of storing only about 4KB of data per entry (i.e you would handle data on an entry basis, rather than an entire object/db basis). This may change at some time in the future.

Chrome Sync or syncFileSystem?

It is worth noting that your app will exprience similar conflict issues if storing multiple items in a single object regardless of whether you’re using Chrome Sync or syncFileSystem.

The real difference between them is that Chrome Sync handles conflict resolution automatically, whilst syncFileSystem will leave you in a ‘conflicting’ state until some action is taken. Storing items in multiple keys in Chrome Sync can usually handle them better.

Sync for IndexedDB?

We asked the team that worked on syncFileSystem if there were any plans to bring it’s goodness to IDB. Unfortunately the answer is that it’s difficult, mainly because of the complexity involved in handling resolving conflicts and handling transactions.

syncFileSystem is actually very simple, doesn’t have the transaction concept, and conflicts will only happen per-entry. Imagine how much more complex this problem gets if you’re handling entry conflicts on each entry, object or value of the IndexedDB – it’s not an easy problem to solve.

It would also be difficult to augment syncFileSystem to work with IndexedDB as the backend (Drive API) that syncFileSystem was built on really only supports file-based operations rather than partial object updates.

It’s therefore more likely that for partial updates (for at least syncable key-value storage), we’ll see efforts put into improving but this is just a guess.

What about outside of Chrome?

I’ve previously read that Mozilla are working on solutions for sync such as, but there unfortunately doesn’t yet seem to be an elegant way of solving data syncronization cross-browser, at least, not natively.

For now, if you are deploying applications outside of the Chrome Apps ecosystem, my recommendation is to continue using libraries like backbone.offline/dualStorage (4), ember-data-sync (5) (or rolling your own where other frameworks are used) to ensure that the correct fallbacks for storage are used locally as necessary. Having spoken to the team behind Meteor, they’ve also been interested in baking offline sync into their solution, but it won’t be implemented for some time.

Final thoughts

Hopefully one day, syncronization will be a little more straight-forward but it won’t happen without a level of consensus and drive between browser vendors to collaborate on solving this problem.

In the mean time, my hope is that developers can continue to build on the workarounds written so far to get a level of syncronisation into webapps. Fingers crossed you won’t have to do this in the future.

1) There are others such as operational transforms and so on but we’ll leave these for another day.
2) syncfilesystem api | dev and by +François Beaufort (good minimalist example)
4) or
6) In case you’re interested in further samples: cloud-backed text editor using the new chrome.syncFileSystem API by Kinuko and by +Sam Dutton

With thanks to +Kinuko Yasuda and +Eiji Kitamura for their helpful review and input