From 3a63862844f1b1729dbc0db2044b88e50cf8455b Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Wed, 20 Dec 2023 16:31:41 -0800 Subject: [PATCH 01/15] docs: add performance page --- .../docs/40-best-practices/05-performance.md | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 documentation/docs/40-best-practices/05-performance.md diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md new file mode 100644 index 000000000000..3c38eda075b8 --- /dev/null +++ b/documentation/docs/40-best-practices/05-performance.md @@ -0,0 +1,70 @@ +--- +title: Performance +--- + +SvelteKit strives to provide a highly performant experience by default. However, when building any web application you will always need to put in some effort to maintain fast speeds. Some tips are included below. + +## Measuring + +For deployed sites, you can measure your page's performance with [Google's PageSpeed Insights](https://pagespeed.web.dev/). More advanced users may also like to use [WebPageTest](https://www.webpagetest.org/). + +You can also use your browser's developer tools to evaluate your page's performance and identify areas of opportunity. Check out some of the resources below if you're not already familiar with your browser's developer tools: + +* Chrome - [Lighthouse](https://developer.chrome.com/docs/lighthouse/overview#devtools), [Network](https://developer.chrome.com/docs/devtools/network), and [Performance](https://developer.chrome.com/docs/devtools/performance) tabs in the developer tools +* Firefox - [Network](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/) and [Performance](https://hacks.mozilla.org/2022/03/performance-tool-in-firefox-devtools-reloaded/) tabs in the developer tools +* Edge - [Lighthouse](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/lighthouse/lighthouse-tool), [Network](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/network/), and [Performance](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/evaluate-performance/) tabs in the developer tools +* Safari - [enhancing the performance of your webpage](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/Web_Inspector_Tutorial/EnhancingyourWebpagesPerformance/EnhancingyourWebpagesPerformance.html) + +### Instrumenting + +If you see in the network tab of your browser that an API call is taking a long time and you'd like to understand why, you may consider instrumenting your backend with a tool like [OpenTelemetry](https://opentelemetry.io/) or [Server-Timing headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing). + +## Multimedia + +### Images + +Typically the most impactful area of opportunity is optimizing your images. Svelte provides an offically-supported image optimization package. Please see the [images](images) page for more details. Additionally, you may use Lighthouse for identifying images needing optimization. + +### Fonts + +Preload fonts when possible with the appropriate by calling `resolve` with the appropriate `preload` option value in the [`handle`](hooks#server-hooks-handle) hook. Also ensure you've set the [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) option appropriately in your CSS. Additionally, you may reduce the size of font files with [subsetting](https://fonts.google.com/knowledge/glossary/subsetting). + +### Videos + +Video are very large files and so extra care should be taken to ensure that they're optimized: + +- Compress videos with tools such as [Handbrake](https://handbrake.fr/). Consider converting the videos to HTML5 video formats such as WebM or MP4. +- [Lazy load](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading) videos located below the fold. +- Strip the audio track out of muted videos using a tool like [FFmpeg](https://ffmpeg.org/). + +## Code size + +### Svelte version + +We recommend running the latest version of Svelte. Svelte 4 is significantly smaller and faster than Svelte 3 and Svelte 5 is very significantly smaller and faster than Svelte 4. + +### Packages + +[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are adding the most size to your site. You may also find areas of opportunity manually inspecting the build output with [`build: { minify: false }`](https://vitejs.dev/config/build-options.html#build-minify) or via the network tab of your browser's developer tools. + +### External scripts + +Try to minimize the number of third-party scripts running in the browser. E.g. instead of using JavaScript-based analytics tracking, you may wish to use server-side implementations. Many hosting providers with SvelteKit adapters offer such functionality such as [Netlify](https://docs.netlify.com/monitor-sites/site-analytics/), [Cloudflare](https://www.cloudflare.com/web-analytics/), and [Vercel](https://vercel.com/docs/analytics). + +You also may consider running third-party scripts in a webworker with [Partytown's SvelteKit integration](https://partytown.builder.io/sveltekit). + +### Selective loading + +Code imported via static import will be automatically bundled into your page's code. If there is a piece of code you need only when some condition is met, use a [dynamic import](https://vitejs.dev/guide/features#dynamic-import). + +## Hosting + +Your frontend should be located in the same data center as your backend for minimal latency. For sites with no backend, many SvelteKit adapters support deploying to "the edge", which means your code will be distributed globally so it can run next to your users. Some adapters even support [configuring deployment on a per-page basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN — the hosts for many adapters offered by SvelteKit will do this automatically. + +Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small files for improved cacheability, which results in excellent performance, but this does assume that your files can be loaded in parallel with HTTP/2. + +## Further reading + +For the most part, building an performant SvelteKit app is the same as building any performant web app. You should be able to apply information from the following general performance resources to any web experience you build: + +- [Core Web Vitals](https://web.dev/explore/learn-core-web-vitals) From 4396b5006a01241c123411e638e1a9c90b8c4717 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 21 Dec 2023 08:28:04 -0800 Subject: [PATCH 02/15] address minor feedback issues --- documentation/docs/40-best-practices/05-performance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 3c38eda075b8..b22d5e996c00 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -41,7 +41,7 @@ Video are very large files and so extra care should be taken to ensure that they ### Svelte version -We recommend running the latest version of Svelte. Svelte 4 is significantly smaller and faster than Svelte 3 and Svelte 5 is very significantly smaller and faster than Svelte 4. +We recommend running the latest version of Svelte. Svelte 4 is significantly smaller and faster than Svelte 3. The Svelte 5 preview is very significantly smaller and faster than Svelte 4 — though we don't recommend users upgrade to this version yet as it's not currently production ready. ### Packages @@ -65,6 +65,6 @@ Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous sm ## Further reading -For the most part, building an performant SvelteKit app is the same as building any performant web app. You should be able to apply information from the following general performance resources to any web experience you build: +For the most part, building a performant SvelteKit app is the same as building any performant web app. You should be able to apply information from the following general performance resources to any web experience you build: - [Core Web Vitals](https://web.dev/explore/learn-core-web-vitals) From b1328d7fd0cd461058c891792198a311a0a02468 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:20:20 -0800 Subject: [PATCH 03/15] lazy loading and waterfalls --- .../docs/40-best-practices/05-performance.md | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index b22d5e996c00..eb6ffeb55f3b 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -19,17 +19,19 @@ You can also use your browser's developer tools to evaluate your page's performa If you see in the network tab of your browser that an API call is taking a long time and you'd like to understand why, you may consider instrumenting your backend with a tool like [OpenTelemetry](https://opentelemetry.io/) or [Server-Timing headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing). -## Multimedia +## Optimizing -### Images +### Multimedia + +#### Images Typically the most impactful area of opportunity is optimizing your images. Svelte provides an offically-supported image optimization package. Please see the [images](images) page for more details. Additionally, you may use Lighthouse for identifying images needing optimization. -### Fonts +#### Fonts Preload fonts when possible with the appropriate by calling `resolve` with the appropriate `preload` option value in the [`handle`](hooks#server-hooks-handle) hook. Also ensure you've set the [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) option appropriately in your CSS. Additionally, you may reduce the size of font files with [subsetting](https://fonts.google.com/knowledge/glossary/subsetting). -### Videos +#### Videos Video are very large files and so extra care should be taken to ensure that they're optimized: @@ -37,32 +39,54 @@ Video are very large files and so extra care should be taken to ensure that they - [Lazy load](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading) videos located below the fold. - Strip the audio track out of muted videos using a tool like [FFmpeg](https://ffmpeg.org/). -## Code size +### Code size -### Svelte version +#### Svelte version We recommend running the latest version of Svelte. Svelte 4 is significantly smaller and faster than Svelte 3. The Svelte 5 preview is very significantly smaller and faster than Svelte 4 — though we don't recommend users upgrade to this version yet as it's not currently production ready. -### Packages +#### Packages [`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are adding the most size to your site. You may also find areas of opportunity manually inspecting the build output with [`build: { minify: false }`](https://vitejs.dev/config/build-options.html#build-minify) or via the network tab of your browser's developer tools. -### External scripts +#### External scripts Try to minimize the number of third-party scripts running in the browser. E.g. instead of using JavaScript-based analytics tracking, you may wish to use server-side implementations. Many hosting providers with SvelteKit adapters offer such functionality such as [Netlify](https://docs.netlify.com/monitor-sites/site-analytics/), [Cloudflare](https://www.cloudflare.com/web-analytics/), and [Vercel](https://vercel.com/docs/analytics). You also may consider running third-party scripts in a webworker with [Partytown's SvelteKit integration](https://partytown.builder.io/sveltekit). -### Selective loading +#### Selective loading Code imported via static import will be automatically bundled into your page's code. If there is a piece of code you need only when some condition is met, use a [dynamic import](https://vitejs.dev/guide/features#dynamic-import). -## Hosting +### Lazy loading + +You can use a placeholder on intial page load and then swap that out with real contents after the page is loaded. For images, you can do this with [the `loading` attribute](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading). To lazy load data, you can use [streaming with promises](load#streaming-with-promises). + +### Hosting Your frontend should be located in the same data center as your backend for minimal latency. For sites with no backend, many SvelteKit adapters support deploying to "the edge", which means your code will be distributed globally so it can run next to your users. Some adapters even support [configuring deployment on a per-page basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN — the hosts for many adapters offered by SvelteKit will do this automatically. Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small files for improved cacheability, which results in excellent performance, but this does assume that your files can be loaded in parallel with HTTP/2. +## Common Issues + +### Waterfalls + +One of the biggest performance killers is what is referred to as a waterfall, which is a series of requests that is made sequentially. This can occur on the the fontend or backend of your application. + +#### Frontend asset waterfall + +You can, for example, encounter a request waterfall when your HTML requests JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) tags or headers. However, you should view [the network tab in your developer tools](#measuring) to check whether there might be additional resources needing to be preloaded. Pay special attention to this if you use web [fonts](#fonts) since they need to be handled manually. + +#### Frontend data waterfall + +Another example of a waterfall would be when your frontend makes an API call to fetch the current user, then uses the details from that response to fetch a list of saved items, and then uses that response to fetch the details for each item. You can identify this by viewing [the network tab in your developer tools](#measuring) or with instrumentation like [OpenTelemetry](https://opentelemetry.io/). Avoid this issue by [making requests in parallel](load#parallel-loading) or joining requests into a single request as is done when using GraphQL. + +#### Backend data waterfall + +You can also, for example, encounter a waterfall when your backend makes a database query to get the current user, then makes a database query based on the result to get a list of saved items, then uses that result to get the details of each item. It will typically be more performant to issue a single query with a database join. You can identify this by logging queries made to your datastore or with instrumentation like [OpenTelemetry](https://opentelemetry.io/). + ## Further reading For the most part, building a performant SvelteKit app is the same as building any performant web app. You should be able to apply information from the following general performance resources to any web experience you build: From 6646e7d72bffc6686100774f355d706e639944ee Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 21 Dec 2023 10:24:03 -0800 Subject: [PATCH 04/15] prefetching --- documentation/docs/40-best-practices/05-performance.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index eb6ffeb55f3b..9651136e52d7 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -59,6 +59,10 @@ You also may consider running third-party scripts in a webworker with [Partytown Code imported via static import will be automatically bundled into your page's code. If there is a piece of code you need only when some condition is met, use a [dynamic import](https://vitejs.dev/guide/features#dynamic-import). +### Prefetching + +You can fetch [data](link-options#data-sveltekit-preload-data) and [code](link-options#data-sveltekit-preload-code) before a page is actually loaded when the user hovers over or begins to click a link with the appropriate [link options](link-options). + ### Lazy loading You can use a placeholder on intial page load and then swap that out with real contents after the page is loaded. For images, you can do this with [the `loading` attribute](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading). To lazy load data, you can use [streaming with promises](load#streaming-with-promises). From 9ff640ce3ee8df1d08db6bbd0829e887360480dc Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 09:11:04 -0500 Subject: [PATCH 05/15] Apply suggestions from code review --- .../docs/40-best-practices/05-performance.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 9651136e52d7..5af73c356c74 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -2,7 +2,7 @@ title: Performance --- -SvelteKit strives to provide a highly performant experience by default. However, when building any web application you will always need to put in some effort to maintain fast speeds. Some tips are included below. +SvelteKit apps provide highly performant experiences by default, but it's always good to invest time to ensure your code is as performant as it can be. Here are some tips to help you get the most out of your SvelteKit app. ## Measuring @@ -25,15 +25,15 @@ If you see in the network tab of your browser that an API call is taking a long #### Images -Typically the most impactful area of opportunity is optimizing your images. Svelte provides an offically-supported image optimization package. Please see the [images](images) page for more details. Additionally, you may use Lighthouse for identifying images needing optimization. +Images are often one of the most impactful areas of opportunity for optimization. Svelte provides an offically-supported image optimization package. Please see the [images](images) page for more details. Additionally, Lighthouse is great for identifying which images on your site are the most problematic / in need of optimizations. #### Fonts -Preload fonts when possible with the appropriate by calling `resolve` with the appropriate `preload` option value in the [`handle`](hooks#server-hooks-handle) hook. Also ensure you've set the [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) option appropriately in your CSS. Additionally, you may reduce the size of font files with [subsetting](https://fonts.google.com/knowledge/glossary/subsetting). +When possible, preload fonts by calling `resolve` with the appropriate `preload` option in your [`handle`](hooks#server-hooks-handle) hook, and ensure you've set the [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) option in your CSS. To reduce the size of font files, utilize [subsetting](https://fonts.google.com/knowledge/glossary/subsetting). #### Videos -Video are very large files and so extra care should be taken to ensure that they're optimized: +Video files can be very large, so extra care should be taken to ensure that they're optimized: - Compress videos with tools such as [Handbrake](https://handbrake.fr/). Consider converting the videos to HTML5 video formats such as WebM or MP4. - [Lazy load](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading) videos located below the fold. @@ -43,11 +43,11 @@ Video are very large files and so extra care should be taken to ensure that they #### Svelte version -We recommend running the latest version of Svelte. Svelte 4 is significantly smaller and faster than Svelte 3. The Svelte 5 preview is very significantly smaller and faster than Svelte 4 — though we don't recommend users upgrade to this version yet as it's not currently production ready. +We recommend running the latest version of Svelte. Svelte 4 is significantly smaller and faster than Svelte 3. The Svelte 5 preview is _much_ smaller and faster than Svelte 4 — though we don't recommend users upgrade to this version until it's production ready. #### Packages -[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are adding the most size to your site. You may also find areas of opportunity manually inspecting the build output with [`build: { minify: false }`](https://vitejs.dev/config/build-options.html#build-minify) or via the network tab of your browser's developer tools. +[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are contributing the most to the size of your site. You may also find areas of opportunity manually inspecting the build output with [`build: { minify: false }`](https://vitejs.dev/config/build-options.html#build-minify), or via the network tab of your browser's developer tools. #### External scripts @@ -57,27 +57,27 @@ You also may consider running third-party scripts in a webworker with [Partytown #### Selective loading -Code imported via static import will be automatically bundled into your page's code. If there is a piece of code you need only when some condition is met, use a [dynamic import](https://vitejs.dev/guide/features#dynamic-import). +Code imported via static imports will be automatically bundled into your page's code. If there is a piece of code you need only when some condition is met, use a [dynamic import](https://vitejs.dev/guide/features#dynamic-import). ### Prefetching -You can fetch [data](link-options#data-sveltekit-preload-data) and [code](link-options#data-sveltekit-preload-code) before a page is actually loaded when the user hovers over or begins to click a link with the appropriate [link options](link-options). +You can fetch [data](link-options#data-sveltekit-preload-data) and [code](link-options#data-sveltekit-preload-code) before a page is actually loaded when the user hovers over (or begins to click) a link with the appropriate [link options](link-options). ### Lazy loading -You can use a placeholder on intial page load and then swap that out with real contents after the page is loaded. For images, you can do this with [the `loading` attribute](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading). To lazy load data, you can use [streaming with promises](load#streaming-with-promises). +You can use a placeholder on the intial page load, then swap it out with real contents after the page is loaded. For images, you can do this with [the `loading` attribute](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading). To lazy load data, you can use [streaming with promises](load#streaming-with-promises). ### Hosting -Your frontend should be located in the same data center as your backend for minimal latency. For sites with no backend, many SvelteKit adapters support deploying to "the edge", which means your code will be distributed globally so it can run next to your users. Some adapters even support [configuring deployment on a per-page basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN — the hosts for many adapters offered by SvelteKit will do this automatically. +Your frontend should be located in the same data center as your backend to minimize latency. For sites with no central backend, many SvelteKit adapters support deploying to the _edge_, which means handling each user's requests from a nearby server. This can reduce load times significantly. Some adapters even support [configuring deployment on a per-page basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN (which are typically edge networks) — the hosts for many adapters offered by SvelteKit will do this automatically. Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small files for improved cacheability, which results in excellent performance, but this does assume that your files can be loaded in parallel with HTTP/2. -## Common Issues +## Common issues ### Waterfalls -One of the biggest performance killers is what is referred to as a waterfall, which is a series of requests that is made sequentially. This can occur on the the fontend or backend of your application. +One of the biggest performance killers is what is referred to as a waterfall, which is a series of requests that is made sequentially. This can occur on the frontend or backend of your application. #### Frontend asset waterfall From d599ef1b9fde9804b9eb7001f4e0f922c635db84 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 10:02:33 -0500 Subject: [PATCH 06/15] Apply suggestions from code review --- .../docs/40-best-practices/05-performance.md | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 5af73c356c74..c4dc18f07274 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -2,17 +2,28 @@ title: Performance --- -SvelteKit apps provide highly performant experiences by default, but it's always good to invest time to ensure your code is as performant as it can be. Here are some tips to help you get the most out of your SvelteKit app. +Out of the box, SvelteKit does a lot of work to make your applications as performant as possible: + +- Code-splitting, so that only the code you need for the current page is loaded +- Asset preloading, so that 'waterfalls' (of files requesting other files) are prevented +- File hashing, so that your assets can be cached forever +- Request coalescing, so that data fetched from separate server `load` functions is grouped into a single HTTP request +- Parallel loading, so that separate universal `load` functions fetch data simultaneously +- Data inlining, so that requests made with `fetch` during server rendering can be replayed in the browser without issuing a new request +- Prerendering (configurable on a per-route basis, if necessary) so that pages without dynamic data can be served instantaneously +- Link preloading, so that data and code requirements for a client-side navigation are eagerly anticipated + +Nevertheless, we can't (yet) eliminate all sources of slowness. To eke out maximum performance, you should be mindful of the following tips. ## Measuring -For deployed sites, you can measure your page's performance with [Google's PageSpeed Insights](https://pagespeed.web.dev/). More advanced users may also like to use [WebPageTest](https://www.webpagetest.org/). +You can measure the performance of a deployed app with Google's [PageSpeed Insights](https://pagespeed.web.dev/) or, for more advanced analysis, [WebPageTest](https://www.webpagetest.org/). You can also use your browser's developer tools to evaluate your page's performance and identify areas of opportunity. Check out some of the resources below if you're not already familiar with your browser's developer tools: -* Chrome - [Lighthouse](https://developer.chrome.com/docs/lighthouse/overview#devtools), [Network](https://developer.chrome.com/docs/devtools/network), and [Performance](https://developer.chrome.com/docs/devtools/performance) tabs in the developer tools -* Firefox - [Network](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/) and [Performance](https://hacks.mozilla.org/2022/03/performance-tool-in-firefox-devtools-reloaded/) tabs in the developer tools -* Edge - [Lighthouse](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/lighthouse/lighthouse-tool), [Network](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/network/), and [Performance](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/evaluate-performance/) tabs in the developer tools +* Chrome - [Lighthouse](https://developer.chrome.com/docs/lighthouse/overview#devtools), [Network](https://developer.chrome.com/docs/devtools/network), and [Performance](https://developer.chrome.com/docs/devtools/performance) devtools +* Edge - [Lighthouse](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/lighthouse/lighthouse-tool), [Network](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/network/), and [Performance](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/evaluate-performance/) devtools +* Firefox - [Network](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/) and [Performance](https://hacks.mozilla.org/2022/03/performance-tool-in-firefox-devtools-reloaded/) devtools * Safari - [enhancing the performance of your webpage](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/Web_Inspector_Tutorial/EnhancingyourWebpagesPerformance/EnhancingyourWebpagesPerformance.html) ### Instrumenting From c6771c59760e5c60fa2f2110841abae64bcbb745 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 10:57:13 -0500 Subject: [PATCH 07/15] various --- .../docs/40-best-practices/05-performance.md | 75 +++++++++---------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index c4dc18f07274..e48740ccf339 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -10,39 +10,36 @@ Out of the box, SvelteKit does a lot of work to make your applications as perfor - Request coalescing, so that data fetched from separate server `load` functions is grouped into a single HTTP request - Parallel loading, so that separate universal `load` functions fetch data simultaneously - Data inlining, so that requests made with `fetch` during server rendering can be replayed in the browser without issuing a new request +- Conservative invalidation, so that `load` functions are only re-run when necessary - Prerendering (configurable on a per-route basis, if necessary) so that pages without dynamic data can be served instantaneously - Link preloading, so that data and code requirements for a client-side navigation are eagerly anticipated Nevertheless, we can't (yet) eliminate all sources of slowness. To eke out maximum performance, you should be mindful of the following tips. -## Measuring +## Diagnosing issues -You can measure the performance of a deployed app with Google's [PageSpeed Insights](https://pagespeed.web.dev/) or, for more advanced analysis, [WebPageTest](https://www.webpagetest.org/). +Google's [PageSpeed Insights](https://pagespeed.web.dev/) and (for more advanced analysis) [WebPageTest](https://www.webpagetest.org/) are excellent ways to understand the performance characteristics of a site that is already deployed to the internet. -You can also use your browser's developer tools to evaluate your page's performance and identify areas of opportunity. Check out some of the resources below if you're not already familiar with your browser's developer tools: +Your browser also includes useful developer tools for analysing your site, whether deployed or running locally: * Chrome - [Lighthouse](https://developer.chrome.com/docs/lighthouse/overview#devtools), [Network](https://developer.chrome.com/docs/devtools/network), and [Performance](https://developer.chrome.com/docs/devtools/performance) devtools * Edge - [Lighthouse](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/lighthouse/lighthouse-tool), [Network](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/network/), and [Performance](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/evaluate-performance/) devtools * Firefox - [Network](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/) and [Performance](https://hacks.mozilla.org/2022/03/performance-tool-in-firefox-devtools-reloaded/) devtools * Safari - [enhancing the performance of your webpage](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/Web_Inspector_Tutorial/EnhancingyourWebpagesPerformance/EnhancingyourWebpagesPerformance.html) +Note that your site running locally in `dev` mode will exhibit slightly different behaviour to your production app, which you can [preview](/docs/building-your-app#preview-your-app) after building. + ### Instrumenting If you see in the network tab of your browser that an API call is taking a long time and you'd like to understand why, you may consider instrumenting your backend with a tool like [OpenTelemetry](https://opentelemetry.io/) or [Server-Timing headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing). -## Optimizing - -### Multimedia +## Optimizing assets -#### Images +### Images Images are often one of the most impactful areas of opportunity for optimization. Svelte provides an offically-supported image optimization package. Please see the [images](images) page for more details. Additionally, Lighthouse is great for identifying which images on your site are the most problematic / in need of optimizations. -#### Fonts - -When possible, preload fonts by calling `resolve` with the appropriate `preload` option in your [`handle`](hooks#server-hooks-handle) hook, and ensure you've set the [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) option in your CSS. To reduce the size of font files, utilize [subsetting](https://fonts.google.com/knowledge/glossary/subsetting). - -#### Videos +### Videos Video files can be very large, so extra care should be taken to ensure that they're optimized: @@ -50,57 +47,53 @@ Video files can be very large, so extra care should be taken to ensure that they - [Lazy load](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading) videos located below the fold. - Strip the audio track out of muted videos using a tool like [FFmpeg](https://ffmpeg.org/). -### Code size - -#### Svelte version - -We recommend running the latest version of Svelte. Svelte 4 is significantly smaller and faster than Svelte 3. The Svelte 5 preview is _much_ smaller and faster than Svelte 4 — though we don't recommend users upgrade to this version until it's production ready. - -#### Packages +### Fonts -[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are contributing the most to the size of your site. You may also find areas of opportunity manually inspecting the build output with [`build: { minify: false }`](https://vitejs.dev/config/build-options.html#build-minify), or via the network tab of your browser's developer tools. +When possible, preload fonts by calling `resolve` with the appropriate `preload` option in your [`handle`](hooks#server-hooks-handle) hook, and ensure you've set the [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) option in your CSS. To reduce the size of font files, utilize [subsetting](https://fonts.google.com/knowledge/glossary/subsetting). -#### External scripts +## Reducing code size -Try to minimize the number of third-party scripts running in the browser. E.g. instead of using JavaScript-based analytics tracking, you may wish to use server-side implementations. Many hosting providers with SvelteKit adapters offer such functionality such as [Netlify](https://docs.netlify.com/monitor-sites/site-analytics/), [Cloudflare](https://www.cloudflare.com/web-analytics/), and [Vercel](https://vercel.com/docs/analytics). +### Svelte version -You also may consider running third-party scripts in a webworker with [Partytown's SvelteKit integration](https://partytown.builder.io/sveltekit). +We recommend running the latest version of Svelte. Svelte 4 is smaller and faster than Svelte 3. (The [Svelte 5 preview](https://svelte-5-preview.vercel.app/) is much smaller and faster still, but we don't recommend that you upgrade to this version until it's production ready.) -#### Selective loading +### Packages -Code imported via static imports will be automatically bundled into your page's code. If there is a piece of code you need only when some condition is met, use a [dynamic import](https://vitejs.dev/guide/features#dynamic-import). +[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are contributing the most to the size of your site. You may also find areas of opportunity manually inspecting the build output with [`build: { minify: false }`](https://vitejs.dev/config/build-options.html#build-minify), or via the network tab of your browser's devtools. -### Prefetching +### External scripts -You can fetch [data](link-options#data-sveltekit-preload-data) and [code](link-options#data-sveltekit-preload-code) before a page is actually loaded when the user hovers over (or begins to click) a link with the appropriate [link options](link-options). +Try to minimize the number of third-party scripts running in the browser. For example, instead of using JavaScript-based analytics you may wish to use server-side implementations. Many hosting providers with SvelteKit adapters offer such functionality such as [Cloudflare](https://www.cloudflare.com/web-analytics/), [Netlify](https://docs.netlify.com/monitor-sites/site-analytics/), and [Vercel](https://vercel.com/docs/analytics). -### Lazy loading +You also may consider running third-party scripts in a web worker with [Partytown's SvelteKit integration](https://partytown.builder.io/sveltekit). -You can use a placeholder on the intial page load, then swap it out with real contents after the page is loaded. For images, you can do this with [the `loading` attribute](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading). To lazy load data, you can use [streaming with promises](load#streaming-with-promises). +### Selective loading -### Hosting +Code imported with static `import` declarations will be automatically bundled with the rest of your page. If there is a piece of code you need only when some condition is met, use the dynamic `import(...)` form instead. -Your frontend should be located in the same data center as your backend to minimize latency. For sites with no central backend, many SvelteKit adapters support deploying to the _edge_, which means handling each user's requests from a nearby server. This can reduce load times significantly. Some adapters even support [configuring deployment on a per-page basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN (which are typically edge networks) — the hosts for many adapters offered by SvelteKit will do this automatically. +## Navigation -Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small files for improved cacheability, which results in excellent performance, but this does assume that your files can be loaded in parallel with HTTP/2. +### Prefetching -## Common issues +You can fetch [data](link-options#data-sveltekit-preload-data) and [code](link-options#data-sveltekit-preload-code) before a page is actually loaded when the user hovers over (or begins to click) a link with the appropriate [link options](link-options). This is configured by default on the `` element when you create a new SvelteKit app. -### Waterfalls +### Non-essential data -One of the biggest performance killers is what is referred to as a waterfall, which is a series of requests that is made sequentially. This can occur on the frontend or backend of your application. +For slow-loading data that isn't needed immediately, the object returned from your `load` function can contain a promise rather than the data itself. For server `load` functions, this will cause the data to [stream](load#streaming-with-promises) in after the navigation (or initial page load). -#### Frontend asset waterfall +### Preventing waterfalls -You can, for example, encounter a request waterfall when your HTML requests JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) tags or headers. However, you should view [the network tab in your developer tools](#measuring) to check whether there might be additional resources needing to be preloaded. Pay special attention to this if you use web [fonts](#fonts) since they need to be handled manually. +One of the biggest performance killers is what is referred to as a _waterfall_, which is a series of requests that is made sequentially. This can happen on the server or in the browser. -#### Frontend data waterfall +- Asset waterfalls can occur in the browser when your HTML requests JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) tags or headers, but you should view [the network tab in your devtools](#diagnosing-issues) to check whether additional resources need to be preloaded. Pay special attention to this if you use web [fonts](#fonts) since they need to be handled manually. +- If a universal `load` function makes an API call to fetch the current user, then uses the details from that response to fetch a list of saved items, and then uses _that_ response to fetch the details for each item, the browser will end up making multiple sequential requests. This is deadly for performance, especially for users that are physically located far from your backend. Avoid this issue by using [server `load` functions](/docs/load#universal-vs-server) where possible. +- Server `load` functions are also not immune to waterfalls (though they are much less costly since they rarely involve roundtrips with high latency), for example if you query a database to get the current user, then use that data to make a second query for a list of saved items, then use that result to get the details of each item. It will typically be more performant to issue a single query with a database join. -Another example of a waterfall would be when your frontend makes an API call to fetch the current user, then uses the details from that response to fetch a list of saved items, and then uses that response to fetch the details for each item. You can identify this by viewing [the network tab in your developer tools](#measuring) or with instrumentation like [OpenTelemetry](https://opentelemetry.io/). Avoid this issue by [making requests in parallel](load#parallel-loading) or joining requests into a single request as is done when using GraphQL. +## Hosting -#### Backend data waterfall +Your frontend should be located in the same data center as your backend to minimize latency. For sites with no central backend, many SvelteKit adapters support deploying to the _edge_, which means handling each user's requests from a nearby server. This can reduce load times significantly. Some adapters even support [configuring deployment on a per-page basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN (which are typically edge networks) — the hosts for many adapters offered by SvelteKit will do this automatically. -You can also, for example, encounter a waterfall when your backend makes a database query to get the current user, then makes a database query based on the result to get a list of saved items, then uses that result to get the details of each item. It will typically be more performant to issue a single query with a database join. You can identify this by logging queries made to your datastore or with instrumentation like [OpenTelemetry](https://opentelemetry.io/). +Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small files for improved cacheability, which results in excellent performance, but this does assume that your files can be loaded in parallel with HTTP/2. ## Further reading From 9a00da537d9114d4dc8e9e167b9ef34c55e16e88 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 11:04:30 -0500 Subject: [PATCH 08/15] tweak --- documentation/docs/40-best-practices/05-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index e48740ccf339..35027486d513 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -37,7 +37,7 @@ If you see in the network tab of your browser that an API call is taking a long ### Images -Images are often one of the most impactful areas of opportunity for optimization. Svelte provides an offically-supported image optimization package. Please see the [images](images) page for more details. Additionally, Lighthouse is great for identifying which images on your site are the most problematic / in need of optimizations. +Reducing the size of image files is often one of the most impactful changes you can make to a site's performance. Svelte provides the `@sveltejs/enhanced-image` package, detailed on the [images](images) page, for making this easier. Additionally, Lighthouse is useful for identifying the worst offenders. ### Videos From a1e56ffe29440d5596964fa1f77250c90b0c4390 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 11:06:51 -0500 Subject: [PATCH 09/15] MDN page says nothing about lazy-loading videos --- documentation/docs/40-best-practices/05-performance.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 35027486d513..8856e0fa6534 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -43,8 +43,8 @@ Reducing the size of image files is often one of the most impactful changes you Video files can be very large, so extra care should be taken to ensure that they're optimized: -- Compress videos with tools such as [Handbrake](https://handbrake.fr/). Consider converting the videos to HTML5 video formats such as WebM or MP4. -- [Lazy load](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading) videos located below the fold. +- Compress videos with tools such as [Handbrake](https://handbrake.fr/). Consider converting the videos to web-friendly formats such as `.webm` or `.mp4`. +- You can [lazy-load videos](https://web.dev/articles/lazy-loading-video) located below the fold with `preload="none"` (though note that this will slow down playback when the user _does_ initiate it). - Strip the audio track out of muted videos using a tool like [FFmpeg](https://ffmpeg.org/). ### Fonts From 24cda86f90cc7588fe20b9a179aec8593445fba9 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 26 Dec 2023 08:54:49 -0800 Subject: [PATCH 10/15] fix link --- documentation/docs/40-best-practices/05-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index e48740ccf339..d55ae3db4bd5 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -85,7 +85,7 @@ For slow-loading data that isn't needed immediately, the object returned from yo One of the biggest performance killers is what is referred to as a _waterfall_, which is a series of requests that is made sequentially. This can happen on the server or in the browser. -- Asset waterfalls can occur in the browser when your HTML requests JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) tags or headers, but you should view [the network tab in your devtools](#diagnosing-issues) to check whether additional resources need to be preloaded. Pay special attention to this if you use web [fonts](#fonts) since they need to be handled manually. +- Asset waterfalls can occur in the browser when your HTML requests JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) tags or headers, but you should view [the network tab in your devtools](#diagnosing-issues) to check whether additional resources need to be preloaded. Pay special attention to this if you use web [fonts](#optimizing-assets-fonts) since they need to be handled manually. - If a universal `load` function makes an API call to fetch the current user, then uses the details from that response to fetch a list of saved items, and then uses _that_ response to fetch the details for each item, the browser will end up making multiple sequential requests. This is deadly for performance, especially for users that are physically located far from your backend. Avoid this issue by using [server `load` functions](/docs/load#universal-vs-server) where possible. - Server `load` functions are also not immune to waterfalls (though they are much less costly since they rarely involve roundtrips with high latency), for example if you query a database to get the current user, then use that data to make a second query for a list of saved items, then use that result to get the details of each item. It will typically be more performant to issue a single query with a database join. From 8c44e172dc58c2045adbf1b8ff4a41994392d5f0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 12:17:27 -0500 Subject: [PATCH 11/15] Update documentation/docs/40-best-practices/05-performance.md Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- documentation/docs/40-best-practices/05-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 6f25d7952ea8..30e520de4e9b 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -27,7 +27,7 @@ Your browser also includes useful developer tools for analysing your site, wheth * Firefox - [Network](https://firefox-source-docs.mozilla.org/devtools-user/network_monitor/) and [Performance](https://hacks.mozilla.org/2022/03/performance-tool-in-firefox-devtools-reloaded/) devtools * Safari - [enhancing the performance of your webpage](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/Web_Inspector_Tutorial/EnhancingyourWebpagesPerformance/EnhancingyourWebpagesPerformance.html) -Note that your site running locally in `dev` mode will exhibit slightly different behaviour to your production app, which you can [preview](/docs/building-your-app#preview-your-app) after building. +Note that your site running locally in `dev` mode will exhibit different behaviour than your production app, so you should do performance testing in [preview](/docs/building-your-app#preview-your-app) mode after building. ### Instrumenting From 473891e2c3ed7cb5177c34c97bcdef8560dba9fa Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 26 Dec 2023 09:20:42 -0800 Subject: [PATCH 12/15] move images page --- .../{30-advanced/60-images.md => 40-best-practices/07-images.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename documentation/docs/{30-advanced/60-images.md => 40-best-practices/07-images.md} (100%) diff --git a/documentation/docs/30-advanced/60-images.md b/documentation/docs/40-best-practices/07-images.md similarity index 100% rename from documentation/docs/30-advanced/60-images.md rename to documentation/docs/40-best-practices/07-images.md From 8c5f2fbd0c1c9627ded52b0eebf268db6c9c8ca8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 16:11:55 -0500 Subject: [PATCH 13/15] Update documentation/docs/40-best-practices/05-performance.md Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com> --- documentation/docs/40-best-practices/05-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 30e520de4e9b..3809460891e4 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -87,7 +87,7 @@ One of the biggest performance killers is what is referred to as a _waterfall_, - Asset waterfalls can occur in the browser when your HTML requests JS which requests CSS which requests a background image and web font. SvelteKit will largely solve this class of problems for you by adding [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) tags or headers, but you should view [the network tab in your devtools](#diagnosing-issues) to check whether additional resources need to be preloaded. Pay special attention to this if you use web [fonts](#optimizing-assets-fonts) since they need to be handled manually. - If a universal `load` function makes an API call to fetch the current user, then uses the details from that response to fetch a list of saved items, and then uses _that_ response to fetch the details for each item, the browser will end up making multiple sequential requests. This is deadly for performance, especially for users that are physically located far from your backend. Avoid this issue by using [server `load` functions](/docs/load#universal-vs-server) where possible. -- Server `load` functions are also not immune to waterfalls (though they are much less costly since they rarely involve roundtrips with high latency), for example if you query a database to get the current user, then use that data to make a second query for a list of saved items, then use that result to get the details of each item. It will typically be more performant to issue a single query with a database join. +- Server `load` functions are also not immune to waterfalls (though they are much less costly since they rarely involve roundtrips with high latency). For example if you query a database to get the current user and then use that data to make a second query for a list of saved items, it will typically be more performant to issue a single query with a database join. ## Hosting From 4db3107264cd2ae1bc89b56a29f896aa759a033b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 16:24:40 -0500 Subject: [PATCH 14/15] update font section (no point mentioning font-display without a recommended value) --- documentation/docs/40-best-practices/05-performance.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 3809460891e4..59c5842f1b05 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -49,7 +49,9 @@ Video files can be very large, so extra care should be taken to ensure that they ### Fonts -When possible, preload fonts by calling `resolve` with the appropriate `preload` option in your [`handle`](hooks#server-hooks-handle) hook, and ensure you've set the [`font-display`](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display) option in your CSS. To reduce the size of font files, utilize [subsetting](https://fonts.google.com/knowledge/glossary/subsetting). +SvelteKit automatically preloads critical `.js` and `.css` files when the user visits a page, but it does _not_ preload fonts by default, since this may cause unnecessary files (such as font weights that are referenced by your CSS but not actually used on the current page) to be downloaded. Having said that, preloading fonts correctly can make a big difference to how fast your site feels. In your [`handle`](hooks#server-hooks-handle) hook, you can call `resolve` with a `preload` filter that includes your fonts. + +You can reduce the size of font files by [subsetting](https://web.dev/learn/performance/optimize-web-fonts#subset_your_web_fonts) your fonts. ## Reducing code size From e6a0d97c1f382e2194782564878d6b8034cba156 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Dec 2023 16:41:36 -0500 Subject: [PATCH 15/15] various tweaks --- .../docs/40-best-practices/05-performance.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/documentation/docs/40-best-practices/05-performance.md b/documentation/docs/40-best-practices/05-performance.md index 59c5842f1b05..e6846e178e6e 100644 --- a/documentation/docs/40-best-practices/05-performance.md +++ b/documentation/docs/40-best-practices/05-performance.md @@ -61,13 +61,13 @@ We recommend running the latest version of Svelte. Svelte 4 is smaller and faste ### Packages -[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are contributing the most to the size of your site. You may also find areas of opportunity manually inspecting the build output with [`build: { minify: false }`](https://vitejs.dev/config/build-options.html#build-minify), or via the network tab of your browser's devtools. +[`rollup-plugin-visualizer`](https://www.npmjs.com/package/rollup-plugin-visualizer) can be helpful for identifying which packages are contributing the most to the size of your site. You may also find opportunities to remove code by manually inspecting the build output (use `build: { minify: false }` in your [Vite config](https://vitejs.dev/config/build-options.html#build-minify) to make the output readable, but remember to undo that before deploying your app), or via the network tab of your browser's devtools. ### External scripts -Try to minimize the number of third-party scripts running in the browser. For example, instead of using JavaScript-based analytics you may wish to use server-side implementations. Many hosting providers with SvelteKit adapters offer such functionality such as [Cloudflare](https://www.cloudflare.com/web-analytics/), [Netlify](https://docs.netlify.com/monitor-sites/site-analytics/), and [Vercel](https://vercel.com/docs/analytics). +Try to minimize the number of third-party scripts running in the browser. For example, instead of using JavaScript-based analytics consider using server-side implementations, such as those offered by many platforms with SvelteKit adapters including [Cloudflare](https://www.cloudflare.com/web-analytics/), [Netlify](https://docs.netlify.com/monitor-sites/site-analytics/), and [Vercel](https://vercel.com/docs/analytics). -You also may consider running third-party scripts in a web worker with [Partytown's SvelteKit integration](https://partytown.builder.io/sveltekit). +To run third party scripts in a web worker (which avoids blocking the main thread), use [Partytown's SvelteKit integration](https://partytown.builder.io/sveltekit). ### Selective loading @@ -75,13 +75,13 @@ Code imported with static `import` declarations will be automatically bundled wi ## Navigation -### Prefetching +### Preloading -You can fetch [data](link-options#data-sveltekit-preload-data) and [code](link-options#data-sveltekit-preload-code) before a page is actually loaded when the user hovers over (or begins to click) a link with the appropriate [link options](link-options). This is configured by default on the `` element when you create a new SvelteKit app. +You can speed up client-side navigations by eagerly preloading the necessary code and data, using [link options](link-options). This is configured by default on the `` element when you create a new SvelteKit app. ### Non-essential data -For slow-loading data that isn't needed immediately, the object returned from your `load` function can contain a promise rather than the data itself. For server `load` functions, this will cause the data to [stream](load#streaming-with-promises) in after the navigation (or initial page load). +For slow-loading data that isn't needed immediately, the object returned from your `load` function can contain promises rather than the data itself. For server `load` functions, this will cause the data to [stream](load#streaming-with-promises) in after the navigation (or initial page load). ### Preventing waterfalls @@ -93,12 +93,10 @@ One of the biggest performance killers is what is referred to as a _waterfall_, ## Hosting -Your frontend should be located in the same data center as your backend to minimize latency. For sites with no central backend, many SvelteKit adapters support deploying to the _edge_, which means handling each user's requests from a nearby server. This can reduce load times significantly. Some adapters even support [configuring deployment on a per-page basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN (which are typically edge networks) — the hosts for many adapters offered by SvelteKit will do this automatically. +Your frontend should be located in the same data center as your backend to minimize latency. For sites with no central backend, many SvelteKit adapters support deploying to the _edge_, which means handling each user's requests from a nearby server. This can reduce load times significantly. Some adapters even support [configuring deployment on a per-route basis](https://kit.svelte.dev/docs/page-options#config). You should also consider serving images from a CDN (which are typically edge networks) — the hosts for many SvelteKit adapters will do this automatically. Ensure your host uses HTTP/2 or newer. Vite's code splitting creates numerous small files for improved cacheability, which results in excellent performance, but this does assume that your files can be loaded in parallel with HTTP/2. ## Further reading -For the most part, building a performant SvelteKit app is the same as building any performant web app. You should be able to apply information from the following general performance resources to any web experience you build: - -- [Core Web Vitals](https://web.dev/explore/learn-core-web-vitals) +For the most part, building a performant SvelteKit app is the same as building any performant web app. You should be able to apply information from general performance resources such as [Core Web Vitals](https://web.dev/explore/learn-core-web-vitals) to any web experience you build.