Some statistics
Legendary Car
Minsk
Some more statistics
Legendary Library
Trends
https://trends.google.com/trends/explore?date=2013-02-09%202017-03-09&q=%2Fm%2F0268gyp,%2Fm%2F0j45p7w,%2Fm%2F012l1vxv,BackboneJS,ExtJS
Trends
https://trends.google.com/trends/explore?date=2013-02-09%202017-03-09&q=%2Fm%2F0268gyp,%2Fm%2F0j45p7w,%2Fm%2F012l1vxv,BackboneJS,ExtJS
Uruguay
EPAM CC
Customer & Offline Second
Insurance Domain
Customer's Clients
Belarus
USA
Reality
Offline
-
Avoid application crashes or errors
-
Allow users to keep working, seamlessly
-
Avoid multiple changes
-
Time Limit
Concerns
Step 0: rules
-
Focus on your goals
-
Do not refresh libraries
-
Do not touch lint or style guides
-
Do not touch working code
-
Do not refactor anything
Rules
Step 1: detect offline
function updateOnlineStatus(event) {
let condition = navigator.onLine ? 'online' : 'offline';
console.log(`Do smth. You are ${condition}`);
}
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
Detect Status
https://jsfiddle.net/cz9u13tr/
Baidu Map
Gracefully Degrate
Gracefully Degrate
Step 2: Requests
-
$http
-
new XMLHttpRequest()
-
$.ajax ($.get, $.post, ...)
-
fetch
-
new ActiveXObject
-
...
Requests
Request Facade
REST
$.ajax
XHR
fetch
Offline...
Facade
Step 3: Detect Slow...
Online or Offline?
-
Slow or intermittent internet
-
Slow or intermittent WiFi
-
Avoid HTTP Timeouts
Detect slow connection
Request Facade + Circuit Breaker
REST
Request
Offline...
Facade
Closed
Opened
Closed
Success
Open
Fast Failer
Open
Half-Open
Success: Open
Try one request
Fail: Close
Circuit Breaker Pattern
https://github.com/HubSpot/offline
Offline.js
https://github.com/HubSpot/offline
Offline.js
{
reconnect: {
// How many seconds should we wait before rechecking.
initialDelay: 3,
// How long should we wait between retries.
delay: (1.5 * last delay, capped at 1 hour)
}
}
https://github.com/HubSpot/offline
Offline.js
{
// Should we store and attempt to remake requests
// which fail while the connection is down.
requests: true,
}
https://github.com/HubSpot/offline
Offline.js
// By default, Offline makes an XHR request
// to load your /favicon.ico
// You can change the URL it hits
// (respond with a quick 204 is perfect):
Offline.options = {checks: {xhr: {url: '/connection-test'}}};
Intermediate Result
-
Offline Status
-
Request
-
Slow or Intermittent Connection
Online
Online
Offline
Restart
Browser
Intermittent Offline
Step 4: Reload Page
Prevent Reload
window.onbeforeunload = function(e) {
let dialogText = `You are offline! Don't do it!`;
e.returnValue = dialogText;
return dialogText;
};
https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload
Service Workers
Installation
https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/
Cache Response
https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/
Cache Storage
-
Promisified
-
Store Request/Response key/value data
-
Persistent between browser restarts
Work with Service Workers
HTTPS
HTTPS
HTTPS
<script src="http://example.com/jquery.js"></script>
<link rel="stylesheet" href="http://assets.example.com/style.css"/>
<img src="http://img.example.com/logo.png"/>;
<p>Read this nice <a href="http://example.com/2014/12/24/">
new post on cats!</a></p>
HTTPS: fix mixed content
<meta http-equiv="Content-Security-Policy"
content="upgrade-insecure-requests">
<meta http-equiv="Content-Security-Policy"
content="block-all-mixed-content">
Activation
https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open('my-cashe-v1').then(function(cache) {
return cache.addAll([
'/css/whatever-v3.css',
'/css/imgs/sprites-v6.png',
'/css/fonts/whatever-v8.woff',
'/js/all-min-v4.js'
// etc
]);
})
);
});
Installation
[
"./48065a15ae3a16e845a528a3c0467487.svg",
"./6beb3319398d06b0635871740330ac7b.svg",
"./8450ddeb645c18bff7890bccc95881a7.svg",
"./ba17b770588f23af1184e66179dc222d.svg",
"./2e030a00362fe30a27bc0750b0626797.svg",
"./3585e1891683a708eabb7ed43446cf82.svg",
"./main.e5d23aa4f5b56b06e5ec.bundle.js",
"./1.e5d23aa4f5b56b06e5ec.chunk.js",
"./main.e5d23aa4f5b56b06e5ec.css",
"./1.e5d23aa4f5b56b06e5ec.chunk.js.gz",
"./1.e5d23aa4f5b56b06e5ec.bundle.map.gz",
"./main.e5d23aa4f5b56b06e5ec.css.gz",
"./main.e5d23aa4f5b56b06e5ec.bundle.js.gz"
]
Assets Installation
https://github.com/GoogleChrome/sw-precache
https://github.com/GoogleChrome/sw-toolbox
Service Worker Libraries:
-
sw-precashe
-
sw-toolbox
https://github.com/GoogleChrome/sw-toolbox
Service Worker Library: sw-toolbox
toolbox.router.get(/urlPattern/, handler, options);
Matches requests using the GET, POST, PUT, DELETE or HEAD HTTP methods respectively.
https://jakearchibald.com/2014/offline-cookbook/
Network Strategies === handlers
https://jakearchibald.com/2014/offline-cookbook/
Network Strategy: Cache Only
https://jakearchibald.com/2014/offline-cookbook/
Network Strategy: Cache Only
class CustomHandler extends workbox.runtimeCaching.Handler {
handle({ event }) {
console.log('CustomHandler is handling', event);
}
}
Network Strategy: Cache & Network race
https://jakearchibald.com/2014/offline-cookbook/
Network Strategy: Network first
https://jakearchibald.com/2014/offline-cookbook/
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open('mycashe-v1').then(function(cache) {
cache.addAll(
// large and unimportant resources
);
return cache.addAll(
// important resources
);
})
);
});
Custom Logic
https://github.com/NekR/offline-plugin
+ AppCache
+ Manifest
SW Libraries: Webpack Offline Plugin
Intermediate Result
-
Offline Status
-
Request
-
Slow or Intermittent Connection
-
Cache Resources
Step 5: Storages
Storage Size
30-40 Mb
~
-
Limited to 5 MBs
-
Store only Strings
-
Persistent between browser restarts
Local Storage
Web SQL
-
More complex than localStorage
-
50 MB + (calculate on quota)
-
Stores Objects, Strings and other
-
Async
IndexedDB
https://nolanlawson.com/2015/09/29/indexeddb-websql-localstorage-what-blocks-the-dom/
Speed Tests: insert 1k objects
https://nolanlawson.com/2015/09/29/indexeddb-websql-localstorage-what-blocks-the-dom/
Speed Tests: insert 1m objects
https://nolanlawson.github.io/html5workertest/
Storages Support in Service Workers
Pull Stategy
Rest API
Data
IndDB
UI-Page
Data
Size/Diff
Cache
Load
Data
40 Mb/...
Pull Strategy
Intermediate Result
-
Offline Status
-
Request
-
Slow or Intermittent Connection
-
Cache Resources
-
Persistence data
Business Logic?
Step 6: Isomorphism
Client App
Server App
Request Facade
Servises
Rest API
IndDB
Mongo
Isomorphism
Router
Adapter
Driver
Mongo API Everywhere
IndDB
Mongo
Router
Adapter
Driver
Servises
IndDB
Mongo
Mongo API Everywhere
Mongo
Adapter API
Driver API
Step 7: Adapters
6393
https://github.com/louischatriot/nedb
-
Basic Querying
-
Operators ($lt, $lte, $gt, $gte, $in, $nin, $ne, $exists, $regex)
-
Logical operators $or, $and, $not, $where
-
Sorting and paginating
-
Projections
-
Indexing
-
File Persistance
3290
http://lokijs.org/#/
-
Fast Performance!
-
Indexing / Secondary Indexing / Unique Indexing
-
Persistence IndexedDB Adapter
-
Partial compatibility with MongoDB API
578
https://github.com/mWater/minimongo
Push Strategy?
Push Strategy
Rest API
ClientDB
UI-Page
Data
Update
Delete
Data
Data
https://pouchdb.com/
-
Omniusable on browsers, nodejs, election, cordova, react-native and every other javascript-runtime
-
Replication between client and server-data, compatible with PouchDB, CouchDB and IBM Cloudant
-
Mango-Query exactly like you know from mongoDB and mongoose
https://github.com/pubkey/rxdb
https://www.meteor.com/
https://www.rethinkdb.com/
Horizon is a realtime, open-source backend for JavaScript apps
https://horizon.io/
What else?
https://loopback.io/
https://github.com/gritzko/swarm
And what is the result?
Final Result
-
Offline Status
-
Request
-
Slow or Intermittent Connection
-
Cache Resources
-
Persistence data
-
Business Logic
-
Partial Sync
Result for Insurance Company
-
Offline Support
-
1 month of development
-
Up to 5% profit
Thank you!
Questions?
Offline Second
By Aliaksei Bahachuk
Offline Second
Nowadays, there are many tips how start your project following the "Offline First" principle. But how add a support offline mode for applications that have already been released? What tactics and architectural approaches are used? What technologies and libraries are looking for? What storages are needed for implementation of pull/push strategies?
- 1,308