Introducing Svelte: The Compile-Time Non-Framework

Arpad Borsos speaking at viennaJS in February, 2017
407Views
 
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

Rollups creator Rich Harris has started a new project called svelte. In this talk we will describe the reasoning behind the project, show some examples and discuss possible future directions.


Transcript


Hello. I'm Arpad and I will talk about Svelte, which is a kind of compile-time client-side framework, and before I get into how Svelte came into existence, let's take a look back into the dark ages of web development. Like 15 years ago, where we had almost...or absolutely no Javascript in our browsers. We had, like plain HTML. Plain mark-up that the servers had mostly written and PHP generated, and we had these fancy table-based layouts and everything. It was awesome. But all joking aside, at some point, there was the requirement to do some inter-activity, and well, we maybe put some little function calls into on-click handlers defined right in the mark-up. Or we selected some elements by ID and attached some eventlessness to do some rudimentary stuff with JavaScript, but it was hard to do. And at some point there was this thing called jQuery, which made is a lot easier to more easily create elements dynamically, and attach them, and listen to events, and so on, and so on, and so on. But it was still a bit hard to do and complex and if you wanted to do really complicated apps with jQuery or binding events and stuff manually, it really got out of hand really quickly. So then with the requirements of single-page apps, and more dynamic web pages, there was this requirement to make development easier, and one of the things people wanted is to have templates which declaratively define how your page should look, given a certain data you wanted to display. And while the really early systems, this templating were basically similar to what the server did on the server-side, it would just spit out aesthetic HTML mark-up string and you would just throw it in via innerHTML, which was okay. It worked, but you still had to attach events manually and so on, and so on. And you also had the problem of a browser-internal state, like for example your cursor position, your scroll position, things like this which got lost when you just changed the whole complete DOM via innerHTML. All right. So we wanted to solve this thing and suddenly this thing, React, came along and brought with it something called the virtual DOM, which basically means that instead of rendering to a string, you render to a JavaScript data structure. And by some kind of magic, this data-structure got updated to the real DOM and only the minimal changes to the DOM were made, because there was this big mantra that touching the DOM is really, really slow. You should avoid it at any cost. But there's also tradeoffs to doing too much magic and the problem with these huge frameworks is that the page bundles themselves get really, really big and also the run time gets really, really slow. This is a actually a recent post by some Google performance engineers in the Chrome team. They did a few benchmarks of a few popular pages and also benchmarking pages. And they came to the conclusion that between 22% maybe up to even 50% of the whole work the browser has to do it actually parsing and compiling the JavaScript bundles you give to your browser, which is a lot of overhead. And remember, JavaScript is the most compiled language in the world because every single time you refresh a page, JavaScript gets downloaded, gets parsed, gets compiled, and so on, and so on. The browser has to do a lot of things in the background, which gets really slow, especially on slow devices like phones. So, for example, at the company where I work, pagestrip, our bundle is like around 700K to 800K of minified JavaScript. And there are some techniques you can do to mitigate this code-splitting. But depending on your use-case, it might be a lot harder to do than you think. So I'm a really performance conscious developer, and everything I do, I really do care about performance and sometimes I'm really sad and depressed because I have to do things which I know are really, really bad. But I have to do them anyway. And I do give a lot of talks, especially here in ViennaJS about JavaScript and performance, and almost a year ago, I had this talk with the title, <i>JS does not offer zero-cost abstractions.</i> And I also gave the talk a second time at the Vienna LinuxWochen last year, which had a few more slides, and one of those slides was this. This was like a vision of me that... what if React was different? What if instead of doing all that stuff at run time, it just created createElement, createdTextNode, and so on, and so on, at compile time and generated code similar to this one, which on a render office would just update a single property with a single line of code. And this was like my dream of how front-end frameworks should really work instead of having 100 to 500 kilobytes of JavaScript code doing tons and tons of stuff to actually draw something on the screen. So well, I did some experiments, but I'm a really lazy, lazy guy and well, I never got anywhere with the experiments I did. But then some day, I browsed on GitHub, and one of the people I follow on GitHub is Rich Harris, who is famous for rollup. Who knows rollup here? Yeah. Yeah. For everyone who doesn't know rollup, check it out. It's really, really awesome. It's basically a bundler that's really slims down your JavaScript to really, really compact code. But anyway, Rich Harris open-sourced a new project, and I was really excited, so what is it? It's Svelte, the magical disappearing UI framework, which turns your templates into tiny framework-less vanilla JavaScript. So wasn't this exactly what I had in mind, what I wanted to do a year ago? So there is also this link you can follow, which is like an introductory post of the reasoning and the ideas behind Svelte. Basically what I just told you about the VAP getting more complex and JavaScript bundles getting bigger and so on, and so on. So Svelte is here to change this. So let's go for a demo. This is, Svelte actually has a REPL. Wait a second. Get this, ALT+shift. Shows what a command... [inaudible]. Okay. [inaudible]. Okay. [inaudible]. Yeah, but anyway. You have this link, and this is just a REPL where you can post some kind of code here and it will give you the output. Like if you just have some text, then the compiler will generate this code for you, which creates a text node here, inserts the node on mount, the output is nothing, and then on tear-down, it just detaches the node. Let's do something a little more interesting. Here in this small window, we have defined some data we want to display, so we can just do it here. [inaudible] this strange Mac keyboard. - [Male] [inaudible]. - Yeah, yeah. I got it. I got it. So, Svelte has a syntax inspired by handlebars or a mustache, so this double-curly syntax for variable interpellations. And you can see it just puts our output on the screen. And the code it generated for this is also really simple. Basically, the only thing that changed is we do a property lookup here, and the update function actually updates the content of the text node. So of course, we can do more complicated things than this. There's a few examples here and there's also a guide with a lot more examples there, if you follow along. Let's look at some of those examples. Of course, we have If blocks, very simple stuff. And the output gets a little bit more complicated, so we have main fragments, which is rendered, which is inserted and updated, depending on the variables we pass in, which is tore down and then we have both of the branches as separate so-called blocks of fragments here. So this is like the S branch and this is code for the If branch. And, yeah. You can also do each blocks and a lot of other stuff which is really nice. So, but there are also some things I personally do not like that much about it, and here in the examples I only showed you half of the artwork that it generates, so let's go back to a little, simple example, do just some text. And this is the main template rendering function here, but if you scroll down Svelte actually generated some more stuff down here, which goes on, and on, and on. And, yeah, and a few helpers. But Svelte comes with some state-management of its own, and some event-management of its own, which I personally think you could do without. As my example, if you have a find-component, like some component, and you can bind special events over this syntax to it. So for example, on foo, you want to... I don't know, do something. What did it do? I don't know. - Smaller case, I think. - Hmm? - [inaudible] smaller case, I think. - No, no. It's supposed to be in upper case, but then I did something wrong, I think. But this is a nice guide, which gives a lot more examples. Which also shows you the whole component APR, and the template syntax, and also the behaviors and custom events that you can do. So for example here, we will define a foreign component that you import from a different file, and you can actually bind some custom event on it. And that's why Svelte actually needs some...a little bit of boilerplate code. But, to be honest, I think you could have just passed a function as props and call it a function, which would have gotten rid of all this custom event handling stuff. And the other code that Svelte generates in the output here, like Get, and Observe, and things like this, these are functions for state-management, which is also kind of redundant if you want to do your own state-management, via things like MobX, or Redux, or something like this. And what Svelte also has is its own stack sheet implementation, which looks kind of like this. You just have a style with some class name defined, and you use this class name inside your template function, and what it will do, it will just attach this fragment of style with some added selectors to your CSS, to a DOM. And the elements which match this special selector, this unique selector, will get this style applied. Which works really, really fine, but maybe you would like to have your own styling solution for whatever reasons. But the reason Svelte comes with all these batteries includes for the phase, it tries to be a complete framework. So you could use Svelte for everything, for a whole... to do NBC example, or something like this, or like DbMon benchmark or something, and you could do everything inside your Svelte templates, without having to write any kind of other code, without having to rely on any kind of other libraries and so on, and so on. So that's basically it. Try it, if you like. Use the REPL. It's online, you can just try simple stuff without having to install anything and otherwise, Svelte has two different compile modes. So the things you see here, the output it generates here, is like the code it would generate for the client-side. It also has a second compiler option, which can generate code for server-side rendering. So it will basically just generate a bunch of string concatenation for your whole template. That's all the server-side compiler will generate. So you can also use to it server-side render your app, and also the client's server [inaudible]. So, yes.