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

Ember.js at FrOSCon 2013

Ember.js at FrOSCon 2013

Single Page Application mit Ember.js erstellen. #froscon #froscon8

Stefan Wintermeyer

August 25, 2013
Tweet

More Decks by Stefan Wintermeyer

Other Decks in Technology

Transcript

  1. What's the impact of slow sites? Lower conversions and engagement,

    higher bounce rates... Ilya Grigorik @igrigorik Make The Web Faster, Google Have a look at Ilya‘s book!
  2. Usability Engineering 101 Delay User reaction 0 - 100 ms

    Instant 100 - 300 ms Feels sluggish 300 - 1000 ms Machine is working... 1 s+ Mental context switch 10 s+ I'll come back later... Stay under 250 ms to feel "fast". Stay under 1000 ms to keep users attention. @igrigorik
  3. Performance Related Changes and their User Impact Web Search Delay

    Experiment @igrigorik • The cost of delay increases over time and persists • Delays under half a second impact business metrics • "Speed matters" is not just lip service Type of Delay Delay (ms) Duration (weeks) Impact on Avg. Daily Searches Pre-header 50 4 Not measurable Pre-header 100 4 -0.20% Post-header 200 6 -0.59% Post-header 400 6 -0.59% Post-ads 200 4 -0.30%
  4. Performance Related Changes and their User Impact Server Delays Experiment

    • Strong negative impacts • Roughly linear changes with increasing delay • Time to Click changed by roughly double the delay @igrigorik
  5. Yo ho ho and a few billion pages of RUM

    How speed affects bounce rate @igrigorik
  6. For many, mobile is the one and only internet device!

    Country Mobile-only users Egypt 70% India 59% South Africa 57% Indonesia 44% United States 25% onDevice Research @igrigorik
  7. The (short) life of our 1000 ms budget 3G (200

    ms RTT) 4G(80 ms RTT) Control plane (200-2500 ms) (50-100 ms) DNS lookup 200 ms 80 ms TCP Connection 200 ms 80 ms TLS handshake (200-400 ms) (80-160 ms) HTTP request 200 ms 80 ms Leftover budget 0-400 ms 500-760 ms Network overhead of one HTTP request! @igrigorik The browser needs 100 - 150ms to render the page.
  8. [email protected] @wintermeyer userlist !"" css # !"" bootstrap-responsive.css # $""

    bootstrap.css !"" img !"" index.html $"" js !"" app.js $"" libs !"" ember.js !"" ember-data.js !"" handlebars.js !"" jquery-1.9.1.js $"" md5.js
  9. [email protected] @wintermeyer userlist !"" css # !"" bootstrap-responsive.css # $""

    bootstrap.css !"" img !"" index.html $"" js !"" app.js $"" libs !"" ember.js !"" ember-data.js !"" handlebars.js !"" jquery-1.9.1.js $"" md5.js
  10. [email protected] @wintermeyer <tbody> {{#each this itemController="user"}} <tr {{bindAttr class="isDirty:warning"}}> <td>

    {{#if syntacticallyPlausableEmail}} <img {{bindAttr src="gravatarUrl"}} w {{/if}} </td> <td>{{firstName}}</td> <td>{{lastName}}</td> <td> {{#unless isNew}} {{#linkTo 'user.edit' this activeClas {{/unless}} </td> </tr> {{/each}} </tbody> Auszug index.html
  11. [email protected] @wintermeyer <tbody> {{#each this itemController="user"}} <tr {{bindAttr class="isDirty:warning"}}> <td>

    {{#if syntacticallyPlausableEmail}} <img {{bindAttr src="gravatarUrl"}} w {{/if}} </td> <td>{{firstName}}</td> <td>{{lastName}}</td> <td> {{#unless isNew}} {{#linkTo 'user.edit' this activeClas {{/unless}} </td> </tr> {{/each}} </tbody> Auszug index.html
  12. [email protected] @wintermeyer <tbody> {{#each this itemController="user"}} <tr {{bindAttr class="isDirty:warning"}}> <td>

    {{#if syntacticallyPlausableEmail}} <img {{bindAttr src="gravatarUrl"}} w {{/if}} </td> <td>{{firstName}}</td> <td>{{lastName}}</td> <td> {{#unless isNew}} {{#linkTo 'user.edit' this activeClas {{/unless}} </td> </tr> {{/each}} </tbody> Auszug index.html
  13. [email protected] @wintermeyer <tbody> {{#each this itemController="user"}} <tr {{bindAttr class="isDirty:warning"}}> <td>

    {{#if syntacticallyPlausableEmail}} <img {{bindAttr src="gravatarUrl"}} w {{/if}} </td> <td>{{firstName}}</td> <td>{{lastName}}</td> <td> {{#unless isNew}} {{#linkTo 'user.edit' this activeClas {{/unless}} </td> </tr> {{/each}} </tbody> Auszug index.html
  14. [email protected] @wintermeyer <tbody> {{#each this itemController="user"}} <tr {{bindAttr class="isDirty:warning"}}> <td>

    {{#if syntacticallyPlausableEmail}} <img {{bindAttr src="gravatarUrl"}} w {{/if}} </td> <td>{{firstName}}</td> <td>{{lastName}}</td> <td> {{#unless isNew}} {{#linkTo 'user.edit' this activeClas {{/unless}} </td> </tr> {{/each}} </tbody> Auszug index.html
  15. [email protected] @wintermeyer <tbody> {{#each this itemController="user"}} <tr {{bindAttr class="isDirty:warning"}}> <td>

    {{#if syntacticallyPlausableEmail}} <img {{bindAttr src="gravatarUrl"}} w {{/if}} </td> <td>{{firstName}}</td> <td>{{lastName}}</td> <td> {{#unless isNew}} {{#linkTo 'user.edit' this activeClas {{/unless}} </td> </tr> {{/each}} </tbody> Auszug index.html
  16. [email protected] @wintermeyer userlist !"" css # !"" bootstrap-responsive.css # $""

    bootstrap.css !"" img !"" index.html $"" js !"" app.js $"" libs !"" ember.js !"" ember-data.js !"" handlebars.js !"" jquery-1.9.1.js $"" md5.js
  17. [email protected] @wintermeyer App = Ember.Application.create(); App.Router.map(function() { this.resource('about'); this.resource('users', function()

    { this.route('new'); this.resource('user', { path: ':user_id' }, this.route('edit'); }); }) }); App.UsersRoute = Ember.Route.extend({ model: function() { return App.User.find(); } }); Auszug app.js
  18. [email protected] @wintermeyer userlist !"" css # !"" bootstrap-responsive.css # $""

    bootstrap.css !"" img !"" index.html $"" js !"" app.js $"" libs !"" ember.js !"" ember-data.js !"" handlebars.js !"" jquery-1.9.1.js $"" md5.js
  19. [email protected] @wintermeyer App.User = DS.Model.extend({ firstName: DS.attr('string'), lastName: DS.attr('string'), email:

    DS.attr('sting') }); App.User.FIXTURES = [{ id: 1, firstName: "Linus", lastName: "Torvalds", email: "[email protected]" }, { id: 2, firstName: "John", lastName: "Hall", email: "[email protected]" }, { Auszug app.js