Skip to main content

性能

SvelteKit 开箱即用地做了很多工作来使您的应用程序尽可能高效:

  • 代码分割,因此只加载当前页面所需的代码
  • 资源预加载,防止出现”瀑布(waterfalls)”(文件请求其他文件的情况)
  • 文件哈希,使您的资源可以永久缓存
  • 请求合并,将从不同服务端 load 函数获取的数据合并成单个 HTTP 请求
  • 并行加载,不同的通用 load 函数同时获取数据
  • 数据内联,服务端渲染期间使用 fetch 发出的请求可以在浏览器中重放而无需重新发出请求
  • 保守的失效处理,因此 load 函数仅在必要时重新运行
  • 预渲染(如有必要,可按路由配置),使没有动态数据的页面可以立即提供服务
  • 链接预加载,以便提前主动获取客户端导航所需的数据和代码

尽管如此,我们(尚)不能消除所有导致性能下降的因素。要获得最大性能,您应该注意以下建议。

诊断问题

Google 的 PageSpeed Insights 和(用于更高级分析的)WebPageTest 是了解已部署到互联网的网站性能特征的出色工具。

您的浏览器还包含有用的开发者工具,用于分析您的网站,无论是已部署还是在本地运行:

请注意,在 dev 模式下本地运行的网站会表现出与生产应用程序不同的行为,因此您应该在构建后在预览模式下进行性能测试。

检测

如果您在浏览器的网络标签中看到 API 调用耗时过长,想了解原因,您可以考虑使用 OpenTelemetryServer-Timing 头 等工具来检测您的后端。

优化资源

图片

减小图片文件的大小通常是对网站性能影响最大的改变之一。Svelte 提供了 @sveltejs/enhanced-img 包,详见图片页面,可以让这个过程更容易。此外,Lighthouse 对识别性能影响最大的图片很有帮助。

视频

视频文件可能非常大,因此应特别注意确保它们经过优化:

  • 使用 Handbrake 等工具压缩视频。考虑将视频转换为 .webm.mp4 等 web 友好的格式。
  • 您可以使用 preload="none" 对折叠区域以下的视频进行延迟加载(但请注意,这会在用户开始播放时减慢播放速度)。
  • 使用 FFmpeg 等工具从静音视频中删除音轨。

字体

当用户访问页面时,SvelteKit 会自动预加载关键的 .js.css 文件,但默认情况下不会预加载字体,因为这可能会导致下载不必要的文件(例如 CSS 中引用但实际上在当前页面上未使用的字体粗细)。话虽如此,正确预加载字体可以对网站的速度感知产生很大影响。在您的 handle hook 中,您可以使用包含字体的 preload 过滤器调用 resolve

通过子集化字体,您可以减小字体文件的大小。

减少代码大小

Svelte 版本

我们推荐使用最新版本的 Svelte。Svelte 5 比 Svelte 4 更小更快,而 Svelte 4 又比 Svelte 3 更小更快。

rollup-plugin-visualizer 可以帮助识别哪些包对网站大小贡献最大。您还可以通过手动检查构建输出发现删除代码的机会(在您的 Vite 配置中使用 build: { minify: false } 使输出可读,但记得在部署应用程序之前撤销此更改),或通过浏览器开发工具的网络标签。

外部脚本

尽量减少在浏览器中运行的第三方脚本数量。例如,与其使用基于 JavaScript 的分析工具,不如考虑使用服务端实现,比如许多带有 SvelteKit 适配器的平台,包括 CloudflareNetlifyVercel 所提供的解决方案。

要在 Web Worker 中运行第三方脚本(避免阻塞主线程),请使用 Partytown 的 SvelteKit 集成

选择性加载

使用静态 import 声明导入的代码将自动与页面的其余部分打包在一起。如果某段代码仅在满足特定条件时才需要,请使用动态 import(...) 形式来选择性地延迟加载组件。

导航

预加载

您可以使用链接选项预先加载必要的代码和数据来加快客户端导航。当您创建新的 SvelteKit 应用程序时,<body> 元素上是默认有配置的。

非必要数据

对于加载缓慢且不需要立即使用的数据,从 load 函数返回的对象可以包含 promise 而不是数据本身。对于服务端 load 函数,这将导致数据在导航(或初始页面加载)后流式传输

防止瀑布问题

最大的性能杀手之一是所谓的瀑布问题,即一系列按顺序发出的请求。这可能发生在服务端或浏览器中。

  • 当您的 HTML 请求 JS,然后请求 CSS,然后请求背景图片和网络字体时,可能会在浏览器中出现资源瀑布。SvelteKit 通过添加 modulepreload 标签或头部,将为您解决这类问题,但您应该查看开发工具中的网络标签以检查是否需要预加载其他资源。如果您使用网络字体,请特别注意这一点,因为它们需要手动处理。
  • 如果通用 load 函数发起 API 调用来获取当前用户,然后使用该响应中的详细信息来获取已保存项目的列表,然后使用该响应来获取每个项目的详细信息,浏览器最终将发出多个顺序请求。这对性能来说是致命的,尤其是对于物理位置远离您后端的用户。在可能的情况下使用服务端 load 函数来避免这个问题。
  • 服务端 load 函数也不能免疫瀑布问题(尽管它们的代价要小得多,因为它们很少涉及高延迟的往返)。例如,如果您查询数据库以获取当前用户,然后使用该数据进行第二次查询以获取已保存项目的列表,使用带有数据库连接的单个查询通常会更高效。

托管

为了最小化延迟,你的前端应该与后端位于同一数据中心。对于没有中央后端的站点,许多 SvelteKit 适配器支持部署到 edge,这意味着从离用户最近的服务器处理每个用户的请求。这可以显著减少加载时间。一些适配器甚至支持按路由配置部署。您还应该考虑从 CDN(通常是 edge 网络)提供图片服务 — 许多 SvelteKit 适配器的主机会自动完成这项工作。

确保您的主机使用 HTTP/2 或更新版本。Vite 的代码分割创建了许多小文件以提高缓存能力,这会带来出色的性能表现,但这建立在您的文件可以通过 HTTP/2 并行加载的前提下。

延伸阅读

在大多数情况下,构建高性能的 SvelteKit 应用程序与构建任何高性能的 Web 应用程序是一样的。您应该能够将这些来自通用性能资源(如 Core Web Vitals)的信息应用到任何您构建的 Web 体验中。

在 GitHub 编辑此页面

上一页 下一页