Loading...
Loading...
Use this skill when optimizing Jazz applications for speed, responsiveness, and scalability. Covers crypto setup, efficient data modeling, and UI patterns to prevent lag.
npx skill4agent add garden-co/jazz jazz-performancejazz-schema-designjazz-permissions-security// ❌ SLOW: Inline CoValue creation creates a dependency chain
const task = await Task.create({
column: {
board: { team: myTeam }
}
});
// ✅ FASTER: Flat structure with references
const board = await Board.create({ team: myTeam });
const column = await Column.create({ board });
const task = await Task.create({ column });sameAsContainerimport { setDefaultSchemaPermissions } from "jazz-tools";
setDefaultSchemaPermissions({
onInlineCreate: "sameAsContainer",
});sameAsContainersameAsContainerz.string()z.string()z.object()z.object()const Sprite = co.map({
// ✅ FAST: Position updated as one unit
position: z.object({ x: z.number(), y: z.number() }),
});
mySprite.$jazz.set('position', { x: 20, y: 30 });const SomeItem = co.map({
content: co.richText()
});
const SomeList = co.list(SomeItem);
// ❌ SLOW: List deeply loaded unnecessarily
const DisplayComponent = (props: { item: co.loaded<typeof SomeItem, {
content: true
}> }) => {
return <div>{props.item.content}</div>
}
const MyTopLevelComponent = () => {
const ITEMS_PER_PAGE = 20;
// **ALL list items are deeply loaded**
const myDeeplyLoadedData = useCoState(SomeList, someListId, {
resolve: {
$each: {
content: true
}
}
});
const [page, setPage] = useState(0);
if (!myDeeplyLoadedData.$isLoaded) return <div>Loading...</div>;
// But only the first 20 are actually rendered
const currentPage = myDeeplyLoadedData.slice(
page * ITEMS_PER_PAGE,
(page + 1) * ITEMS_PER_PAGE
);
return currentPage.map(item => <DisplayComponent key={item.$jazz.id} item={item} />)
}
// ✅ FAST: Deep loading only when a component is rendered
const DisplayComponent = (props: { itemId: string }) => {
const myItem = useCoState(SomeItem, props.itemId, {
resolve: {
content: true
}
});
if (!myItem.$isLoaded) return <div>Loading...</div>;
return <div>{myItem.content}</div>
}
const MyTopLevelComponent = () => {
const ITEMS_PER_PAGE = 20;
const myShallowlyLoadedData = useCoState(SomeList, someListId);
const [page, setPage] = useState(0);
if (!myShallowlyLoadedData.$isLoaded) return <div>Loading...</div>;
const currentPage = myShallowlyLoadedData.slice(
page * ITEMS_PER_PAGE,
(page + 1) * ITEMS_PER_PAGE
);
return currentPage.map(item => <DisplayComponent key={item.$jazz.id} itemId={item.$jazz.id} />)
}equalityFnuseMemo// ❌ SLOW: Expensive computation in selector
const project = useCoState(Project, id, {
select: (p) => ({
name: p.name,
sortedTasks: p.tasks.sort(expensiveSort) // Runs on every update!
})
});
// ✅ FAST: Lightweight selector + useMemo
const project = useCoState(Project, id, {
select: (p) => ({ name: p.name, tasks: p.tasks }),
equalityFn: (a, b) => a.name === b.name && a.tasks.length === b.tasks.length
});
const sortedTasks = useMemo(() =>
project.tasks.sort(expensiveSort),
[project.tasks]
);sameAsContainerz.string()z.object()useMemosameAsContainerz.string()z.object()sameAsContaineruseMemo