通用渲染骨架在sveltekit中加载

问题描述 投票:0回答:1

我正在开发一个 SvelteKit 项目,目标是实现通用渲染。我的目标是让第一个请求进行服务器端渲染(SSR),然后切换到客户端渲染(CSR)以进行后续导航。但是,我遇到了一个似乎无法解决的问题。

问题:

从一个页面导航到另一页面(例如,从主页导航到产品)时,只有完全获取目标页面的数据后才会进行导航。理想情况下,我希望目标页面立即加载并在获取数据时显示各个组件的加载器。这样,用户就不会在导航发生之前等待整个页面加载。

我尝试在组件中使用 Svelte 的 {#await ...} 块来实现此功能,但我面临着困境:

在加载函数中使用await: SSR 工作正常,但页面导航会延迟,直到获取数据为止。

在加载函数中跳过await: 导航立即发生,但 SSR 中断。

我的设置:

这是我正在使用的简化版本:

// +page.svelte

<script lang="ts">
  let { data } = $props();
</script>

<h1>TODOS</h1>
{#await data.todos}
  Loading ...
{:then todos}
  {#each todos as todo}
    <div>{todo.todo}</div>
  {/each}
{/await}

// +page.ts

type Todo = {
  id: number;
  todo: string;
  completed: boolean;
  userId: number;
};

export async function load({ fetch }) {
  const getTodos = () =>
    fetch('https://dummyjson.com/todos')
      .then(r => r.json())
      .then((r): { todos: Todo[] } => r.todos);
  return {
    todos: getTodos(), // await getTodos()
  };
}

// /产品/+page.svelte

<script lang="ts">
  let { data } = $props();
</script>

<h1>Products</h1>
{#await data.products}
  Loading ...
{:then products}
  {#each products as product}
    <div>{product.title}</div>
  {/each}
{/await}

// /产品/+page.ts

type Product = {
  id: number;
  title: string;
};

export async function load({ fetch }) {
  const getProducts = () =>
    fetch('https://dummyjson.com/products')
      .then(r => r.json())
      .then(r => r.products as Product[]);
  return {
    products: getProducts(), // await getProducts(),
  };
}

我在寻找什么:

有人设法解决这个问题,还是我缺少更好的方法?我很想获得一些建议或示例,了解如何在第一个请求时使用 SSR 正确实现通用渲染,并在之后使用各个组件加载器实现流畅的客户端导航。

P.S 我尝试过浏览器? getTodos() : 等待 getTodos() 但我遇到了水合不匹配错误

svelte sveltekit
1个回答
0
投票

您可以尝试使用

isDataRequest
参数中的
PageServerLoad

export const load: PageServerLoad = async ({ isDataRequest, params }) => {
    const data = get(params.id);

    return {
        data: isDataRequest ? data : await data,
    };
}

有关流式承诺的链接文档:
https://kit.svelte.dev/docs/load#streaming-with-promises

然后使用异步块来显示骨架。

注意:它可能无法在开发模式下工作,因此请先构建站点。


您可以在本文中查看有关此方法的更多信息:
https://geoffrich.net/posts/conditionally-stream-data/\ (请记住,您不需要嵌套 Promise 对象,SvelteKit 1.x 行为)

© www.soinside.com 2019 - 2024. All rights reserved.