DEV Community

Cover image for What's New in Svelte 4: Performance Boosts and Streamlined Development
Pierre Bouillon for This is Learning

Posted on

What's New in Svelte 4: Performance Boosts and Streamlined Development

On the 22th of June, Svelte has announced its new major release.

Even if it is presented as "mainly about setting the ground for these future improvements", it also bring its share of improvements along with the rework of some of their showcase websites.

If you're more a listener than a reader, this release has also been recorded on Svelte Radio Live

Table of Content


Performance Enhancements

📉 Drastic reduction of the Svelte package

For this release, Svelte sure has lost some weight!

The overall size of Svelte dropped from 10.6 MB to 2.8MB, almost a 75% size decrease.

As its dependencies dropped from 61 to 16, the additional packages needed to run Svelte also have been reduced, also reducing the number of dependencies of SvelteKit.

This reduction brings some nice side effects such as a faster REPL experience, a faster experience on the interactive website and a much faster execution of npm install (of whatever package manager you might be using).

As of this release, Svelte sure is now!

🚿 Improved Hydration

Along with this drop in the package size, Svelte also lighten the code it generates for hydration.

As an example, the code generated for the SvelteKit website has been reduced from 126.3 kB to 110.2 kB, almost 13%.

Improved Developer Experience

🎭 Transitions Scope

Transitions are now local by default.

This prevents them from being global by default and thus risking to interfere with others, resulting in a collision of your transitions during page load.

🧱 Web Components Authoring

Creating a Web Component in Svelte has been pretty easy:

<svelte:options tag="my-component" />
Enter fullscreen mode Exit fullscreen mode

However it also has been limiting for more advanced cases such as controlling whether or not to reflect updated prop values back to the DOM, disabling the shadow DOM, etc.

Svelte 4 makes the authoring experience of Web Component way smoother by shifting its configuration into a dedicated customElement attribute of svelte:options.

This attribute takes a number of options that helps you configure your Web Component:

<svelte:options
  customElement={{
    tag: 'custom-element',
    shadow: 'none',
    props: {
      name: {
        <!-- 👇 Reflects the updated value back to the DOM -->
        reflect: true,
        <!-- 👇 Reflects the value as a number -->
        type: 'Number',
        <!-- 👇 Name of the attribute -->
        attribute: 'element-index'
      }
    }
  }}
/>

<script>
  export let elementIndex;
</script>

...
Enter fullscreen mode Exit fullscreen mode

🛡️ Stricter Types

Stricter types are now enforced for createEventDispatcher, Action, ActionReturn and onMount:

  • createEventDispatcher now looks for the correctness of the provided parameters regarding their type and number and throws the associated errors:
import { createEventDispatcher } from 'svelte';

const dispatch = createEventDispatcher<{
  optional: number | null;
  required: string;
  noArgument: never;
}>();

// Svelte version 3:
dispatch('optional');
dispatch('required'); // Detail argument still omitted
dispatch('noArgument', 'surprise'); // Detail argument still provided

// Svelte version 4 using TypeScript strict mode:
dispatch('optional');
dispatch('required'); // Error, missing argument
dispatch('noArgument', 'surprise'); // Error, cannot pass an argument
Enter fullscreen mode Exit fullscreen mode
  • Action and ActionReturn now have a default parameter type of never if Action has no generic type provided:
const untyped: Action = (node, params) => {
  // Now an error as `params` is expected not to exist
}

const typed: Action<HTMLElement, string> = (node, params) => {
  // `params` is of type string
}
Enter fullscreen mode Exit fullscreen mode
  • onMount now requires its return a synchronous function as an asynchronous one might lead to bugs if the callback is expected to be called on destroy, since this is the case only for synchronous functions:
// ❌ `cleanup()` is not called due to the function being async
onMount(async () => {
  const bar = await foo();
  return cleanup();
});

// ✅ `cleanup()` will be called
onMount(() => {
  foo().then(bar => /* ... */ );
  return cleanup();
});
Enter fullscreen mode Exit fullscreen mode

Updated Websites

📝 Tutorial Website

The tutorial has been reworked for a better user experience:

Former Newer
Legacy Tutorial Newer Tutorial

The design still is the same: a side panel with text and instructions with a code editor on the right to do the exercise.

However, some neat things were improved such as seeing the file structure on the side, reducing the number of elements in the navbar and a better navigation between sections. It also feature a dark mode!

The tutorial now lives on https://learn.svelte.dev while the former is reachable at https://svelte.dev/tutorial/basics

