Drupal in an offline world
Kristof de Jaeger
Mathieu Spillebeen
swentel
mathieuspil
-
Apps
-
Websites
-
AMP
-
FB's Instant articles
-
Android Instant Apps
-
Appcache
-
PWA
Online capabilities
Offline capabilities
Push notifications
Background sync
Push notifications
Background sync
How?
- Stripping down
- Limiting stuff
- No valid HTML
Why?
-
Faster
-
Ads!
For who?
- News agencies
- edge-cases
And how about ?
-
drupal.org/project/amp
- Drupal 7 & 8
- Developed by Lullabot.
How?
- Stripping down
- Limiting stuff
- No valid HTML
- Only inside the fb app
Why?
-
Faster
-
Ads!
For who?
- News agencies
- edge-cases
And how about ?
-
drupal.org/project/fb_instant_articles
-
D7 & D8
Badass RSS!
How?
- Modular apps
- Android-only
- Deeplinking
Why?
-
No installing
-
Faster
-
No hassle
For who?
Companies with existing apps
And how about ?
Nah
It's old!
Very very old!
(already six years now)
And it's already deprecated ...
-
True offline experience
-
!= browser cache
-
Supported in all major browsers
So how does it work ?
-
You need a manifest file which is just a simple text file with the appcache extension
-
add manifest attribute in the HTML tag
<html manifest="/manifest.appcache">
-
Any page with the attribute is automatically in the appcache
(but not the assets on that page!) -
Better to define all resources (pages, assets) explicitely in the manifest file (for updating)
Manifest anatomy
CACHE MANIFEST
CACHE
/offline/venue
FALLBACK:
/ /offline/appcache-fallback
NETWORK:
*
Updating the cache
- manifest file needs to be changed
- even if there are no new resources
- or if only one page/asset was updated
CACHE MANIFEST
# random string in comment to trigger updates (e.g. time)
API
- window.applicationCache object
var appCache = window.applicationCache;
switch (appCache.status) {
case appCache.UNCACHED: // UNCACHED == 0
return 'UNCACHED';
break;
// Check if a new cache is available on page load.
window.addEventListener('load', function (e) {
window.applicationCache.addEventListener('updateready', function (e) {
if (window.applicationCache.status === window.applicationCache.UPDATEREADY) {
alert('The content has been updated');
}
}),
}, false);
Gotchas
- Check your cache headers of manifest (!) and resources
- must-revalidate - never far future
- pages in cache are served from cache when online
- assets not in cache will not be served when online
(NETWORK: *)
- assets not in cache will not be served when online
- download of manifest fails on a single resource error
http://alistapart.com/article/application-cache-is-a-douchebag
For who?
-
Simple sites (e.g. conference)
-
Applications (e.g. google docs, outlook ..)
-
Developers
-
Issues
-
Security (runs on HTTP too)
-
And how about ?
-
drupal.org/project/offline_app
Drupal 8 only - used for Frontend United 2016
Features
- Configure resources to be in the manifest
- Dedicated 'offline/{path}' route
-
- render nodes / views in different 'context' with different formatters
- dedicated block regions and page/html template
- menu
- Scan for images in nodes
- manifest validator
Even more features
- Add homescreen manifest
- Define the launcher icon
- Strategy
- add manifest on the 'offline' pages
- use a block that renders an iframe which calls a page that contains the manifest aka 'hidden download'
Demo!
What could go wrong , we don't even need WiFi! :)
http://frontendunited.org/offline/homepage
Frontend
United
(PWA)
How?
- HTTPS!
- Progressively
How?
- Web app Manifest
{
"lang": "en",
"dir": "ltr",
"name": "Super Racer 2000",
"description": "The ultimate futuristic racing game from the future!",
"short_name": "Racer2K",
"icons": [{
"src": "icon/lowres.webp",
"sizes": "64x64",
"type": "image/webp"
},{
"src": "icon/lowres.png",
"sizes": "64x64"
}, {
"src": "icon/hd_hi",
"sizes": "128x128"
}],
"scope": "/racer/",
"start_url": "/racer/start.html",
"display": "fullscreen",
"orientation": "landscape",
"theme_color": "aliceblue",
"background_color": "red"
}
How?
Normal behaviour
Service workers?
SW: Define the files
var CACHE_NAME = 'dependencies-cache';
// Files required to make this app work offline
var REQUIRED_FILES = [
'random-1.png',
'random-2.png',
'random-3.png',
'random-4.png',
'random-5.png',
'random-6.png',
'style.css',
'index.html',
'/', // Separate URL than index.html!
'index.js',
'app.js'
];
SW - Install
self.addEventListener('install', function(event) {
// Perform install step: loading each required file into cache
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
// Add all offline dependencies to the cache
return cache.addAll(REQUIRED_FILES);
})
.then(function() {
// At this point everything has been cached
return self.skipWaiting();
})
);
});
SW - Fetch
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return the response from the cached version
if (response) {
return response;
}
// Not in cache - return the result from the live server
// `fetch` is essentially a "fallback"
return fetch(event.request);
}
)
);
});
SW - Activate
self.addEventListener('activate', function(event) {
// Calling claim() to force a "controllerchange" event on
// navigator.serviceWorker
event.waitUntil(self.clients.claim());
});
Why?
-
Speed!
-
Huge caching control
-
Control the network layer
Why?
-
Road to background sync
-
Road to push notifications
-
Replace apps
Why?
-
Offline-first
-
Flaky internet connection
-
See internet as enhancement
For who?
-
Basically every project you have
And how about ?
-
drupal.org/project/pwa
Drupal 7 & 8 - Developed by _nod.
Some extra links
-
davidwalsh.name/offline-recipes-service-workers
-
https://events.withgoogle.com/progressive-web-app-dev-summit/
-
youtube.com/watch?v=cmGr0RszHc8
Some nice extra's
Splash screens!
No address bar
Add to splash screen
Appcache & serviceworkers - Frontend United.
By Mathieu Spillebeen
Appcache & serviceworkers - Frontend United.
Appcache and serviceworkers explained through the use case of Frontend United.
- 3,667