Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Your Website is Just an App

9bf3a766e037b9d5a4da0a6f9d0f4f68?s=47 tomdale
November 13, 2012

Your Website is Just an App

In this talk, we'll explore why you should think of your web application as no different from an iOS or Android app, by moving 100% of logic and HTML to the browser. While other frameworks like Backbone help you embed "islands of richness" into the traditional page-by-page model, we'll also explore the tools Ember.js gives you to build real, honest-to-goodness apps that run entirely in the browser.

9bf3a766e037b9d5a4da0a6f9d0f4f68?s=128

tomdale

November 13, 2012
Tweet

Transcript

  1. Your Website is Just an App This is a talk

    in two parts. In the first half, I want to convince you that, if you have a sophisticated web app, you should be architecting it like an app for every other platform—Mac, Windows, iOS, Android. In the second half, I'll talk specifically about some of the features of Ember.js that help you write these apps, and make them as fast as possible.
  2. I'm here to defend client-side apps.

  3. None
  4. “To improve the twitter.com experience for everyone, we've been working

    to take back control of our front-end performance by moving the rendering to the server.
  5. “Rails doesn't scale.

  6. 1MB of JavaScript for 140 characters.

  7. What is performance?

  8. Make it faster.

  9. Lower latency. More requests per second. Aggressive caching.

  10. These are all important.

  11. But it‘s easy to optimize for the local maximum.

  12. None
  13. Turbolinks

  14. “Turbolinks makes following links in your web application faster. Instead

    of letting the browser recompile the JavaScript and CSS between each page change, it keeps the current page instance alive and replaces only the body and the title in the head.
  15. None
  16. <link rel="canonical"> treated like normal links

  17. Asset caching doesn't work with async loaded JS (like Google

    Analytics)
  18. Scripts with type other than "text/javascript" evaluated as JS

  19. Page not returning to previous scroll location

  20. 302 redirects do not work

  21. 302 redirects do not work WONTFIX

  22. None
  23. None
  24. None
  25. None
  26. 500ms The problem with this is that your user interface

    can only respond as fast as your server—especially bad on flaky 3G connections
  27. By decoupling the user interface from the typical HTTP request/

    response cycle, you can completely modify how updates are communicated to the client. WebSocket
  28. None
  29. •Aggressive caching •Available offline •Fast to respond •Client-side rendering Native

    App Features
  30. If it‘s appropriate, please consider writing a client-side web app.

  31. None
  32. None
  33. User Interface HTML+CSS Data Persistence ? Application Architecture ?

  34. User Interface HTML+CSS Data Persistence Application Architecture

  35. Fast by Default

  36. a confession

  37. Turn best practices into patterns

  38. 1. JavaScript is cheaper than DOM 2. Be declarative as

    possible 3. Laziness is a virtue
  39. 1. JavaScript is cheaper than DOM

  40. Get truth out of the DOM

  41. Eliminate intermediate state

  42. { todos: [{ isDone: false }, { isDone: false },

    { isDone: false }], remainingTodos: 3 } Todo 1 Todo 2 Todo 3 3 Remaining
  43. Backbone

  44. { todos: [{ isDone: true }, { isDone: false },

    { isDone: false }], remainingTodos: 3 } Todo 1 Todo 2 Todo 3 3 Remaining
  45. { todos: [{ isDone: true }, { isDone: false },

    { isDone: false }], remainingTodos: 3 } Todo 1 Todo 2 Todo 3 3 Remaining ✔
  46. { todos: [{ isDone: true }, { isDone: false },

    { isDone: false }], remainingTodos: 2 } Todo 1 Todo 2 Todo 3 3 Remaining ✔
  47. { todos: [{ isDone: true }, { isDone: false },

    { isDone: false }], remainingTodos: 2 } Todo 1 Todo 2 Todo 3 2 Remaining ✔
  48. { todos: [{ isDone: true }, { isDone: true },

    { isDone: false }], remainingTodos: 2 } Todo 1 Todo 2 Todo 3 2 Remaining ✔
  49. { todos: [{ isDone: true }, { isDone: true },

    { isDone: false }], remainingTodos: 2 } Todo 1 Todo 2 Todo 3 2 Remaining ✔ ✔
  50. { todos: [{ isDone: true }, { isDone: true },

    { isDone: false }], remainingTodos: 1 } Todo 1 Todo 2 Todo 3 2 Remaining ✔ ✔
  51. { todos: [{ isDone: true }, { isDone: true },

    { isDone: false }], remainingTodos: 1 } Todo 1 Todo 2 Todo 3 1 Remaining ✔ ✔
  52. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 1 } Todo 1 Todo 2 Todo 3 1 Remaining ✔ ✔
  53. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 1 } Todo 1 Todo 2 Todo 3 1 Remaining ✔ ✔ ✔
  54. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 0 } Todo 1 Todo 2 Todo 3 1 Remaining ✔ ✔ ✔
  55. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 0 } Todo 1 Todo 2 Todo 3 0 Remaining ✔ ✔ ✔
  56. 6 DOM manipulations for 3 todos

  57. None
  58. { todos: [{ isDone: true }, { isDone: false },

    { isDone: false }], remainingTodos: 3 } Todo 1 Todo 2 Todo 3 3 Remaining
  59. { todos: [{ isDone: true }, { isDone: false },

    { isDone: false }], remainingTodos: – } Todo 1 Todo 2 Todo 3 3 Remaining
  60. { todos: [{ isDone: true }, { isDone: true },

    { isDone: false }], remainingTodos: – } Todo 1 Todo 2 Todo 3 3 Remaining
  61. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: – } Todo 1 Todo 2 Todo 3 3 Remaining
  62. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 0 } Todo 1 Todo 2 Todo 3 3 Remaining
  63. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 0 } Todo 1 Todo 2 Todo 3 0 Remaining
  64. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 0 } Todo 1 Todo 2 Todo 3 0 Remaining ✔
  65. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 0 } Todo 1 Todo 2 Todo 3 0 Remaining ✔ ✔
  66. { todos: [{ isDone: true }, { isDone: true },

    { isDone: true }], remainingTodos: 0 } Todo 1 Todo 2 Todo 3 0 Remaining ✔ ✔ ✔
  67. 4 DOM manipulations for 3 todos

  68. 1000 todos 2000 DOM manips 1001 DOM manips

  69. How do we do it?

  70. The Run Loop

  71. App Code App Code App Code App Code End Run

    Loop Start Run Loop
  72. Bindings

  73. Object A Object B age age binding 1 1

  74. Naïve Approach

  75. Object A Object B age age binding 1 1

  76. Object A Object B age age binding 2 2

  77. Object A Object B age age binding 3 3

  78. Object A Object B age age binding 4 4

  79. Object A Object B age age binding 5 5

  80. None
  81. Object A Object B age age binding 1 1

  82. Object A Object B age age binding 2 1

  83. Object A Object B age age binding 3 1

  84. Object A Object B age age binding 4 1

  85. Object A Object B age age binding 5 1

  86. Object A Object B age age binding 5 5

  87. String Templates

  88. Advantages •DOM traversal sucks in general •DOM traversal sucks in

    IE •One innerHTML access
  89. 2. Declarative as possible

  90. Declarative Advantages •Can be optimized by the system •As the

    framework gets faster, your apps get faster •Makes best practices portable •Automatic memory management
  91. Memory consumption is performance.

  92. Demo

  93. 3. Laziness is a virtue

  94. Computed properties only calculated when needed.

  95. Cached out of the box.

  96. Identity Map

  97. Identity Map •Every request for a record returns the same

    object •Changes synchronized across app •Avoid redundant HTTP requests
  98. Demo

  99. Thank you. Questions? http://plus.tomdale.net http://emberjs.com @tomdale