A talk about Svelte. By Rich Harris, creator of Svelte and graphics editor at the New York Times.
Notes
Lanpar Technologies created a spreadsheet program which was the first example of forward referencing, AKA reactive programming. When a cell is updated, all the cells that depend on those cells are also updated.
Definition
The essence of cuntional reactive programming is to specify the dynamic behaviour of a value completely at the time of declaration.
Heinrich Apfelmus
React
React was the first library to use the Virtual DOM. Your code updates the Virtual DOM and then React updates the actual DOM based on that. It does a deep tree comparison between the old and new virtual DOM.
React doesn’t have any understanding of the valeus running through your app. It is not Reactive.
This is slow and to help React has methods such as shouldComponentUpdate
, React.PureComponent
, useMemo
and useCallback
, which break the abstraction.
Svelte
Rich wanted to use the declarative component framework, but without the overhead.
Frameworks are not tools for organising your code, they’re tools for organising your mind.
It turns your components into efficient low level to update the UI.
How do we tell if something has changed?
In React (with classes), you call this.setState
.
In React (with hooks), you call setCount
or whatever it’s called.
In old Svelte we use this.set
.
The this
is a problem, it introduces constraints to your API.
How do we tell the computer something changed?
You look for the =
operator?
Svelte 3
Reactivity is moved into the language.
<script>
let name = 'world';
let count = 0;
function handleClick() {
count += 1;
}
function handleInput(event) {
name = event.target.value;
}
</script>
<h1>Hello {name}</h1>
<input value={name} on:input={handleInput}>
<button on:click={handleClick}>
Clicks: {count}
</button>
The compiler adds invalidate
calls to assignments.
We can use the bind
directive, so that the input
becomes:
<input bind:value={name} >
By putting JS in HTML (instead of HTML into JS) we can create different output formats - eg, server side rendering.
To use it:
import App from './App.svelte';
new App({
target: document.querySelector('main'),
// ...
});
Full Reactivity
We’re not yet reactive - we need state that is derived from other state.
React doesn’t care about this because they rerun all the code (unless you use useMemo
).
Inspiration from the Observable library, which is like Jupyter but it automatically runs the dependent cells. The post What is Reactive Programming (see end) creates the destiny operator which automatically updates a value if the value it is calculated from is updated.
There is some syntax that we could use (we don’t want anything too wacky because otherwise linters won’t work on our code).
let a = 10;
$: b = a + 1;
This is a labelled statement in JavaScript, which is rarely ever used.
In Svelte this binds b
to the value a + 1
.
React’s Concurrent Mode
It’s painful when you’re typing something and because of the page updating you get input lag. This can be solved with debouncing, nothing updates until you stop typing. React’s concurrent mode updates while you’re typing, but if too much is going on the main thread (handling input) takes precedent over the background one (updating the UI).
In the example given Svetle works fine in single threaded mode. (The point of this part was to show that even with React’s attempts to speed up performance, single threaded performance matters.)
There’s more talk about Svelte having amazing performance (with examples such as Stone and Mustlab).
Accessibility
The Svelte compiler will warn you about accessibility issues. (I’m not quite sure why this is a big deal - it’s nothing new.)
Scoped Styles
Svelte files contain styles that are scoped to the file. The compiler adds a unique hash to the style. The compiler can also eliminate styles that aren’t used.
Transitions
Svelte contains transitions, using for example transition:fly={{y: 20}}
.
These are turned into CSS animations (off the main thread, better for performance and battery life).
There’s a fancy example of items being moved between lists and animating nicely.
Since Svelte is a compiler, you only pay for what you use.
Beyond Svelte
Sapper is a NextJS/Gatsby style framework - it contains automatic Server Side Rendering and Code-Splitting.
Svelte Native can be used to build iOS and Android applications.