1
Some statistics
2
Auto #2: Lada
http://www.belstat.gov.by
3
Summary
http://www.belstat.gov.by
LadaOther
4
Summary
http://www.belstat.gov.by
New Cars
Old Cars
5
Upgrades
6
Some more statistics
7
Trends
http://www.belstat.gov.by
8
Trends
https://trends.google.com/trends/explore?date=2013-02-09%202017-03-
09&q=%2Fm%2F0268gyp,%2Fm%2F0j45p7w,%2Fm%2F012l1vxv,BackboneJS,ExtJ
Uruguay
9
Garther Hype Cycle
10
Hype Cycle
Peak of Inflated Expectations
Trough of Disillusionment
Plateau of Productivity
Innovation Trigger
11
Customer & Offline Second
12
Insurance Domain
13
Customer's Clients
14
Belarus
15
USA
16
Reality
17
Reality
18
Offline
19
Avoid application crashes or errors
Allow users to keep working, seamlessly
Avoid multiple changes
Time Limit
Conserns
20
Step 0: rules
21
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
22
Step 1: detect offline
23
function updateOnlineStatus(event) {
let condition = navigator.onLine ? 'online' : 'offline';
console.log('Do smth.');
}
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
Detect Status
24
Baidu Map
25
Gracefully Degrate
26
Step 2: Requests
27
$http
new XMLHttpRequest()
$.ajax ($.get, $.post, ...)
fetch
new ActiveXObject
...
Requests
28
Request Facade
REST
$.ajax
XHR
fetch
Offline...
Facade
29
Step 3: Detect Slow...
30
Online or Offline?
31
Slow or intermittent internet
Slow or intermittent WiFi
Avoid HTTP Timeouts
Detect slow connection
32
Request Facade + Circuit Breaker
REST
Request
Offline...
Facade
Opened
33
Closed
Success
Open
Fast Failer
Open
34
Half-Open
Success: Open
Try one request
Fail: Close
Circuit Breaker Pattern
https://github.com/HubSpot/offline
Offline.js
35
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)
}
}
36
https://github.com/HubSpot/offline
Offline.js
{
// Should we store and attempt to remake requests
// which fail while the connection is down.
requests: true,
}
37
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'}}};
38
Online OnlineOffline
Restart
Browser
Intermittent Offline
39
Step 4: Reload Page
40
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-
41
Service Workers in 2 slides
42
Installation
https://developers.google.com/web/fundamentals/instant-and-
offline/offline-cookbook/43
Cache Storage
Promisified
Store Request/Response key/value data
Persistent between browser restarts
44
Work with Service Workers
45
HTTPS
46
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>
47
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">
48
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
49
[
"./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
50
https://github.com/GoogleChrome/sw-precache
https://github.com/GoogleChrome/sw-toolbox
Service Worker Libraries:
sw-precashe
sw-toolbox
51
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
Matches requests using the GET, POST, PUT, DELETE or
Matches requests using the GET, POST, PUT, DELETE or
HEAD HTTP methods respectively.
HEAD HTTP methods respectively.
HEAD HTTP methods respectively.
52
https://jakearchibald.com/2014/offline-cookbook/
Network Strategies === handlers
53
https://jakearchibald.com/2014/offline-cookbook/
Network Strategy: Cache Only
54
https://jakearchibald.com/2014/offline-cookbook/
Network Strategy: Cache Only
importScripts('/sw-toolbox.js');
self.toolbox.options.cache.name = 'test-cache-name';
self.toolbox.router.get('/get-cache-value', self.toolbox.cacheOnly);
55
Network Strategy: Cache & Network race
https://jakearchibald.com/2014/offline-cookbook/
56
Network Strategy: Network first
https://jakearchibald.com/2014/offline-cookbook/
57
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
58
https://github.com/NekR/offline-plugin
+ AppCache
+ Manifest
SW Libraries: Webpack Offline Plugin
59
Step 5: Storages
60
Storage Size
30-40 Mb~
61
Limited to 5 MBs
Store only Strings
Persistent between browser restarts
Local Storage
62
Web SQL
63
More complex than localStorage
50 MB + (calculate on quota)
Stores Objects, Strings and other
Async
IndexedDB
64
https://nolanlawson.com/2015/09/29/indexeddb-websql-
localstorage-what-blocks-the-dom/
Speed Tests: insert 1k objects
65
https://nolanlawson.com/2015/09/29/indexeddb-websql-
localstorage-what-blocks-the-dom/
Speed Tests: insert 1m objects
66
https://nolanlawson.github.io/html5workertest/
Storages Support in Service Workers
67
Pull Stategy
68
RestAPI
Data
UI-Page
Data
Size/Diff
IndDB
Cache
Load
69
Data
40 Mb/...
Pull Strategy
Step 6: Isomorphism
70
Client App
Server App
Request Facade
Servises
Rest API
IndDB
Mongo
71
Isomorphism
Router
Adapter
Driver
Mongo API Everywhere
IndDB
Mongo
Router
Adapter
Driver
72
Servises
IndDB
Mongo
Step 7: Adapters
73
6106
https://github.com/louischatriot/nedb
74
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
75
3164
http://lokijs.org/#/
76
Fast Performance!
Indexing / Secondary Indexing / Unique Indexing
Persistence IndexedDB Adapter
Partial compatibility with MongoDB API
77
563
https://github.com/mWater/minimongo
78
Happy end
but ...?
79
Push Strategy?
80
Push Strategy
RestAPI
Data
UI-Page
ClientDB
Delete
Update
81
Data
Data
https://pouchdb.com/
82
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
83
https://www.meteor.com/
84
https://www.rethinkdb.com/
85
Horizon is a realtime, open-source
backend for JavaScript apps
https://horizon.io/
86
What else?
https://loopback.io/
https://github.com/gritzko/swarm87
Thank you!
Questions?
88

Aleksey Bogachuk - "Offline Second"