A Jōtai utility package for better performance.
# npm
npm i jotai-scheduler
# yarn
yarn add jotai-scheduler
# pnpm
pnpm add jotai-scheduler
The usage of jotai-scheduler is very similar to jotai itself. The only difference from the native Jotai API is that it requires passing a priority parameter:
-
jotai
import { useAtomValue } from 'jotai-scheduler' const num = useAtomValue(anAtom, {});
-
jotai-scheduler
import { LOW_PRIORITY, useAtomValueWithSchedule } from 'jotai-scheduler' const num = useAtomValueWithSchedule(anAtom, { priority: LOW_PRIORITY, });
The field priority
can be can be IMMEDIATE_PRIORITY
, NORMAL_PRIORITY
, or LOW_PRIORITY
. If you don't pass any priority, it will use NORMAL_PRIORITY
by default, and its behavior is the same as jotai.
Now you can use jotai-scheduler to replace jotai in your project.
useAtom
-->useAtomWithSchedule
useAtomValue
-->useAtomValueWithSchedule
useSetAtom
-->useSetAtomWithSchedule
You can view a detailed comparison and live demo on CodeSandbox.
Let's say we have an app that contains typical elements such as the Header, Footer, Sidebar, and Content:
Every element represents a component, and all these components share the same state. When we click the button, the state will be updated, and all components will be re-rendered. While we were using jotai, the code might have looked like this:
const anAtom = atom(0);
const Header = () => {
const num = useAtomValue(anAtom);
return <div className="header">Header-{num}</div>;
};
const Footer = () => {
const num = useAtomValue(anAtom);
return <div className="footer">Footer-{num}</div>;
};
const Sidebar = () => {
const num = useAtomValue(anAtom);
return <div className="sidebar">Sidebar-{num}</div>;
};
const Content = () => {
const [num, setNum] = useAtom(anAtom);
return (
<div className="content">
<div>Content-{num}</div>
<button onClick={() => setNum((num) => ++num)}>+1</button>
</div>
);
};
When we click the button, the rendering seems a bit laggy, right? That's because we need to wait for all the components to render.
When we open the Chrome Performance tool, we can see:
This means it is not good for the user experience. But not all components have the same priority. A better way is to render the important content first, and then the rest, the more important content will be shown more quickly.
Let's say the priority of those components is Content > Sidebar > Header = Footer, then we can pass a priority
field to represent the priority of each component.
Now let's use jotai-scheduler to optimize it:
const anAtom = atom(0);
const Header = () => {
const num = useAtomValueWithSchedule(anAtom, {
priority: LOW_PRIORITY,
});
return <div className="header">Header-{num}</div>;
};
const Footer = () => {
const num = useAtomValueWithSchedule(anAtom, {
priority: LOW_PRIORITY,
});
return <div className="footer">Footer-{num}</div>;
};
const Sidebar = () => {
const num = useAtomValueWithSchedule(anAtom);
return <div className="sidebar">Sidebar-{num}</div>;
};
const Content = () => {
const [num, setNum] = useAtomWithSchedule(anAtom, {
priority: IMMEDIATE_PRIORITY,
});
return (
<div className="content">
<div>Content-{num}</div>
<button onClick={() => setNum((num) => ++num)}>+1</button>
</div>
);
};
When we open the Chrome Performance tool, we can see:
The performance is better. Important content will be displayed to users more quickly, thereby providing a better user experience.