Auto Scroll
Select text to annotate, Click play in YouTube to begin
50 years ago humanity entered a new era when two heroic explorers took a small step into a new world it was a massive technolog technological achievement aside from the breakthrough itself it
spurred innovation in agriculture and medicine business and consumer products and in a strange way it brought us all a little closer together I'm talking of course about spreadsheets 1969 was the
year that Remmy Landau and Rene Pardo came together to form lampur technologies as well as being a play on their names LAN par is an acronym it stands for the language for programming arrays at random and it had a lot of the
features that we associate with modern spreadsheets most notably forward referencing or as we call it reactive programming and you've all experienced this but I'm going to show you anyway I have a spreadsheet here that tracks my
fruit purchasing habits and in columns B and C I have some values I've got some prices and I've got some quantities in column B I've got something more interesting I've got formulas the values of these cells are derived from the
values of other cells which means that if I buy another cantaloupe the spreadsheet updates automatically the subtotal and the total updates reflect the new inputs and the way that this works is the spreadsheet maintains a
dependency graph internally and we can visualize that we can click around and we can see the inputs and the outputs for each of these cells and we can even change a dependency graph by adding a new formula all of a sudden these cells now have two
outputs now this was important back in 1969 because computers weren't very fast then it's a lot more efficient to only update the things that have changed rather than re-rendering everything but lamp r wasn't destined to
become a household name it was too far ahead of its time and instead it became a footnote in the history of computers nowadays when we think about the first electronic spreadsheet we think about busy count Missi count was a huge deal
Steve Jobs credited busy count with it with the success of the Apple 2e pictured here the visicalc didn't use forward referencing it took a far more naive approach every time you changed the data in one of your cells you had to
go cell by cell updating all the others and it was pretty slow and clunky people didn't mind they didn't know any better but it meant that when Lotus 1-2-3 came along which did implement forward referencing spreadsheets suddenly became so much
more capable you could use them for more things and in a very short period of time busy count was all but forgotten my name is rich Harris I am a graphics editor at the New York Times and this talk is called rethinking reactivity it's a talk
about how we can apply the lessons of our forebears to build software that is a little bit less busy out and a little bit more Lotus 1-2-3 and I hope you enjoy it what is reactive programming
well this Michelle said yesterday there are as many definitions of reactive programming is there are reactive programmers so to make it simple I just stole his from his slides the essence of functional reactive programming is to specify the dynamic behavior of a value
completely at the time of declaration in other words reactive programming is all about beta flow it's all about tracking values through your application when the value changes your application should react we've talked about reacts a lot of
this conference already and we're going to talk about it a little bit more react is a miracle that changed everything whether you use it or not you've probably been influenced by the patterns that react introduced to the web programming community and since it was
released in 2013 the react team has crushed it year after year helping us solve problems that we didn't even know that we had but I think we can do better I think we can do a lot better and this talk is going to be about how now I know
that in the JavaScript community we tend to get a little bit uncomfortable when we criticize each other's work especially when I react contributor is sitting right in front of me sorry Brendan but I think it's really important for our collective growth and if you look back to the early days when
react first came out and react advocates were giving talks at conferences they were very very critical about the frameworks of that era and rightly so I'm going to continue in that proud tradition react was the first library
that used a virtual Dom and we're going to talk about how virtual Dom libraries work a lot of you might already know what this code does but let's talk through it anyway this is a simple react application that has a single component
called app and it has some local state account and name and it has two functions that change that state handle click which use this set count and handle input which use this set name and then at the bottom it returns a slice of
virtual Dom and as that that state changes that virtual Dom is regenerated each time and then reacts job is to reconcile what came before with what came after so let's see what this
process looks like first we look as a top-level element it was a div is still a div so we keep it then we need to look at the attributes that had a class name at but it still has a class name and so we keep it then we look at the children it had an h1 it still has an h1 so we
keep it then we look what's inside the h1 some text it hasn't changed we keep it look at the input this linen but we keep it the value hasn't changed we keep it look at a button it's still a button we keep it this text has changed so we
need to apply that to the Dom all that work to change a four to a five as engine is we should be offended all that inefficiency but that's not the bad part the bad part is that we keep running this code over and over again every time
there is any state change at all we need to read Eclair these functions that close over that local state the problem here is that react doesn't have any understanding of the values flowing through your app it treats it as a black
box in other words by any reasonable definition of the word react is not reactive or as john lindquist said react is a terrible name for react Jess
so is the virtual DOM fast no it's not fast is the virtual DOM fast enough well that's a more interesting question I work with data visualization and animation and I would say categorically no it is not but you don't need to take
my word for it we can ask the react core team the react core team don't think that the virtual Dom is fast enough and I know this because they've given us things like should component update react dot pure component use memo and use callback these are all abstraction
leaks that let you the programmer tell the computer that it doesn't need to worry about this subtree within your application in other words you're doing the computers job for it another sign that the virtual bomb isn't fast enough is when we start to develop
amortization strategies like concurrent mode which we'll talk about later so a few years ago I was thinking what can we do about this I want my users to have a fast application I want them to have a good
experience but I want to have the experience of using a declarative component framework like react and then it occurred to me maybe we're thinking about frameworks all wrong a framework doesn't need to be a thing that runs in
the browser frameworks are not tools for organizing your code there are tools for organizing your mind so given that maybe the framework should be a thing that runs in your build step instead or as
Kyle was enthusiastically saying yesterday compilers are the new frameworks and so I started a project called spelt and this is what it does it takes your declarative components and
then it turns it into the the efficient imperative low-level code that manipulates the Dom directly the interesting part here is changed how do we figure out what changed now
frameworks have solved this problem in different ways over the years old-school react with classes had this set state you pass it some new state it merges it with the old state and it triggers a rerender in modern react we
use hooks we call the second count function and then it updates its counterpart the count variable in old-school spelt we had something very similar to classical react this set
instead of this set state that also triggers a rerender and that's fine it works but the trouble is this set State and this set they're kind of verbose it's a lot of work to do just
play some state the thing that they have in common the problem that they have in common is that this as soon as your API depends on of this you introduce all sorts of constraints that are a little bit difficult to anticipate at first and
so we wanted to improve upon that let's take a step back how do we tell the computer something changed well there's actually a really good answer for this already we use an operator specifically we use the assignment operator we
declare a variable and then we say count equals count plus one or more concisely count plus equals one and to give credit where it's due view figured this out a long time ago in view you trigger
updates by assigning to properties this dot count plus equals one now the way that that works that run time is very different it requires that you have of this which has the problems that we were trying to avoid so that won't work for
us those are just the rules of JavaScript but we're a compiler we don't need to play by everyone else's rules so we are days away from the release of version three as felt or if you're watching this on YouTube hopefully has
already been released and spelled three is different spelt three moves reactivity out of the component API and into the language and I'm gonna show you what that looks like this is the same application as before implemented in
spell up here let name equals world instead of you state let count equals zero and then we've got some similar functions except this time we update this count variable by assigning to it
count plus equals one and I can type in here yeah like that click the button and the application that pays accordingly how does this work we go to the compiled
output and look at the code that the compiler has generated we'll see that it's actually left our code more or less intact it's just instrumented it with these calls to the invalidate function every
time you assign to a variable that is used inside your components markup it calls invalidate invalidates job is to say to the component this value has changed be aware of that when you update and by the way you need to update at the end of the event loop
we can actually get a little bit more efficient here we in spoke we don't need to use event handlers just to sync values between an input and a variable we can use the bind directive get rid of
that and we can make this an inline function and get rid of that and this
continues to work as before now an interesting thing about doing it this way putting JavaScript in our HTML instead of putting HTML in our JavaScript is that we can compile it to different outputs depending on the needs
that we have so far we've been looking at a JavaScript class that dates and manipulates the Dom but we can also do server-side rendering in SSL mode all we're doing is concatenated a string and
this is orders of magnitude faster than creating a component tree and then serializing it what this means is that if you do server-side rendering we spelled your AWS bills will be lower sell your product managers how you use
it it's just like any other JavaScript module you import it using the import keyword once your bundler is using the spelt plug-in this gets converted on the fly into a JavaScript class in the client you just call new app and then on
the server you have a different API because you're just serializing HTML it call app bot render but we're not reactive yet because in most components you will have state that is derived from
other state just like in our spreadsheet we have cells that are derived from other cells and the way that this is dealt with in react is well they don't need to because the code runs over and over again so if we have a list of to
do's here that can be done or not done and if we toggle them by clicking on them and if we can hide the ones that we've done already then we can generate that filtered list of hidden to dues or unhidden to do's using Const filtered
and it will just regenerate that each time and then down here at the bottom we have a list maps over the filtered array that's not ideal though because we might have this component inside another
component which means that that filtered variable keep getting regenerated and necessarily it's dependences might not have changed so in reacts what we do is we wrap that in use memo and we pass
a second document which the dependencies are filtered in our case to do's and hide them and what use memo does is it compares the variables in the second argument with the values in the previous run and if they're unchanged then it
knows that the return value is unchanged and it just gives you back the cached value and that's a bit more efficient but it's obviously more work for the developer is more boilerplate for us my
zoom out so that we can see the entire in out component this is the spelt equivalent it's a little bit leaner and this is something that we see quite a lot I've converted a lot of react components to spell components and typically what you find is the react
component is about 40% larger you have to type 40% more code to get it to work but the trouble here is that this doesn't actually work right I'm clicking on these these items but they're not toggling and that's because this code
only runs once console turd it's a con so it can't change we need to find some way of telling spelt that this is a reactive value that depends on other reactive values and for that we need to look for inspiration in the
outside world speaking of inspiration I find this guy pretty inspirational Mike Bostock is the creator of B 3 and is also the creator of observable is anyone familiar with observable here great this is a hugely popular tool in the date of
his world it's an interactive notebook generator it's similar to run kit or Jupiter in the Python world things like that he said it has a key difference rather than running your notebook from top to bottom it runs your code in
what's called topological order this is a fancy way of saying that if statement a depends on statement B statement B will run first regardless of the order in which they're declared in other words it functions like a spreadsheet well we
like spreadsheets maybe this is an idea that we could use in our components there's a blog post I like by an Australian developer called pulse devel what is reactive programming and it tells the story of some code
anthropologists from the year 2050 one looking back and struggling to understand the code that we wrote today VAR a equals 10 VAR b equals a plus 1 equals 11 well then we need to say 8 B equals a plus 1 again
the relationship between those two variables isn't fixed but in 2015 we have the Destiny operator Bobby destiny a plus one now if we change the value of a the value of B changes with it
they are bound it's explicit a part of a language could we use the Destiny operator in JavaScript well no we couldn't it wouldn't be syntactically valid and that would mean that we can use parses we can use linters all of the other things that are really valuable
but it turns out there is a piece of syntax that we can use and there's a piece of syntax that almost no one has ever encountered let alone used does anyone recognize this this is a thing called a labelled statement and it
doesn't really do anything most of the time in JavaScript so we on the spell team have co-opted it we've made it our own dollar b equals a plus 1 b is now bound to the value of a plus 1 and the
guy kyle simpson was trying to warn you about so we can add that to our original component just go down here it's a Const filtered and change it to dollar fill
third hey presto it's reactive that's kind of handy and we can go further we can say showing equals filtered length and start to have reactive values that
depend on other reactive values showing showing of two dues block length then now if I start to toggle these it updates automatically we're not limited
to declarations thank you we're not limited to declarations we can also have arbitrary statements in here so we can do this kind of thing which is very useful for debugging values as as they change alright so how does this
work well if we look at the j/s output from this and scroll down to where it's placing the reactive values it's taken
these statements and it's wrapped them in if statements if change I'd done or change to dues then we recalculate filtered and we invalidate filtered and you'll notice that because it's figured
out that showing depends on filtered it has to calculate filtered before it calculates showing that's the topological ordering that Mike Bostock was talking about and this is all
extremely fast for the browser to run this is very efficient code now a lot of people when they see this for the first time they're like I'm not sure about that that's a little bit magical and they don't mean magical in the good way
they mean the bad kind of magic ever no that creates the review j/s said well this isn't even JavaScript this is technically spell script and he's right we are abusing the language for fun and profit but I find it a little bit odd that 'even of all people is the one
saying this when he perhaps more than anyone else more even than michele has popularized the idea of assignments having side effects in JavaScript the distinction that he draws is between magic that happens in the browser and
magic that happens at compile time I think this is an arbitrary distinction I think if you draw a line between those two things then you're guilty of making the same mistake as people who used to say that templates and styles and JavaScript should be in separate files
even though they relate to the same component what matters is the functionality not where the functionality happens something I like to do when framework authors release benchmarks showing how
fast their framework is I had spelt true and then I tweaked out the result it is probably why I don't have many friends but it's so worth it because look this is an old one and it's showing the spelt is 35 times faster
than react and 50 times faster than view Dan on the react team thinks that this benchmark is meaningless and I kind of agree with him there is no point updating your application hundreds of thousands of times a second if your
refresh rate this 60 Hertz Dan thinks that we should be measuring user experience instead and I agree but he says that we should be but he doesn't say that we should be but Dan is talking
specifically about something called concurrent mode which is a feature that has come in to react soon and we need to talk about concurrent mode and the best way to do that is to use one of Dan's demos from a previous conference talk
many of you probably seen this this is from Jes confit Iceland if you haven't seen this talk I I really do urge you to do so it's an incredible talk that really changed a lot of people's understanding about how this stuff works so if we start typing
into the same pot this is react today now maybe you can't see what's going on here because you're in the audience you're not typing but for me this is a very frustrating experience because my keys aren't having an immediate effect I
can't see the input taking place so if we fire at the frustration meter and try it again right that's not that's no fun in a way that we have often tried to fix this is
using a technique called debouncing I can't type right with the bouncing nothing happens it's like stop typing and then everything updates all in one go and it means that the main thread stays unblocked and the apps there is
responsive but we don't get any feedback so that's not really a great user experience now concurrent modal async mode as it was referred to at the time is the best of both worlds yeah updates while I type
but if it gets too much to be too much then it will chunk up the work and yield back to the main thread so the frustration meter stays green the whole
time but you might notice that as we get more and more complex it starts to get a little bit slow to update the graph in the background this is the same application implemented in spell
it's a very different user experience I don't need to tell you whether that's better than the time slicing one it's obvious what's better and even in the frustration meter I mean you're welcome
to you'll probably get a better result than you do with react but inferno is still a virtual DOM mechanism and it's gonna have some of the same fundamental
bottlenecks I mean you're welcome to try and if you do it then I will add spell and I will tweet it out and we'll we'll compare notes so just to show you one
more time in async mode with with react and it's nice at first but it quickly gets a bit chunky now it's obviously better than react without time slicing
but it's not clear to me that it's better than just having a framework that doesn't have these bottlenecks in the first place the best way to deliver a good user experience is to be extremely fast
an analogy that I like to use is that of the internal combustion engine the internal combustion engine is a marvel of engineering modern ICS are incredible devices car companies have spent
millions of dollars eking out incremental gains over the years but then Tesla came along and said well what if we just changed the underlying assumptions what if we don't use fossil fuels at all well then we have a sit at
different set of constraints the average internal combustion engine has hundreds and hundreds of moving parts the electric motor inside the Tesla has two an internal combustion engine the best one in the world has an efficiency
of maybe twenty twenty-five percent the typical electric motor has an efficiency of 85% so car companies are spending all this money trying to eke out these incremental gains from the internal
combustion engine when actually the game has changed so a few different strategies for speeding up our code breaking it up into small chunks and moving it around like time slicing it doesn't really speed up your code it
might make it feel faster but it doesn't fundamentally change what's happening a few years ago everyone was trying to put their code in webworkers to unlock the main threat that way but no one does that anymore because it turns out it just doesn't work you can't move the code around into a different place and
expect it to have a meaningfully different result you can't even rewrite it in rust it turns out last month a guy called Nick Fitzgerald wrote a blog post about a
library that he's working on at the moment called Dodge Rio this is a virtual Tom implementation written in rust and compiled to wasm which is you know pretty mind-blowing and the blog post boasted of best-in-class performance
now when you say best-in-class performance it's like if you stand in front of the mirror and say Candyman five times I will appear behind you so I added spell 2 to this benchmark and sure
enough spelt house better than best-in-class performance actually the benchmark that it was using it was using set timeout for the scheduling which meant that most of the benchmark was just waiting for the browser's timer to
run so I changed the implementation to use promise resolution instead which gives us a better idea of the raw Dom update performance and we can see on the right that beats da geo by a larger margin now I am
bullish on rust and wasm in general I think there are a lot of good reasons why you would want to use rust for different parts of your application and I think that Nick has done some really incredible work here but the virtual Tom mechanism is fundamentally not going to
yield the best performance there's only one reliable way to speed up your code and that is to get rid of it be like Mary Kondo does this javascript spark
Troy now when people like me talk about performance who are often accused of having our heads in the clouds they're not being concerned with the real-world impacts of our applications and I find
that so confusing performance is the most real-world thing there is stone is a company in Brazil that makes points of sale systems that you put your credit card into and they tried building the interface for these devices with react
and with view and with a panoply of other frameworks and they couldn't get the results that they wanted it was just to slow the user experience was awful they built it with felt instead and it worked really well so now if you want to
talk about real world there are 200,000 these devices in the real world on the streets of Brazil running spelt these are low powered devices that don't have the same amount of memory and CPU
capacity that we have on a mobile device normally most lab in Russia is another example of a company that gets this they make applications for smart TVs and things like that and for them spell is the perfect fit it allows them to be
extremely productive without having to worry about performance and they're expanding svelte now into other areas of their business including a control panel for smart home automation this is a
trend that is only going to increase the mobile web is not the new frontier anymore the new frontier is the embedded web wearables Internet of Things Smart TVs in-car entertainment all that kind
of stuff and the traditional JavaScript first framework simply will not cut the mustard we need something more powerful but I'm done talking about performance I want to talk about some of the other benefits that svelt can give you first
that accessibility this is one of the things that developers all care about in theory but something that we habitually get wrong because it's kind of difficult like a lot of people working in development we
don't have visual impairments very often often we have you know good motor skills and so on and so it's difficult for us to appreciate how difficult using the web can be for some people and I think
that tools can really help us solve this problem if you write marker that is inaccessible spelt will yell at you here we've got an image tag with a source attribute but it doesn't have an alt attribute which means that someone using
a screen reader wouldn't know what was in this image or someone even on a slow connection who couldn't download the image in the first place and so down here I don't if you can see it at the back there is a warning is saying accessibility image element should have
an alt attribute and it's pointing to where the image is this is a warning that you would get in your terminal if you're using this in a conventional build setup so we can add an alt tag and the warning goes away it's still
compiled but we got a warning it will let you write market that isn't accessible but it won't respect you for it who works on a web application that doesn't have any styling no one okay
good so if styling is such a fundamental parts of the web that we build why do we use frameworks that don't deal with styles their unfinished spell on the other hand because we're basically
writing into a superset of HTML we can use style tags right inside our components we can have a paragraph tag that you that has a style from this P selector here we haven't had to use classes we haven't had to use complex
and namespacing schemes like man we're just using the paragraph selector and yet are nested component here even though it has a paragraph is unaffected by the styles in the parent component
and I can add some styles to this one as well P text transform uppercase right and it only affects the child component
not the top one the way that this works is it adds a computer-generated unique hash to the classes and then it applies that to both the markup and the styles another cool thing that we can do if a
framework understands both markup and styles is it can tell us when our declarations are not being used by the markup and it will actually just remove
it you can see that that style there isn't reflected in the CSS output that it gets written to disk but it also gives us a warning so that we can remove that this solves the problem that so many of us have experienced where you're
terrified of removing any of the styles from your style sheets because you don't know what they affect right we've all experienced this at some point CSS nsj is designed to solve this problem and it does so pretty well you
can use CSS and J's misspelled but you probably won't need to because it has file handling built into the framework something else that we can do with spelt is add transitions if I toggle this
visible boolean which is literally just that then the element doesn't disappear and reappear and doesn't a snap into place instead it transitions out gracefully this is really good for like
notifications and things like that and the way that that is done is just by adding this transition fly directive to the element and then giving it some some
arguments there's an object literal with with one property twice and that's just imported from this svelte transition package here now if I toggle this really quickly you can see that it actually reverses the transition smoothly and
puts it back into the place where it's supposed to be which is kind of difficult to do with with some frameworks interestingly though this isn't done with JavaScript when the state changes spell will calculate a CSS
animation and then it will apply that to the element because CSS animations run off the main thread this is more performant and more battery friendly particularly on mobile devices than if you're doing the animation inside JavaScript and we can get pretty funky
with this stuff we can create our own custom transitions this is a a spin function which takes a node and it takes some arguments optionally and then it returns an object with a CSS method
which takes T a value between 0 and 1 0 is fully off the screen one is fully on the screen and it returns some CSS so this kind of like JavaScript in CSS and then smoke will take that compile it to
a CSS animation and then it will play it on the element so let's import spin from spin s and then down here we'll replace
that with in spin and out fade and now when we play it end you can go crazy and we can use easing functions that aren't available in CSS normally all that kind of stuff and yet it's all done
completely in CSS in a nice performant way and we can get pretty complex with that stuff I'm not going to show you all the code for this example but I do want to show you conceptually what's happening we've got
a to-do list with two views of it we've got one that is the two dues filter by the ones that have not been done and then beneath it we've got one that's filtered with all of the dues that
happened then and as we toggle these they move from one list to the other but that's quite unsatisfying because that's not how objects behave in the real world our brains don't don't like it when
things just disappear and reappear elsewhere on the screen what we run is for these things to move gracefully to their new position that helps us understand what's actually happening to the things inside the application and so
I'm going to take this label here and I'm gonna add some directors to it and now when I toggle these they move out of the way cleanly like that and again this
is all done with CSS and not JavaScript this is the kind of feature that most frameworks don't include and the reason for that is because in the JavaScript world with very conscious of bundle size
often you go to a frame rate marketing page and they will have the size of the framework right there on the front of the page saying look with a three kilobyte alternative to react in finance case and that's good because it's better
if we can deliver less JavaScript to our users but it means that we're restricting the number of features that we can include in our frameworks but spelt is a compiler it doesn't have the same constraints if you're not using a
particular feature like transitions or bindings then we don't need to include the code that makes that feature possible so you're always going to get the minimal subset of the frameworks features it means that we've decoupled
feature set from file size and that lets us the spelt team be far more expansive and the kinds of features that we consider worth including in the framework and that's good for developers because developers has developers we
want all the features but we just don't want to pay for the ones that we're not using and what's good for developers is ultimately good for users so spell is a low-level component
framework and you can use it to build pretty complex applications but at some point you will need something a little bit more more well-rounded and so we have a project called sapper is a companion project just felt if you're
familiar we've react and you've used Next and Gatsby those are frameworks that take the component framework and turn it into an application framework so that you get routing and code splitting server-side rendering and all the
features that make a modern web application easy to develop but performance sapper is like that except with much less JavaScript because it's spelled you get automatic server-side rendering you get automatic code splitting all of that good stuff there's
a community project called spelt native which will probably become an official project at some point but it's still quite new it's a community driven project based on native script view and it allows you to build iOS and Android
applications using spelt and beyond that something that I really want to work on is spelt GL which would be like 3j s but spelter you would use the same kind of declarative style to describe a
three-dimensional scene graph and then it would get compiled to the low like the low-level underlying draw calls that would make that possible without all of the the added bloat of a conventional
web GL library so in conclusion spreadsheets are pretty cool and we should be more like them there's actually one more thing I want to say about spreadsheets and that is how accessible they are my wife is not a
programmer and after being with me for 15 years she does not want to become a programmer but she can do some incredible things with spreadsheets when I look over the shoulder when she's working my mind is blown at the amount of value contained in businesses around
the world in these humble spreadsheets wouldn't it be wonderful if the tools that we used to build the web were as accessible the spreadsheets are and that is one of spelts overriding goals is to
make web development accessible without sacrificing power for power users my friend Eliza working at Spotify and was using spell to work on a project and her
project manager was able to come over and work with them manipulate the component code directly in a way that would have been more intimidating it was a javascript file when all different people with different
disciplines and different skill sets can crowd around the same laptop and work on the same piece of code simultaneously that's when great things happen so I hope that one day we'll be able to look back it's felt and say that in a strange
way it brought us all a little closer together thank you so much for listening
End of transcript