文档
性能

性能

Quaere 在各种 web 应用中提供了关键功能,因此 性能 是重中之重。

Quaere 内置的 缓存重复数据删除 会跳过不必要的网络请求,但 useQuery hook 本身的性能仍然很重要。在一个复杂的应用中,单个页面渲染可能会调用数百次 useQuery

Quaere 确保你的应用具有:

  • 没有不必要的请求
  • 没有不必要的重新渲染
  • 没有不必要的代码导入

而无需你更改任何代码。

重复数据删除

在应用中重用 Quaere hooks 非常常见。例如,一个应用渲染 5 次当前用户的头像:

function Avatar() {
  const { data, error } = useQuery({ query: userQuery });
 
  if (error) return <Error />;
  if (!data) return <Spinner />;
 
  return <img src={data.avatar_url} />;
}
 
function App() {
  return (
    <>
      <Avatar />
      <Avatar />
      <Avatar />
      <Avatar />
      <Avatar />
    </>
  );
}

每个 <Avatar> 组件内部都有一个 useQuery hook。由于它们具有相同的 Quaere key,并且几乎同时渲染,因此 只会发送 1 个网络请求

你可以在任何地方重用数据 hooks(比如上面示例中的 useUser),而不用担心性能或重复请求。

还有一个 staleTime 选项用于覆盖默认的数据被视为过期的毫秒数。

深度比较

Quaere 默认 深度比较 数据更改。如果 data 值没有改变,则不会触发重新渲染。

依赖收集

useQuery 返回 4 个 有状态的 值:dataerrorisLoadingisFetching,每个都可以独立更新。例如,如果我们在一个完整的数据请求生命周期中打印这些值,则将如下所示:

function App() {
  const { data, error, isLoading, isFetching } = useQuery({ query: userQuery });
  console.log(data, error, isLoading, isFetching);
  return null;
}

在最坏的情况下(第一个请求失败,然后重试成功),你将看到 4 行日志:

// console.log(data, error, isLoading, isFetching)
undefined undefined true true  // => 开始 fetching
undefined Error false false     // => 结束 fetching,出现错误
undefined Error true true      // => 开始重试
Data undefined false false      // => 重试结束,得到数据

状态的改变是有道理的。但这也意味着组件 渲染了 4 次

如果我们将组件更改为只使用 data

function App() {
  const { data } = useQuery({ query: userQuery });
  console.log(data);
  return null;
}

神奇的事情发生了 - 现在只有 2 次重新渲染

// console.log(data)
undefined; // => hydration / 初始渲染
Data; // => 重试结束,得到数据

内部发生了完全相同的过程,第一个请求出现了错误,然后我们重试得到了数据。但是,Quaere 只更新了组件使用的状态,即:data

Tree Shaking

Quaere 满足 tree-shakeable (opens in a new tab) 且没有副作用。这意味着如果你只导入核心的 useQuery API,像 useMutation 这样的未使用的 API 将不会绑定到你的应用中。