In his presentation at Breaking Development in Orlando FL Andrew Betts shared lessons learned making the Financial Times website work offline. Here's my notes from his talk on Offline rules: Bleeding edge web standards at the Financial Times.
- Newsprint could be carried everywhere and read offline. The Web added new capabilities but removed these. Native apps brought back portability and off-line access but lost some of the other benefits of the Web. We need to care about supporting existing features as much as getting new ones.
- HTML5 is not a mobile thing, it is not an alternative to native apps. It's just a way of making better Websites.
- The goal is to loose constraints: enable people to access information anywhere and everywhere they are.
Working Offline
- Offline mode makes everything harder. So decide if you really need it for your site.
- There are multiple forms of storing things on the client: cookies, localStorage, IndexedDB, AppCache, Files API.
- In the EU every Website has to include a message about the fact they use cookies. This creates barriers for storing data in offline applications but we can get over them.
- Each of these local storage solutions works independent of each other. You can see this when Firefox shows two different styled dialogs if you use both appCache and indedexDB. They have the same text in them so you can't tell which one applies to what.
- Read/write access to localStorage is 2x faster. So you might use it over IndexedDB just for this reason.
- A lot of the mark-up between web pages is the same. Its just the content that changes.
- The Bootstrap system from Financial Times keeps content cleanly separated from Web pages. They serve a baseline set of content, then only load modules and enhancements that make sense for the browser the content runs in.
AppCache
- Taming the appCache: in principle it is really simple. You set a version, what resources you want to store offline, which ones you want as fallback, and which ones should come from the network.
- Any page with the manifest attribute will get cached, like it or not. So you can't put the manifest in the header of all your pages. To solve this issue, just cache one 'master' URL using an iframe.
- Internet Explorer and Firefox manage AppCache differently. You'll need to account for these differences.
- When the manifest is updated, every entry in it is re-downloaded. With far future cache headers, we can keep some assets around in the browser cache which will refill the AppCache.
- On very slow networks a request might timeout before the fallback is used. You can't control this timeout -it is up to the browser. Usually this takes too long for users.
- Ideas to fix AppCache: separate the cache and the offline router; more granular way to specify what needs to be re-downloaded; a better Javascript API to look inside AppCache; a way to know how much space is available in AppCache.
- Mozilla is proposing to change the AppCache format to JSON and allow for extra information like network controllers. Google is working on a new API that create a navigation controller in Javascript. This controller could have different cache groups that can be loaded by priority. From there you can define your own caching policies instead of relying on the browser only.
- Perhaps both of these proposals should be implemented. Mozilla is the simpler declarative solution. NavigationController is a more powerful programatic solution.
- To make AppCache useful constrain it to the minimum amount possible: fonts, app icon, entry page, fallback pages. Do not put in CSS, HTML, and Javascript. These need more frequent updates and are in LocalStorage instead.
- Storage limits for local solutions vary wildly between browsers. Nothing in the standards tells browsers how much storage to provide.
- Javascript uses UTF-16 to encode text which means each character takes up two bytes. This uses up precious local storage space. Using a hack allows you to convert ASCII to UTF-16, which doubles your storage space.
- Connection state allows you to know if someone is connected but it can be challenging to manage.
- If window.navigator.online is false, people are not connected. If it is true, it means they might not be online.
- The only way to answer: are you online or not is by determining "can you get this file from our server"?
- Provide people an option to try loading an asset again if it does not. This gives people control over connections since they often know better what their connection status is like.