Writing Fast Client-Side Code: Lessons Learned from SproutCore
-
Upload
yehuda-katz -
Category
Technology
-
view
1.913 -
download
1
description
Transcript of Writing Fast Client-Side Code: Lessons Learned from SproutCore
SproutCore and Performance
Wednesday, June 29, 2011
“Albert Einstein
One should not pursue goals that are easily achieved. One must develop an instinct for what one can just barely achieve through one’s greatest efforts.
Wednesday, June 29, 2011
"Fast By Default"
Wednesday, June 29, 2011
Core Concepts
Wednesday, June 29, 2011
1. JS is cheaper
than DOMWednesday, June 29, 2011
2. Keep Intermediate State in JS
Wednesday, June 29, 2011
(and out of DOM)
Wednesday, June 29, 2011
3. Events Cannot
CoalesceWednesday, June 29, 2011
(prefer cache
clearing)Wednesday, June 29, 2011
4. Materialize Objects
When UsedWednesday, June 29, 2011
(also, proxy, don't copy)
Wednesday, June 29, 2011
5. Follow Speed
GuidelinesWednesday, June 29, 2011
JS is Cheaper
than DOMWednesday, June 29, 2011
change title
change name
change address
change DOM
change DOM
change DOM
Wednesday, June 29, 2011
change title
change name
change address
change DOM
Wednesday, June 29, 2011
change title
change name
change address
change DOM
Wednesday, June 29, 2011
browsereventloop
SCrunloop
Wednesday, June 29, 2011
nativeevent
handle event
handle event
handle event
sync bindings
Wednesday, June 29, 2011
nativeevent
handle event
handle event
handle event
sync bindings
Wednesday, June 29, 2011
nativeevent
handle event
handle event
handle event
sync bindings
Wednesday, June 29, 2011
JS Code
JS Code
JS Code
Event Handling
...
DOM Code
Wednesday, June 29, 2011
Keep Intermediate State in JS
Wednesday, June 29, 2011
Case Study
Wednesday, June 29, 2011
“ I want to have a view that displays the total number of items that are marked done.
I want to have a feature that can mark all remaining items done.
Wednesday, June 29, 2011
What do you want to do?
4 items remaining
Mark All Done
Wash dishes
Take out garbage
Make bed
Relax
Wednesday, June 29, 2011
What do you want to do?
4 items remaining
Mark All Done
Wash dishes
Take out garbage
Make bed
Relax
✓
Wednesday, June 29, 2011
What do you want to do?
3 items remaining
Mark All Done
Wash dishes
Take out garbage
Make bed
Relax
✓
Wednesday, June 29, 2011
What do you want to do?
3 items remaining
Mark All Done
Wash dishes
Take out garbage
Make bed
Relax
✓
Wednesday, June 29, 2011
What do you want to do?
3 items remaining
Mark All Done
Wash dishes
Take out garbage
Make bed
Relax
✓✓
Wednesday, June 29, 2011
What do you want to do?
0 items remaining
Mark All Done
Wash dishes
Take out garbage
Make bed
Relax
✓✓✓✓
✓
Wednesday, June 29, 2011
"KVO"
Wednesday, June 29, 2011
item marked done
re-render stats view
Wednesday, June 29, 2011
Backbone
window.AppView = Backbone.View.extend({ initialize: function() { _.bindAll(this, 'addOne', 'addAll', 'render'); this.input = this.$("#new-todo"); Todos.bind('add', this.addOne); Todos.bind('refresh', this.addAll); Todos.bind('all', this.render); Todos.fetch(); }, render: function() { var done = Todos.done().length; this.$('#todo-stats').html(this.statsTemplate({ total: Todos.length, done: Todos.done().length, remaining: Todos.remaining().length })); }});
Wednesday, June 29, 2011
Backbone
window.TodoList = Backbone.Collection.extend({ done: function() { return this.filter(function(todo){ return todo.get('done'); }); }, remaining: function() { return this.without.apply(this, this.done()); }}); window.Todos = new TodoList;
Wednesday, June 29, 2011
Toggling
Todos.forEach(function(todo) { todo.toggle();});
Wednesday, June 29, 2011
item marked done
compute remaining
compute done
render stats view
x N
Wednesday, June 29, 2011
This is foundational
Wednesday, June 29, 2011
No notion of intermediate
stateWednesday, June 29, 2011
Prefer Coalescing Operations
Wednesday, June 29, 2011
SproutCore
ArrayController.create({ content: [],
remaining: function() { return this.filterProperty('isDone', false); }.property('@each.isDone')});
Wednesday, June 29, 2011
Superficially Similar
Wednesday, June 29, 2011
item marked done
clear remaining cache
compute remaining
render stats view
x N
run loop
intermediate state
Wednesday, June 29, 2011
Easy to Overlook
Wednesday, June 29, 2011
SproutCore
ArrayController.create({ content: [],
remaining: function() { return this.filterProperty('isDone', false); }.property('@each.isDone')});
Wednesday, June 29, 2011
Key:Declare Intent
Wednesday, June 29, 2011
"Coalesce"
Wednesday, June 29, 2011
Wrong
Wednesday, June 29, 2011
A
"hello"
B
"hello"
Wednesday, June 29, 2011
A
"1"
B
"1"
Wednesday, June 29, 2011
A
"12"
B
"12"
Wednesday, June 29, 2011
A
"123"
B
"123"
Wednesday, June 29, 2011
Right
Wednesday, June 29, 2011
A
"hello"
B
"hello"
Wednesday, June 29, 2011
A
"1"
B
"hello"
Wednesday, June 29, 2011
A
"12"
B
"hello"
Wednesday, June 29, 2011
A
"123"
B
"hello"
Wednesday, June 29, 2011
A
"123"
B
"hello"run loop
Wednesday, June 29, 2011
A
"123"
B
"123"
Wednesday, June 29, 2011
Not 3 Deferred
ObserversWednesday, June 29, 2011
Materialize Objects
When UsedWednesday, June 29, 2011
Large JSON Structure
{ contacts: [ { name: "Yehuda", ... }, ... x 10,000 ]}
Wednesday, June 29, 2011
Acre, Julie
Appleseed, Johnny
Arrow, Bob
Astels, David
Atwood, Michael
Axelrod, Peter
Azeroth, Roy
Wednesday, June 29, 2011
Data Store
(JSON Hashes)
Contact
nametitleaddresstelephone
on demand
Wednesday, June 29, 2011
Data Store
(JSON Hashes)
Contacts
where company = "GOOGLE"
live
RecordArray
Ajax Response
Wednesday, June 29, 2011
Contact
datastatus
{ name: "yehuda" title: "Chief Technologist" address: "690 Spruce" telephone: "718.877.1325"}
Wednesday, June 29, 2011
No Need to Copy
PropertiesWednesday, June 29, 2011
Again, Foundational
Wednesday, June 29, 2011
One More Thing
Wednesday, June 29, 2011
Page Speed
Wednesday, June 29, 2011
Build Tools
Wednesday, June 29, 2011
Packed Files
Wednesday, June 29, 2011
CDN: Versioned
URLsWednesday, June 29, 2011
Expires Header: Same
Wednesday, June 29, 2011
Stylesheets at the Top
Wednesday, June 29, 2011
Scripts at the Bottom
Wednesday, June 29, 2011
Simple Layout
Wednesday, June 29, 2011
External JS and CSS
Wednesday, June 29, 2011
Minification
Wednesday, June 29, 2011
Easier said than done
Wednesday, June 29, 2011
SproutCore 2.0
Wednesday, June 29, 2011
OverallFile Size
Matters, but not as much as you think.
Wednesday, June 29, 2011
Modules w/ Declared
DepsWednesday, June 29, 2011
Lazy Loading Modules
Wednesday, June 29, 2011
Thank you.
Wednesday, June 29, 2011
Questions
Wednesday, June 29, 2011