Turbolinks: Turbolinks and progressive web applications

Created on 13 Oct 2016  路  23Comments  路  Source: turbolinks/turbolinks

Turbolinks 5 was designed with mobile in mind. It's meant to be dropped into native mobile apps with native navigation shells (like Basecamp).

It seems to me that a progressive web application could use Turbolinks in a _very_ similar way to how a native mobile app uses it.

This sort of dovetails with #152 (which is really about "can we make the network layer pluggable?"). I haven't actually tried to build a progressive webapp with TL5, so I'm not sure what (if any) changes to TL would be required. But I'm opening this issue to see if anyone has tried this or is interested in it.

enhancement

Most helpful comment

All 23 comments

The main issue I've had with building PWAs with Turbolinks is that iOS Safari completely kills the page state every time you switch to another App, when you're in using full-screen mode. This is particularly bad if you want to jump into another app to copy something and jump back. Saving the page state to localstorage would help a lot. See #185

For basic read-only offline support, Turbolinks' cache could be adapted to use a more permanent storage mechanism like lscache.

I don't think you could ever use Turbolinks to make an app work entirely offline, though. Reading from a cache is one thing but creating new records, adding them to all the different views, queueing changes for background syncing, etc. would require so much additional work. You'd essentially have to build the entire app - Models, Views, Controllers and all - in JavaScript. At which point, you might as well just build and API and use something like Ember for your PWA.

For my use case, being able to create and edit records offline isn't really necessary, but I am really interested in pushing the hybrid approach even further with improved caching, etc. Interestingly, this model fits Google鈥檚 definition of a PWA.

Disclaimer: I didn't try the lib yet, rediscovering it via.

Maybe serviceworkers might help by caching/pre-fetching/retrieving from cache links close to the cursor of the mouse or within the displayed window on small screens. Not really PWA but closer to your description and the discussion that initiated this issue. I'm currently using http://instantclick.io/ but I'm willing to change to have more options on the loading/caching part so any improvement on that part interests me.

@nateberkopec I'm going to experiment with increasing the cache limits and switching to lscache, as I could do with this hybrid functionality myself. Let me know if you're interested!

@joeldrapper I am!

Hi @joeldrapper and @nateberkopec , any updates of your Turbolinks with lscache journey to build hybrid functionality ?

Aren't ServiceWorkers not supported in iOS? If this is true, wouldn't a PWA on iOS with offline support not be possible (regardless of Turbolinks 5) until ServiceWorkers are supported?

Does anyone have experience with using something like Firebase to implement offline support with their hybrid app?

Hey @kirantpatil I've been working on it, but not had much time. I'll comment here when I have a better understanding, and I might open a PR.

Hi @MrHubble, yes for now the iOS doesn't support ServiceWorks, instead of it, you can use (with more effort) Appcache to deliver an offline experience.

I've been making some presentations about Turbolinks in some Brazilian meetups. And to share some examples I created a PWA, which uses Turbolinks, works offline, receives web pushes (via FCM) and can be installed.

But it doens't use Appcache for now, I've been planning to implement this until the next month, and fix a few issues too! 馃槄

This the link to the project: https://github.com/YSimplicity/try-turbolinks.

Thanks for sharing @serradura

I created a PWA, which uses Turbolinks, works offline, receives web pushes (via FCM) and can be installed.

Does this all work within the Turbolinks native Android adapter?

@MrHubble I didn't try it yet. But, following the MDN documentation, I believe that won't be possible. Because the Android Webview hasn't support for Service Workers.

Please check the Browser compatibility section in this link: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker

The Appcache API has support in all Webview platforms, but I believe that you'll have some headache to make everything works.

https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

P.S. Follows another reference to check this kind of info.
http://caniuse.com/#feat=serviceworkers

@serradura thanks, I thought Service Workers were supported by Android Webview so that info and link helped to clear things up for me.

But it doens't use Appcache for now, I've been planning to implement this until the next month

Do you have any experience and thoughts on rails_appcache?

Has any body tried https://github.com/rossta/serviceworker-rails with turbolinks for PWA ?

