Slide 1

Slide 1 text

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.

Slide 2

Slide 2 text

I'm here to defend client-side apps.

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

“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.

Slide 5

Slide 5 text

“Rails doesn't scale.

Slide 6

Slide 6 text

1MB of JavaScript for 140 characters.

Slide 7

Slide 7 text

What is performance?

Slide 8

Slide 8 text

Make it faster.

Slide 9

Slide 9 text

Lower latency. More requests per second. Aggressive caching.

Slide 10

Slide 10 text

These are all important.

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Turbolinks

Slide 14

Slide 14 text

“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.

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

treated like normal links

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Page not returning to previous scroll location

Slide 20

Slide 20 text

302 redirects do not work

Slide 21

Slide 21 text

302 redirects do not work WONTFIX

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

500ms The problem with this is that your user interface can only respond as fast as your server—especially bad on flaky 3G connections

Slide 27

Slide 27 text

By decoupling the user interface from the typical HTTP request/ response cycle, you can completely modify how updates are communicated to the client. WebSocket

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

User Interface HTML+CSS Data Persistence ? Application Architecture ?

Slide 34

Slide 34 text

User Interface HTML+CSS Data Persistence Application Architecture

Slide 35

Slide 35 text

Fast by Default

Slide 36

Slide 36 text

a confession

Slide 37

Slide 37 text

Turn best practices into patterns

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

1. JavaScript is cheaper than DOM

Slide 40

Slide 40 text

Get truth out of the DOM

Slide 41

Slide 41 text

Eliminate intermediate state

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

Backbone

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

6 DOM manipulations for 3 todos

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

4 DOM manipulations for 3 todos

Slide 68

Slide 68 text

1000 todos 2000 DOM manips 1001 DOM manips

Slide 69

Slide 69 text

How do we do it?

Slide 70

Slide 70 text

The Run Loop

Slide 71

Slide 71 text

App Code App Code App Code App Code End Run Loop Start Run Loop

Slide 72

Slide 72 text

Bindings

Slide 73

Slide 73 text

Object A Object B age age binding 1 1

Slide 74

Slide 74 text

Naïve Approach

Slide 75

Slide 75 text

Object A Object B age age binding 1 1

Slide 76

Slide 76 text

Object A Object B age age binding 2 2

Slide 77

Slide 77 text

Object A Object B age age binding 3 3

Slide 78

Slide 78 text

Object A Object B age age binding 4 4

Slide 79

Slide 79 text

Object A Object B age age binding 5 5

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

Object A Object B age age binding 1 1

Slide 82

Slide 82 text

Object A Object B age age binding 2 1

Slide 83

Slide 83 text

Object A Object B age age binding 3 1

Slide 84

Slide 84 text

Object A Object B age age binding 4 1

Slide 85

Slide 85 text

Object A Object B age age binding 5 1

Slide 86

Slide 86 text

Object A Object B age age binding 5 5

Slide 87

Slide 87 text

String Templates

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

2. Declarative as possible

Slide 90

Slide 90 text

Declarative Advantages •Can be optimized by the system •As the framework gets faster, your apps get faster •Makes best practices portable •Automatic memory management

Slide 91

Slide 91 text

Memory consumption is performance.

Slide 92

Slide 92 text

Demo

Slide 93

Slide 93 text

3. Laziness is a virtue

Slide 94

Slide 94 text

Computed properties only calculated when needed.

Slide 95

Slide 95 text

Cached out of the box.

Slide 96

Slide 96 text

Identity Map

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

Demo

Slide 99

Slide 99 text

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