Tips for maximising Jazz performance
Use the best crypto implementation for your platform
The fastest implementations are (in order):
- Node-API crypto (only available in some Node/Deno environments) or RNQuickCrypto on React Native
- WASM crypto
- JavaScript fallback (slowest, but most compatible)
Check whether your environment supports Node-API. Some edge runtimes may not enable WASM by default.
Minimise group extensions
Group extensions make it easy to cascade permissions and they’re fast enough for most cases. However, performance can slow down when many parent groups need to load in the dependency chain. To avoid this, create and reuse groups manually when their permissions stay the same for both CoValues over time.
Note: Implicit CoValue creation extends groups automatically. Be careful about how you create nested CoValues if you are likely to build long dependency chains.
const SubSubItem = co.map({ name: z.string() }); const SubItem = co.map({ subSubItem: SubSubItem }); const Item = co.map({ subItem: SubItem }); // Implicit CoValue creation // Results in Group extension for subItem and subSubItem's owners. const item = Item.create({ subItem: { subSubItem: { name: "Example" } } }); // Explicit CoValue creation // Does not result in Group extension. const fasterItem = Item.create({ subItem: SubItem.create({ subSubItem: SubSubItem.create({ name: "Example" }) }) }) // Alternative const subSubItem = SubSubItem.create({ name: "Example"}); const subItem = SubItem.create({ subSubItem: subSubItem }); const fasterItem = Item.create({ subItem: subItem });
Choose simple datatypes where possible
CoValues will always be slightly slower to load than their primitive counterparts. For most cases, this is negligible.
In data-heavy apps where lots of data has to be loaded at the same time, you can choose to trade off some of the flexibility of CoValues for speed by opting for primitive data types.
z.string()
vs CoTexts
In case you use a CoText, Jazz will enable character-by-character collaboration possibilities for you. However, in many cases, users do not expect to be able to collaborate on the text itself, and are happy with replacing the whole string at once, especially shorter strings. In this case, you could use a z.string()
for better performance.
Examples:
- names
- URLs
- phone numbers
z.object()/z.tuple()
vs CoMaps
CoMaps allow granular updates to objects based on individual keys. If you expect your whole object to be updated at once, you could consider using the z.object()
or z.tuple()
type. Note that if you use these methods, you must replace the whole value if you choose to update it.
Examples:
- locations/co-ordinates
- data coming from external sources
- data which is rarely changed after it is created
const Sprite = co.map({ position: z.object({ x: z.number(), y: z.number() }), }); const Location = co.map({ position: z.tuple([z.number(), z.number()]), }); const mySprite = Sprite.create({ position: { x: 10, y: 10 }}); mySprite.$jazz.set("position", { x: 20, y: 20 }); // You cannot update 'x' and 'y' independently, only replace the whole object const myLocation = Location.create({ position: [26.052, -80.209] }); myLocation.$jazz.set("position", [-33.868, -63.987]) // Note: you cannot replace a single array element, only replace the whole tuple