Saving the page state to localstorage would help a lot. See #185

Might there be privacy issues with using localstorage as a content cache? e.g. a user's browsing history is persisted in localstorage even if they log out and delete their history

Hi all,

I want build a offline supported app using Rails 5.1 ?

Usecase: App should work offline seamless and when network is available, it has to sync data with Server.

I am bit confused here.

Please suggest, how should I progress and what technologies do I need to use ?

Thanks.

It seems like turbolinks can benefit quite a bit by just using browser local storage for it's cache, examples are:
1) Opening a link in a new tab won't start that tab with a blank cache and cause all pages to load instead of showing cache preview for some.
2) When using multiple tabs they will use the same cache meaning more pages will load instantly and provide the latest cached version across all tabs.
3) Closing and opening your browser will not reset it's cache. Sure cached pages are older but in many cases it doesn't matter. If you take this github issue page as an example: loading it from cache will be better even if there is a new post to it, because by the time the user scrolls down the page content has been replaced with the latest.

Once local storage is in place it seems like a big step towards progressive web apps. In offline mode you could display a banner indicating you are offline and that everything is read only while a service worker continues serving pages from local storage. This is great for connections that drop for a few seconds and then recovers which is quite common. Once the user requests a page that isn't in the cache the service worker just renders an offline page with automatic reload once the connection is back.

It also seems like progressive web apps have a bright future. Many developers will prefer it over native hybrid apps like turbolinks Android or iOS.

I really like this idea, but we should use sessionStorage instead of localStorage. We also need to make sure the cache is effectively cleared when someone manually logs out of an authenticated app. This could be done by encrypting the cache with the session key.

I've created a very rough but working proof of concept if someone wants to try it out:
https://gist.github.com/pierre-pretorius/25c6c67cf8745bedcc241f818189e3ed

Nice PoC by @pierre-pretorius, however, I don't see any cache invalidation mechanism.

In serviceworker.js you basically have three hooks:

  • activate
  • install
  • fetch

The browser will automatically check if there is a new serviceworker.js upstream. In this case, it will call "activate" again, from the new version: that's when it's supposed to invalidate old versions in cache.

You can get started with the official example from MDN and hack your own implementation inside:

https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker

Haven't tried yet, but this gem appears to provide a solution for this issue.

Haven't tried yet, but this gem appears to provide a solution for this issue.

That gem makes your webapp a PWA, but it's a different approach to what we want to achive here. The idea here is to extend turbolinks so that it uses the browser native PWA functionality to get more advanced features such as (limited) offline browsing of pages you opened previously, cross tab caching, etc.

@pierre-pretorius In your opinion, is it possible to replace http server that generates markup with a webworker for a simple application? This idea was bugging me for sometime - if a worker could generate markup Turbolinks would become a universal router.

I've been using WebWorkers with Turbolinks for couple month now. I cache pages and assets with CacheAPI when I need to provide SPA experience. There are some caveats, for example, caching works bad for IFrames and any elements with src attribute. Say, If I don't have to cache an image I replace it with some placeholder so it wouldn't request the same image twice.. Also, it is still hard to debug an application with webworkers.
Caching Example

I've created a very rough but working proof of concept if someone wants to try it out:
https://gist.github.com/pierre-pretorius/25c6c67cf8745bedcc241f818189e3ed

@pierre-pretorius your work is amazing!

  1. Do you think you will make a PR shortly? (today is in typescript but logic is the same: https://github.com/turbolinks/turbolinks/blob/master/src/snapshot_cache.ts).

  2. What do you think about using ServiceWorker with CacheAPI and default Turbolinks instead?


Nice PoC by @pierre-pretorius, however, I don't see any cache invalidation mechanism.

@jpic, what do you mean?


@nesterow, are you still using default Turbolinks with CacheAPI and ServiceWorkers? Can you link a real example?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tadiou picture tadiou  路  42Comments

kochka picture kochka  路  14Comments

nerdcave picture nerdcave  路  16Comments

sblackstone picture sblackstone  路  38Comments

jakehockey10 picture jakehockey10  路  31Comments