Pro Yearly is on sale from $80 to $50! »

Why Mobile Web Still Sucks

Why Mobile Web Still Sucks

What comes next into our browsers: Service Workers, Push API, Browser Sync, Installable Web Apps.

E13498af38db5a5ab97f89fdc500b5af?s=128

Ilya Pukhalski

June 05, 2014
Tweet

Transcript

  1. Why Mobile Web Still Sucks? Ilya Pukhalski May MMXIV

  2. @pukhalski ! Solution Architect, EPAM Systems Lecturer, British Higher School

    of Art & Design
  3. % of time spent 2013 2014 14 20 86 80

    Apps Mobile Web
  4. Why apps? • Easy to control over stores • Rich-get-richer

    dynamics • Easier to retain users
  5. None
  6. None
  7. HTML5 vs Native on mobile Web

  8. Watch your language • HTML5 is a marketing buzzword •

    Responsive Web Design doesn’t exist Good design is responsive by default.
  9. What is web?

  10. – Wiki “Web is a system of interlinked “hypertext documents

    that run “on and are accessed “via the Internet.”
  11. None
  12. Custom URL schemas • fb://profile/(fbid) • tel:+180022933 • twitter://username •

  13. applinks.org

  14. Native is a part of Web ecosystem

  15. What is native?

  16. “Native — software or data “formats supported by a certain

    “system with minimal overhead “and additional components” – Wiki
  17. Web technologies are native for browsers

  18. Browsers are responsible for standards support

  19. Apps boom Do you remember dot-com boom?

  20. Why do we love apps? • Push Notifications • Offline

    Mode • Performance ! ! • Look & Feel • Distribution • Background Sync
  21. Look & Feel

  22. famo.us

  23. None
  24. Touch Events, Pointer Events, Mouse Events

  25. ~300ms delay

  26. tap.js

  27. document .getElementById('any-element') .addEventListener('tap', function (e) { // All the magic

    happens here }); $('#any-element').on('tap', function (e) { // All the magic happens here });
  28. Performance

  29. Heavy DOM

  30. Facebook React.js Model DOM Virtual DOM Redraw on requestAnimationFrame Changes

    Changes Changes
  31. Animations

  32. 2010-2013

  33. 2014

  34. requestAnimationFrame

  35. None
  36. None
  37. element.animate([ {cssProperty: value0}, {cssProperty: value1}, {cssProperty: value2}, //... ], {

    duration: timeInMs, iterations: iterationCount, delay: delayValue });
  38. Offline Mode

  39. Cache Manifest

  40. A declarative way CACHE MANIFEST # 2012-02-21 v1.0.0 /theme.css /logo.png

    /main.js ! NETWORK: login.asp ! FALLBACK: /html/ /offline.html
  41. 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/
  42. Debugging hell 1. Change the code 2. Change manifest 3.

    Clean cache 4. Debug 5. GOTO 1
  43. None
  44. Meet Service Worker

  45. Event-driven scripts that run independently of web pages

  46. • Handling resource requests • Foundation for other standards

  47. navigator.serviceWorker.register('/worker.js') .then(function(serviceWorker) { // To use the serviceWorker immediately, //

    you might call window.location.reload() });
  48. 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: { /* ... */ } }) })); } });
  49. 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); });
  50. this.addEventListener("fetch", function(e) { ! e.respondWith( caches.match(e.request, “videos-cache") ); });

  51. 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); } ) ); } });
  52. Distribution

  53. Stores • App Store • Google Play • BlackBerry AppWorld

    • Amazon Appstore • EPAM Mobile Appstore
  54. Stores • App Store • Google Play • BlackBerry AppWorld

    • Amazon Appstore • EPAM Mobile Appstore
  55. Will you install an app to buy a car?

  56. None
  57. None
  58. None
  59. Install this app

  60. navigator .mozApps .install("path/to/manifest");

  61. Notifications

  62. Web Notifications

  63. var Notification = window.Notification || window.mozNotification || window.webkitNotification; ! Notification.requestPermission(

    function (permission) { // console.log(permission); } );
  64. ! var notification = new Notification( "SEC Spring 2014", {

    body: "I hope you enjoy the conference" } ); ! notification.onclick = function () { // Something to do };
  65. • Opened website • Client-side only

  66. Safari Remote Notifications

  67. The Flow • Request permissions • Register the device •

    Send notifications
  68. {! ! "aps": {! ! "alert": {! ! "title": "Flight

    A998 Now Boarding",! ! "body": "Boarding has begun for Flight A998.",! ! "action": "View"! ! },! ! "url-args": ["boarding", "A998"]! ! }! ! }!
  69. • Server-side • Offline

  70. Service Worker Push Notifications

  71. The Flow • Register locally • Register on the server

    side • Send notifications
  72. 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); ); }); });
  73. this.onpush = function(e) { console.log(e.message.data); // Cache the data //

    ... }
  74. Background Sync

  75. Service Worker? Yes!

  76. navigator.serviceWorker.register("/sw.js"); ! ! navigator.serviceWorker.whenReady() .then(function(sw) { ! navigator.registerSync( "id", {

    interval: 'daily', data: '', description: '', lang: '', dir: '' } ); });
  77. this.onsync = function(event) { var data = JSON.parse(event.data); ! if

    (event.id === "id") { // make something with data } };
  78. How to make mobile web suck less?

  79. Blame the implementation, not technique

  80. Thanks @pukhalski Ilya_Pukhalski@epam.com