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

Your Website is Just an App

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.

tomdale

November 13, 2012
Tweet

More Decks by tomdale

Other Decks in Technology

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.

    View Slide

  2. I'm here to defend
    client-side apps.

    View Slide

  3. View Slide

  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.

    View Slide

  5. “Rails doesn't
    scale.

    View Slide

  6. 1MB of JavaScript
    for 140 characters.

    View Slide

  7. What is
    performance?

    View Slide

  8. Make it faster.

    View Slide

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

    View Slide

  10. These are all
    important.

    View Slide

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

    View Slide

  12. View Slide

  13. Turbolinks

    View Slide

  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.

    View Slide

  15. View Slide


  16. treated like normal links

    View Slide

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

    View Slide

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

    View Slide

  19. Page not returning to
    previous scroll location

    View Slide

  20. 302 redirects do not
    work

    View Slide

  21. 302 redirects do not
    work
    WONTFIX

    View Slide

  22. View Slide

  23. View Slide

  24. View Slide

  25. View Slide

  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

    View Slide

  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

    View Slide

  28. View Slide

  29. •Aggressive caching
    •Available offline
    •Fast to respond
    •Client-side rendering
    Native App Features

    View Slide

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

    View Slide

  31. View Slide

  32. View Slide

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

    View Slide

  34. User Interface HTML+CSS
    Data Persistence
    Application
    Architecture

    View Slide

  35. Fast by Default

    View Slide

  36. a confession

    View Slide

  37. Turn best practices
    into patterns

    View Slide

  38. 1. JavaScript is cheaper than
    DOM
    2. Be declarative as possible
    3. Laziness is a virtue

    View Slide

  39. 1. JavaScript is
    cheaper than DOM

    View Slide

  40. Get truth out of
    the DOM

    View Slide

  41. Eliminate
    intermediate state

    View Slide

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

    View Slide

  43. Backbone

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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


    View Slide

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


    View Slide

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


    View Slide

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


    View Slide

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



    View Slide

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



    View Slide

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



    View Slide

  56. 6 DOM manipulations
    for 3 todos

    View Slide

  57. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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


    View Slide

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



    View Slide

  67. 4 DOM manipulations
    for 3 todos

    View Slide

  68. 1000 todos
    2000
    DOM manips
    1001
    DOM manips

    View Slide

  69. How do we
    do it?

    View Slide

  70. The Run Loop

    View Slide

  71. App Code
    App Code
    App Code
    App Code
    End Run Loop
    Start Run Loop

    View Slide

  72. Bindings

    View Slide

  73. Object A Object B
    age age
    binding
    1 1

    View Slide

  74. Naïve Approach

    View Slide

  75. Object A Object B
    age age
    binding
    1 1

    View Slide

  76. Object A Object B
    age age
    binding
    2 2

    View Slide

  77. Object A Object B
    age age
    binding
    3 3

    View Slide

  78. Object A Object B
    age age
    binding
    4 4

    View Slide

  79. Object A Object B
    age age
    binding
    5 5

    View Slide

  80. View Slide

  81. Object A Object B
    age age
    binding
    1 1

    View Slide

  82. Object A Object B
    age age
    binding
    2 1

    View Slide

  83. Object A Object B
    age age
    binding
    3 1

    View Slide

  84. Object A Object B
    age age
    binding
    4 1

    View Slide

  85. Object A Object B
    age age
    binding
    5 1

    View Slide

  86. Object A Object B
    age age
    binding
    5 5

    View Slide

  87. String Templates

    View Slide

  88. Advantages
    •DOM traversal sucks in general
    •DOM traversal sucks in IE
    •One innerHTML access

    View Slide

  89. 2. Declarative as
    possible

    View Slide

  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

    View Slide

  91. Memory consumption
    is performance.

    View Slide

  92. Demo

    View Slide

  93. 3. Laziness is a
    virtue

    View Slide

  94. Computed properties
    only calculated when
    needed.

    View Slide

  95. Cached out of
    the box.

    View Slide

  96. Identity Map

    View Slide

  97. Identity Map
    •Every request for a record
    returns the same object
    •Changes synchronized across
    app
    •Avoid redundant HTTP
    requests

    View Slide

  98. Demo

    View Slide

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

    View Slide