Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Why Mobile Web Still Sucks
Search
Ilya Pukhalski
June 05, 2014
Technology
3
520
Why Mobile Web Still Sucks
What comes next into our browsers: Service Workers, Push API, Browser Sync, Installable Web Apps.
Ilya Pukhalski
June 05, 2014
Tweet
Share
More Decks by Ilya Pukhalski
See All by Ilya Pukhalski
There's a bot for that
pukhalski
1
300
50 Shades of Flux
pukhalski
3
380
Responsive Typography: Wrap-Up
pukhalski
8
410
Next Level SVG
pukhalski
1
1.7k
XFramework: the story so far
pukhalski
0
480
XFramework: build cross-platform responsive web apps easily
pukhalski
3
950
Mobile Cross-Platform Development
pukhalski
2
310
Rest in PS: рабочий процесс современного веб-дизайнера
pukhalski
12
1.5k
Что сломалось в белорусском интернете?
pukhalski
4
510
Other Decks in Technology
See All in Technology
「Chatwork」の認証基盤の移行とログ活用によるプロダクト改善
kubell_hr
1
240
無意味な開発生産性の議論から抜け出すための予兆検知とお金とAI
i35_267
0
860
本が全く読めなかった過去の自分へ
genshun9
0
710
Delegating the chores of authenticating users to Keycloak
ahus1
0
130
ドメイン特化なCLIPモデルとデータセットの紹介
tattaka
1
440
AWS Summit Japan 2025 Community Stage - App workflow automation by AWS Step Functions
matsuihidetoshi
1
310
MySQL5.6から8.4へ 戦いの記録
kyoshidaxx
1
300
asken AI勉強会(Android)
tadashi_sato
0
140
ネットワーク保護はどう変わるのか?re:Inforce 2025最新アップデート解説
tokushun
0
150
Amazon S3標準/ S3 Tables/S3 Express One Zoneを使ったログ分析
shigeruoda
5
590
ハッカソン by 生成AIハッカソンvol.05
1ftseabass
PRO
0
130
Core Audio tapを使ったリアルタイム音声処理のお話
yuta0306
0
150
Featured
See All Featured
Writing Fast Ruby
sferik
628
62k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
940
Large-scale JavaScript Application Architecture
addyosmani
512
110k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
138
34k
Unsuck your backbone
ammeep
671
58k
Fireside Chat
paigeccino
37
3.5k
GraphQLとの向き合い方2022年版
quramy
49
14k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
Agile that works and the tools we love
rasmusluckow
329
21k
Designing Experiences People Love
moore
142
24k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Transcript
Why Mobile Web Still Sucks? Ilya Pukhalski May MMXIV
@pukhalski ! Solution Architect, EPAM Systems Lecturer, British Higher School
of Art & Design
% of time spent 2013 2014 14 20 86 80
Apps Mobile Web
Why apps? • Easy to control over stores • Rich-get-richer
dynamics • Easier to retain users
None
None
HTML5 vs Native on mobile Web
Watch your language • HTML5 is a marketing buzzword •
Responsive Web Design doesn’t exist Good design is responsive by default.
What is web?
– Wiki “Web is a system of interlinked “hypertext documents
that run “on and are accessed “via the Internet.”
None
Custom URL schemas • fb://profile/(fbid) • tel:+180022933 • twitter://username •
…
applinks.org
Native is a part of Web ecosystem
What is native?
“Native — software or data “formats supported by a certain
“system with minimal overhead “and additional components” – Wiki
Web technologies are native for browsers
Browsers are responsible for standards support
Apps boom Do you remember dot-com boom?
Why do we love apps? • Push Notifications • Offline
Mode • Performance ! ! • Look & Feel • Distribution • Background Sync
Look & Feel
famo.us
None
Touch Events, Pointer Events, Mouse Events
~300ms delay
tap.js
document .getElementById('any-element') .addEventListener('tap', function (e) { // All the magic
happens here }); $('#any-element').on('tap', function (e) { // All the magic happens here });
Performance
Heavy DOM
Facebook React.js Model DOM Virtual DOM Redraw on requestAnimationFrame Changes
Changes Changes
Animations
2010-2013
2014
requestAnimationFrame
None
None
element.animate([ {cssProperty: value0}, {cssProperty: value1}, {cssProperty: value2}, //... ], {
duration: timeInMs, iterations: iterationCount, delay: delayValue });
Offline Mode
Cache Manifest
A declarative way CACHE MANIFEST # 2012-02-21 v1.0.0 /theme.css /logo.png
/main.js ! NETWORK: login.asp ! FALLBACK: /html/ /offline.html
A mess CACHE MANIFEST # v1 index.html js/lib/mapbox.js js/lib/iscroll.min.js js/lib/jquery/dist/jquery.min.js
js/lib/backbone/backbone.min.js js/lib/underscore/underscore.min.js js/xf.min.js js/app.js styles/xf.min.css styles/app.css styles/mapbox.css js/components/PointsList.js tmpl/desktop/PointsList.tmpl tmpl/mobile/PointsList.tmpl js/components/PointsMap.js https://api.tiles.mapbox.com/mapbox.js/v1.6.1/images/icons-000000.png http://api.tiles.mapbox.com/mapbox.js/v1.6.1/images/icons-000001.png http://api.tiles.mapbox.com/mapbox.js/v1.6.1/images/icons-000002.png http://api.tiles.mapbox.com/mapbox.js/v1.6.1/images/icons-000003.png http://api.tiles.mapbox.com/mapbox.js/v1.6.1/images/icons-000004.png http://api.tiles.mapbox.com/mapbox.js/v1.6.1/images/icons-000005.png http://a.tiles.mapbox.com/v3/witchfinderx.hb934388.json http://a.tiles.mapbox.com/v3/marker/pin-s-fuel+fc4353.png http://a.tiles.mapbox.com/v3/marker/pin-m-circle+f0a.png NETWORK: http://api.tomtom.com/ http://a.tiles.mapbox.com/ http://b.tiles.mapbox.com/ http://c.tiles.mapbox.com/
Debugging hell 1. Change the code 2. Change manifest 3.
Clean cache 4. Debug 5. GOTO 1
None
Meet Service Worker
Event-driven scripts that run independently of web pages
• Handling resource requests • Foundation for other standards
navigator.serviceWorker.register('/worker.js') .then(function(serviceWorker) { // To use the serviceWorker immediately, //
you might call window.location.reload() });
var base = "https://videos.example.com"; var inventory = new URL("/inventory.json", base)
+ ""; ! ! this.addEventListener("fetch", function(e) { var url = e.request.url; if (url == inventory) { e.respondWith(new Response({ statusCode: 200, body: JSON.stringify({ videos: { /* ... */ } }) })); } });
var base = "https://videos.example.com"; ! this.addEventListener("install", function(e) { ! var
cachedResources = new Cache( base + "/base.css", base + "/app.js", base + "/logo.png" ); ! ! e.waitUntil(cachedResources.ready()); ! ! caches.set("videos-cache", cachedResources); });
this.addEventListener("fetch", function(e) { ! e.respondWith( caches.match(e.request, “videos-cache") ); });
var base = "https://videos.example.com"; var inventory = new URL("/inventory.json", base)+"";
! this.addEventListener("fetch", function(e) { var url = e.request.url; if (url == inventory) { e.respondWith( fetch(url).then( null, function() { return caches.match(inventory); } ) ); } });
Distribution
Stores • App Store • Google Play • BlackBerry AppWorld
• Amazon Appstore • EPAM Mobile Appstore
Stores • App Store • Google Play • BlackBerry AppWorld
• Amazon Appstore • EPAM Mobile Appstore
Will you install an app to buy a car?
None
None
None
Install this app
navigator .mozApps .install("path/to/manifest");
Notifications
Web Notifications
var Notification = window.Notification || window.mozNotification || window.webkitNotification; ! Notification.requestPermission(
function (permission) { // console.log(permission); } );
! var notification = new Notification( "SEC Spring 2014", {
body: "I hope you enjoy the conference" } ); ! notification.onclick = function () { // Something to do };
• Opened website • Client-side only
Safari Remote Notifications
The Flow • Request permissions • Register the device •
Send notifications
{! ! "aps": {! ! "alert": {! ! "title": "Flight
A998 Now Boarding",! ! "body": "Boarding has begun for Flight A998.",! ! "action": "View"! ! },! ! "url-args": ["boarding", "A998"]! ! }! ! }!
• Server-side • Offline
Service Worker Push Notifications
The Flow • Register locally • Register on the server
side • Send notifications
navigator.serviceWorker.register("/sw.js"); ! navigator.serviceWorker.whenReady().then(function(sw) { ! navigator.push.has("regId").catch(function() { navigator.push.register({ sender: {
// sender data... } }); }).then(function (registration) { asyncXHR( "http://example.com/push/activate" + toQueryString(registration); ); }); });
this.onpush = function(e) { console.log(e.message.data); // Cache the data //
... }
Background Sync
Service Worker? Yes!
navigator.serviceWorker.register("/sw.js"); ! ! navigator.serviceWorker.whenReady() .then(function(sw) { ! navigator.registerSync( "id", {
interval: 'daily', data: '', description: '', lang: '', dir: '' } ); });
this.onsync = function(event) { var data = JSON.parse(event.data); ! if
(event.id === "id") { // make something with data } };
How to make mobile web suck less?
Blame the implementation, not technique
Thanks @pukhalski
[email protected]