📚 Svelte Website

The Svelte Website also had a rework:

Former Newer
Legacy Page Newer Page

The pages have been split, mobile navigation has been improved, the TypeScript documentation has been enhanced and a dark mode has also been released.

As of now, the SvelteKit website has not yet been updated but a rework to offer a similar experience is currently ongoing.

Migration Guide

This release is shown as a step towards Svelte 5 and not a very impactful one.

In order to upgrade from Svelte 3 to Svelte 4, the team has updated their migration tool and it should not take much more than running the following command:

npx svelte-migrate@latest svelte-4
Enter fullscreen mode Exit fullscreen mode

Please note that the minimum version requirements have been updated and you will need:

  • NodeJS 16 or higher
  • SvelteKit 1.20.4 or higher
  • TypeScript 5 or higher

More details about the requirements are listed in the migration guide

What to Expect From Svelte 5

Almost no information about what is upcoming in Svelte 5 has been shared so far.

However, as Svelte is heavily tied to ESLint, so is its package size. With the current rewrite of ESLint, by the time Svelte 5 is released, its size might drop by over another 50%.

As Svelte is focused on developer experience and efficiency, the changes we will probably see a number of improvements in those areas, as stated in their blog post:

Svelte 5 will bring major new features and performance improvements to Svelte


I hope that you learn something useful there!

Top comments (13)

Collapse
 
ting profile image
Ting

Been looking into svelte and solid, how does Svelte 4 compare to Solid with all these new improvements?

Collapse
 
pbouillon profile image
Pierre Bouillon

I wish I could answer you precisely, however si do not know SolidJS (nor Svelte but I’m working on it) enough to give you a proper feedback on this

I guess that the core features and performance are still the same (so far, before Svelte 5) but that at least the size of Svelte 4 is not a pain point anymore!

Collapse
 
ting profile image
Ting

No worries, thank you for making the post! Maybe I will try them out and share my experience as a total noob :)

Collapse
 
bhendi profile image
Jyothikrishna

Hello @ting 👋. Welcome to Dev community

Collapse
 
ting profile image
Ting

Thanks!

Collapse
 
dimitrim profile image
Dimitri Mostrey

Thanks for the article. Svelte is on my radar. Upgrading my vast Laravel website to LiveWire and alpinejs. And Tailwind... A stepping stone towards an API. A lot to do but worth it. So I hope.

Maybe the SPA will be Svelte based. Alpinejs has a similar code structure. I'll wait for Svelte 5.

Collapse
 
pbouillon profile image
Pierre Bouillon

Thanks for reading and your feedback!

I also kept an eye on Svelte, to see if it can still prove relevant among the other giants of JS Frameworks

So far they are still proposing some interesting features and updates seems to stay relevant and in the same spirit

I hope that Svelte 5 will be as exciting as they are implying!

Collapse
 
artydev profile image
artydev • Edited

" 2.8MB" small ?

Look at this : VanJS

devtoVanJS

VanJSIfYouMissJSX

Here is a basic Counter , no bundling, directly in browser Counter

import van from "./van.js"
const {button, h1, div} = van.tags


//VanJS
// Create a new State object with init value 1
const counter = van.state(1)

let Counter = div (
  h1("VanJS Counter ", counter),
  button({onclick: () => counter.val++}, "INC")
)

van.add(document.body, Counter)

Enter fullscreen mode Exit fullscreen mode

regards

Collapse
 
thiagolino8 profile image
Thiago Lino Gomes • Edited

2.8M is the size of the compiler, the javascript generated and sent to the browser in an app with a simple counter like the one in your example is 2.04KB
But with a much more convenient and scalable syntax
example

Collapse
 
pbouillon profile image
Pierre Bouillon • Edited

Their package is indeed smaller than it was, and I’m looking forward to Svelte 5 for an event smaller bundle

Still, there is of course tools that will be lighter for sure, be it VanJS, another tool or even raw HTML/JS

I guess that, as everything in tech, this is a matter of compromise and choosing the most suitable tool for your usage

However I didn’t knew about VanJS, glad to have learn something new, thanks for sharing!

Collapse
 
artydev profile image
artydev

You are welcome :-)

Collapse
 
v3ss0n profile image
Phyo Arkar Lwin

Great one. Better than official svelte4 launch post. It was missing a lot of information.

Collapse
 
v3ss0n profile image
Phyo Arkar Lwin

Thanks , the original svelte4 launch blockpost was lacking information .
This is a lot better.