Things I learned writing a frontend framework
Federico Pereiro
whoami?
- JS dev since 2010 (mostly backend, go figure)
- Founder @ altocode.nl
- Engineer @ bridgefund.nl
whyamihere?
Summarize the most important concepts I learned from building (and using) a frontend framework
(Framework: github.com/fpereiro/gotob)
0
What I'm aiming for
Obvious
New
Wrong
Demo time!
(with thanks to browserstack.com)
Try it yourself: altocode.nl/gotob
Why did you do that to yourself?
Why did you do that to yourself?
-
Interesting
-
Maybe useful in the real world
It all starts here
(Source: http://info.cern.ch/hypertext/WWW/TheProject.html)
It all starts here
<HEADER>
<TITLE>The World Wide Web project</TITLE>
<NEXTID N="55">
</HEADER>
<BODY>
<H1>World Wide Web</H1>The WorldWideWeb (W3) is a wide-area<A
NAME=0 HREF="WhatIs.html">
hypermedia</A> information retrieval
initiative aiming to give universal
access to a large universe of documents.<P>
Everything there is online about
W3 is linked directly or indirectly
to this document, including an <A
NAME=24 HREF="Summary.html">executive
summary</A> of the project, <A
NAME=29 HREF="Administration/Mailing/Overview.html">Mailing lists</A>
, <A
NAME=30 HREF="Policy.html">Policy</A> , November's <A
NAME=34 HREF="News/9211.html">W3 news</A> ,
<A
NAME=41 HREF="FAQ/List.html">Frequently Asked Questions</A> .
<DL>
<DT><A
NAME=44 HREF="../DataSources/Top.html">What's out there?</A>
<DD> Pointers to the
world's online information,<A
NAME=45 HREF="../DataSources/bySubject/Overview.html"> subjects</A>
, <A
NAME=z54 HREF="../DataSources/WWW/Servers.html">W3 servers</A>, etc.
<DT><A
NAME=46 HREF="Help.html">Help</A>
<DD> on the browser you are using
<DT><A
NAME=13 HREF="Status.html">Software Products</A>
<DD> A list of W3 project
components and their current state.
(e.g. <A
NAME=27 HREF="LineMode/Browser.html">Line Mode</A> ,X11 <A
NAME=35 HREF="Status.html#35">Viola</A> , <A
NAME=26 HREF="NeXT/WorldWideWeb.html">NeXTStep</A>
, <A
NAME=25 HREF="Daemon/Overview.html">Servers</A> , <A
NAME=51 HREF="Tools/Overview.html">Tools</A> ,<A
NAME=53 HREF="MailRobot/Overview.html"> Mail robot</A> ,<A
NAME=52 HREF="Status.html#57">
Library</A> )
<DT><A
NAME=47 HREF="Technical.html">Technical</A>
<DD> Details of protocols, formats,
program internals etc
<DT><A
NAME=40 HREF="Bibliography.html">Bibliography</A>
<DD> Paper documentation
on W3 and references.
<DT><A
NAME=14 HREF="People.html">People</A>
<DD> A list of some people involved
in the project.
<DT><A
NAME=15 HREF="History.html">History</A>
<DD> A summary of the history
of the project.
<DT><A
NAME=37 HREF="Helping.html">How can I help</A> ?
<DD> If you would like
to support the web..
<DT><A
NAME=48 HREF="../README.html">Getting code</A>
<DD> Getting the code by<A
NAME=49 HREF="LineMode/Defaults/Distribution.html">
anonymous FTP</A> , etc.</A>
</DL>
</BODY>
So how did we get here?
Page + State = App
1
Page + State = App
username: 'fpereiro' balance: 0.81 theme: 'dark'
<div style="background-color:black;color:white;font-family:monospace;padding:20px;">
<p>Welcome, fpereiro</p>
<p>Your balance is 0.81</p>
<button onclick="toggleTheme()">
Switch to light theme
</button>
</div>
UI + State = App
(Web page + State = Web app)
UI allows the user to:
1. See state: <p>Welcome, fpereiro</p>
2. Change state: <button onclick="toggleTheme ()"></button>
This is the entire game!
Generate HTML that allows the user to:
1) see state
2) change state.
2
Requirements
Static requirement:
HTML in sync with state.
Dynamic requirement:
User actions* on DOM elements change the state.
(the static is the hard one!)
Static requirement
requires us to use logic to generate HTML
- Variable substitution: username -> 'fpereiro' - Conditional: darkTheme ? 'background-color: black' : 'background-color: white' - Iteration: (lists, tables)
Static requirement
also needs to know
when to update the HTML
Immediate Mode
vs
Retained Mode
3
Immediate Mode
vs
Retained Mode
Frame
Update
Retained mode requires
client-side JS
(at least to update the existing HTML
which new HTML from the server)
Bonus 1: offline functionality
Bonus 2: avoid page refreshes
4
It is very convenient to use client-side JS to generate HTML
- Performance (no round trip)
- Separation of concerns
5
What is a view, really?
A view is a function that takes the state as its argument,
and which returns HTML
6
var View = function (state) { // Your working hours go here. return html; }
What is a view, really?
A view is a function that
takes certain parts of the state as its argument,
and which returns HTML
var View = function (statePart1, statePart2) { // Your working hours go here. return html; }
(And the output of the view is placed somewhere in the DOM)
My mental model for how any frontend framework works:
The Declarative Sandwich
7
The D'éclatative Sandwich
Views: f (s1, ...) => ...
Diff: compare old HTML & new, update
Events: when s1, s2 change, call the right views
The D'éclatative Sandwich
Ghostbusters!
Cleanup the apartment/hotel/NYC
On state change, who you gonna call?
Top of the sandwich: events
Why events? Because it's 1 -> n
(and n can be 0)
8
Bottom of the sandwich: diff
How can you get to B from A?
9
Bottom of the sandwich: graph diff
How can you get to graph B from graph A?
(quadratic problem!)
jQuery
vs
gotoB
(as told by the d'éclatative sandwich)
jQuery implements toggleTheme
Top of the sandwich:
var toggleTheme = function () {
var oldTheme = window.theme;
var newTheme = oldTheme === 'dark' ? 'light' : 'dark';
window.theme = newTheme;
updateHeader ();
updateSidebar ();
updateMainView ();
updateFooter ();
};
jQuery implements toggleTheme
Center & bottom of the sandwich:
var updateHeader = function () {
var theme = oldTheme === 'dark' ? 'light' : 'dark';
// Your working hours from 2009 go here.
$ ('#header').innerHTML (html);
};
gotoB implements toggleTheme
Top of the sandwich: var toggleTheme = function () { var oldTheme = B.get ('theme'); var newTheme = oldTheme === 'dark' ? 'light' : 'dark'; B.call ('set', 'theme', newTheme); };
gotoB implements toggleTheme
Center of the sandwich: var header = function () { return B.view ('theme', function (theme) { // My unpaid working hours go here. } };
gotoB implements toggleTheme
Bottom of the sandwich:
['O div {"background-color":"black","color":"white"}', 'O p', 'L Welcome, fpereiro', 'C p', 'O p', 'L Your balance is 0.81', 'C p', 'O button {"onclick":"toggleTheme ()"}', 'L Switch theme', 'C button', 'C div']
['O div {"background-color":"white"}', 'O p', 'L Welcome, fpereiro', 'C p', 'O p', 'L Your balance is 0.81', 'C p', 'O button {"onclick":"toggleTheme ()"}', 'L Switch theme', 'C button', 'C div']
The diff trick!
Myers diff algorithm:
linear performance for text
(The same that when you run `git diff`)
How? Flatten the graph into text.
What did you learn from IE6 compatibility?
What did you get from IE6 compatibility that is useful?
From The Art of console.log
to the Event Log
Questions!
Thank you!
fpereiro@gmail.com
Things I learned writing a frontend framework
By Fede Pereiro
Things I learned writing a frontend framework
Why and how I ended up writing a frontend framework
- 142