Patterns of a frontend framework
Federico Pereiro
(yes, I wrote my own framework)
burnout.js
What we're talking about today
Scope: frontend of web applications (SPAs)
Takeaway: patterns
Experience: moderate
No code!
Terrain patterns
web pages (y < 2005)
HTML & CSS
link
Server
render
web apps (y > 2005)
HTML & CSS
action
Server
bootstrap
ajax
update
Web page
- Sending or receiving info requires a page refresh.
- The page is rendered once.
Web app
- Background communication with server.
- The page must be updated.
compare with batch program & web server route
Web apps need javascript
At a minimum:
- Perform bidirectional ajax
- Update parts of the view
- Navigation (SPA)
Optionally:
- Generate HTML/CSS (CSR)
- Hold client state
Solution patterns
Static patterns
1) HTML/CSS generation
2) Holding client state
HTML generation
<p>Hello!</p>
[‘p’, ‘Hello!’]
HTML generation
<p class=”nice”></p>
[‘p’, {class: ‘nice’}]
HTML generation
<div>
<p class=”nice”>Hello</p>
</div>
['div', [
[‘p’, {class: ‘nice’}, 'Hello']
]]
HTML generation
Conditional #1: cond ? [‘p’, ‘Hello!’] : []
Conditional #2: [‘p’, {class: cond ? ‘h2’ : ‘’}, ‘Hello!’]
Iteration:
[‘table’, ITEMS.map (function (item) {
return [‘tr’, [‘td’, item]];
})]
First static pattern
function (...) {
// return object literals that represent HTML/CSS
}
The state is king
The state with no frills
{}
Static patterns #1 & #2
function (State) {
// return object literals that represent HTML/CSS
}
Dynamic patterns
1) Data events
2) Complex events
Event system!
verb
path
arguments
Data events
add
set
rem
+
path
Data events
set ['users'] [{id: 1}, {id: 2}] add ['users'] {id: 3} rem ['users'] 1
Data events pattern
- Modify store
- Fire an event
Complex events pattern
submit ['user'] {id: 4}
retrieve ['users'] {filter: ...}
Complex events pattern
- Read store
- Perform computation or AJAX
- Update store
- Trigger other events
The juggernaut
View (path, complex_events, function (state) {
// object literals with stringified event triggers
});
Implementation patterns
Redrawing approach
nuke (innerHTML)
flatten (Myers diff)
Flatten & diff
- Make tree into array of strings
- Diff 'em
- Give up after n millis (O (nd))
View redrawing
- Descending priority for nested
-change verb
- Listeners path wildcard
Where's the verb?
add
set
rem
change
path wildcard
set ['users'] [{name: 'pepe'}]
set ['users', 0, 'name'] 'pepe'
change ['users']
change ['users', 0]
change ['users', 0, 'name']
change ['users', 0, 'email']
event
listener
github.com/fpereiro/gotoB
Questions?
Thank you!
fpereiro@gmail.com
Patterns of a frontend framework
By Fede Pereiro
Patterns of a frontend framework
- 512