Single Page Applications done right

Single Page Applications done right

BrazilJS 2014

3e52153b29fd5540b549089f1f925eca?s=128

Eduardo Lundgren

August 21, 2014
Tweet

Transcript

  1. Single Page Applications done right @eduardolundgren

  2. browser diet

  3. Perceived performance

  4. Persistence of vision

  5. None
  6. None
  7. None
  8. 24 frames per second 41 milliseconds per frame Real time

  9. 24 fps 60 fps

  10. User Perspective 10 milliseconds can make a really good game

    into a really bad game. 10 milliseconds on an e-commerce can reduce sales. Interval User perspective 0 - 100 milliseconds Instant 100 - 300 milliseconds Perceptible delay 300 - 1000 milliseconds Task Focus, Perceptible delay 1+ second Mental context switch 10+ seconds I'll come back later
  11. 10KB of HTML 3KB of CSS 500Bytes of GIFs Hacker

    News, technically, it's fast First render in <500ms
  12. The page loads really fast, but I can't read anything

    Needs to zoom and scroll The perceived performance is actually 5+ seconds What is the problem?
  13. Page load time

  14. Task completion

  15. What really matters? Visits, engagement, conversions.

  16. What is performance?

  17. “Performance means many different things to many different people”

  18. Actual performance

  19. Actual performance GPU Acceleration RAM Usage Parsers & Lexers Layers

    & Render Trees Multi-Core Optimization
  20. Actual performance GPU Acceleration RAM Usage Parsers & Lexers Layers

    & Render Trees Multi-Core Optimization Energy constrains
  21. Transport When you ship bytes, needs to execute those bytes.

    Bytes Parse What happens after shipping those bytes? Selector Matching Style Calculation Layout & Painting JavaScript GC Performance Latency Bandwidth Protocols
  22. Is there such thing as fast enough?

  23. You made it 2x faster, is that enough?

  24. When we talk about Perceived Performance it is a factor

    of multiple things.
  25. Perceived Performance = f( Expected Performance, UX, Actual Performance )

  26. Perceived Performance = f( Expected Performance, UX, Actual Performance )

    Computer power
  27. Perceived Performance = f( Expected Performance, UX, Actual Performance )

    It's the glue!
  28. “Performance is not just milliseconds and bytes. It's also how

    milliseconds and bytes translate to how the user perceives the app” Ilya Grigorik Developer Advocate, Google
  29. Single Page Application

  30. None
  31. “SPA is a web site that fits on a single

    web page with the goal of providing a more fluid user experience”
  32. SPAs were pioneered in the mid-2000s by web apps like

    Gmail and Google Maps.
  33. None
  34. None
  35. These days the approach is widely employed by others

  36. How to build a
 Single Page Application?

  37. <iframe> http://trackingjs.com

  38. Ajax http://trackingjs.com

  39. var xhr = new XMLHttpRequest(); xhr.onload = successFn; xhr.onerror =

    errorFn; xhr.open('GET', '/foo.html'); xhr.send(); Ajax
  40. Define surfaces to update on navigate JavaScript listens for links

    Ajax http://trackingjs.com 1 2
  41. Content is empty Link is clicked
 Request content using XHR

    Ajax http://trackingjs.com Loading... Some fancy loader appears 1 2 3
  42. Content is loaded Ajax http://trackingjs.com URL doesn't change 1 2

  43. Hijax http://trackingjs.com

  44. var xhr = new XMLHttpRequest(); xhr.onload = successFn; xhr.onerror =

    errorFn; xhr.open('GET', '/foo.html'); xhr.send(); location.hash = '#foo'; Hijax
  45. Define surfaces to update on navigate JavaScript listens for links

    Hijax http://trackingjs.com 1 2
  46. Content is empty Link is clicked
 Request content using XHR

    Hijax http://trackingjs.com#docs Loading... Some fancy loader appears URL updates with hash bang # 1 4 2 3
  47. Content is loaded Hijax http://trackingjs.com#docs URL updates with hash bang

    # 2 1
  48. Okay, so what is a good single page app then?

  49. SEO & Bookmarkability

  50. Share or bookmark a link should always display the same

    content
  51. History API window.location.href = "page.html"; history.pushState({}, "title", "page.html"); history.replaceState({}, "title",

    "page.html");
  52. History API page01.html page02.html page03.html Navigate between pages without page

    refresh history.state: null
  53. History API history.pushState({}, '', 'page02.html') page01.html page02.html page03.html Navigate between

    pages without page refresh history.state: {}
  54. History API history.pushState(null, '', 'page02.html') page01.html page02.html page03.html history.replaceState({ key:

    123 }, '', 'page02.html') Navigate between pages without page refresh history.state: { key: 123 }
  55. History API history.pushState(null, '', 'page02.html') page01.html page02.html page03.html history.replaceState({ key:

    123 }, '', 'page02.html') Navigate between pages without page refresh "onpopstate" ‏ history.back(); history.state: null
  56. None
  57. None
  58. History navigation

  59. By using History API you can manipulate the browser history,

    so you can use browser’s back & forward buttons
  60. Cacheable screens

  61. Once you load a certain surface this content is cached

    in memory and is retrieved later on without any additional request
  62. None
  63. UI feedback

  64. When some content is requested, it indicates to the user

    that something is happening
  65. Pending navigations

  66. Block UI rendering until data is loaded

  67. None
  68. State retention

  69. Scrolling, reloading or navigating through the history of the page

    should get back to where it was
  70. None
  71. State retention window.history.state = {}; Memory State object size limits

    (640KB)
 Serialized objects Memory management to avoid leaks
  72. Memory
 recover

  73. None
  74. Hybrid rendering

  75. Ajax + server-side rendering allows disable pushState at any time,

    allowing progressive enhancement.
  76. None
  77. Client-side only rendering <div id="content"></div> XHR Response

  78. None
  79. Page resources management

  80. Evaluate scripts and stylesheets from dynamic loaded resources

  81. None
  82. Timeout detection

  83. Timeout if the request takes too long to load

  84. “Mimic the native browser behavior is what makes your Single

    Page Application done right.”
  85. 2012

  86. None
  87. 2013

  88. None
  89. 2014?

  90. None
  91. Overview

  92. Overview Surface Surface Surface Surface

  93. Overview Surface Surface Surface Surface Screen

  94. Yahoo

  95. youtube

  96. Surface

  97. Daniel Pupius Former Googler, Medium Chief Engineer

  98. Lifecycle subsequent navigations are handled without a full page load

    Initial Page Loaded additional content is requested via Ajaxy techniques Ajax Request Update the URL Render Page Flip Screen Finalize Request pages are bookmarkable and sharable once content is ready, flip the screen render relevant parts of the page URL Routing makes it easy to wire up route handlers for different application states UI Feedback
  99. senna.App senna.Screen senna.Surface Our solution

  100. Showcase video

  101. var app = new senna.App(); app.addSurfaces(['header', 'body', 'footer']); app.addRoutes(new senna.Route(/.*\.html/,

    senna.Screen)); app.navigate('/foo.html'); JavaScript
  102. <link rel="senna-route" href="regex:.*\.html" type="senna.Screen"> ! <body data-senna> <div id="header" data-senna-surface></div>

    <div id="body" data-senna-surface></div> <div id="footer" data-senna-surface></div> </body> Data attributes
  103. Web components? Coming soon...

  104. Demo time

  105. Less Bandwidth Data transfered (KB) 0 350 700 1050 1400

    Page 1 Page 2 Page 3 Page 4 Refresh SPA
  106. 1.3MB transferred 22.7KB transferred

  107. Low Cost USD USD 20 40 USD 40 USD 100

    $30 USD 50 Monthly broadband subscription Oxford Internet Institute
  108. Mobile

  109. Productivity

  110. Main features SEO, Bookmarkability Hybrid rendering State retention Timeout detection

    Pending navigation UI Feedback History navigation Cacheable screens Resources management
  111. ~8KB

  112. And more… Zero dependencies Open source Fully tested Lightweight ~8KB

    Data attributes Built in promises
  113. None
  114. Team Iliyan Peychev Pedro Marques Zeno Rocha Iliyan Peychev

  115. @eduardolundgren Thank you!