SvelteKit静态站点如何消除HTML中冗余的数据获取脚本?
问题
使用SvelteKit搭配static adapter构建静态站点,已开启预渲染(prerender)。在+page.ts的服务端load函数中通过fetch获取博客文章数据后,生成的HTML文件里仍包含一段data-sveltekit-fetched类型的脚本,里面重复了已经嵌入页面的相同数据。想知道这段冗余脚本的作用,以及如何配置移除它。
相关代码
+page.ts代码:
import type { Post } from '$lib/types'; export async function load({ fetch }) { const response = await fetch('../api/posts'); const posts: Post[] = await response.json(); return { posts }; } export const prerender = true;
生成的冗余脚本示例:
<script type="application/json" data-sveltekit-fetched data-url="/api/posts"> {"status":200, ... 完整数据内容 ...} </script>
解决方案
冗余脚本的作用
这段data-sveltekit-fetched脚本是SvelteKit客户端 hydration 机制的产物:
- 预渲染时页面已把数据嵌入HTML,但SvelteKit会保留一份数据副本,用于客户端初始化时快速复用,避免重复发起网络请求。
- 但在纯静态、无客户端交互的站点场景下,这份副本属于完全冗余。
移除方案
方案1:直接读取本地数据文件(替代fetch)
如果博客数据是本地文件(如posts.json、Markdown文件),直接在load函数中读取文件,而非通过fetch调用API:
import type { Post } from '$lib/types'; import fs from 'fs/promises'; import path from 'path'; export async function load() { const filePath = path.join(process.cwd(), 'src', 'data', 'posts.json'); const posts: Post[] = JSON.parse(await fs.readFile(filePath, 'utf-8')); return { posts }; } export const prerender = true;
这种方式不会触发SvelteKit的fetch缓存逻辑,自然不会生成冗余脚本。
方案2:禁用客户端hydration
如果页面不需要任何客户端交互,在+page.ts中添加hydrate: false完全禁用 hydration:
import type { Post } from '$lib/types'; export async function load({ fetch }) { const response = await fetch('../api/posts'); const posts: Post[] = await response.json(); return { posts }; } export const prerender = true; export const hydrate = false;
此操作会生成纯静态HTML,所有 hydration 相关脚本(包括冗余的data-sveltekit-fetched)都会被移除。但页面会失去客户端交互能力,需根据实际场景选择。
方案3:给API路由开启预渲染
若必须保留fetch调用API的方式,确保对应API路由(src/routes/api/posts/+server.ts)也开启预渲染:
export const prerender = true;
SvelteKit会预渲染API响应数据,部分版本会自动优化掉重复的data-sveltekit-fetched脚本。
内容的提问来源于stack exchange,提问作者Friedrich Siever
相关产品推荐
相关产品推荐

