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