perf: faster page navigation by speeding up createClientConfig, speed up version fetching, speed up lexical init. Up to 100x faster
If you had a lot of fields and collections, createClientConfig would be extremely slow, as it was copying a lot of memory. In my test config with a lot of fields and collections, it took 4 seconds(!!).
And not only that, it also ran between every single page navigation.
This PR significantly speeds up the createClientConfig function. In my test config, its execution speed went from 4 seconds to 50 ms. Additionally, createClientConfig is now properly cached in both dev & prod. It no longer runs between every single page navigation. Even if you trigger a full page reload, createClientConfig will be cached and not run again. Despite that, HMR remains fully-functional.
This will make payload feel noticeably faster for large configs - especially if it contains a lot of richtext fields, as it was previously deep-copying the relatively large richText editor configs over and over again.
Before - 40 sec navigation speed
https://github.com/user-attachments/assets/fe6b707a-459b-44c6-982a-b277f6cbb73f
After - 1 sec navigation speed
https://github.com/user-attachments/assets/384fba63-dc32-4396-b3c2-0353fcac6639
Todo
- [x] Implement ClientSchemaMap and cache it, to remove createClientField call in our form state endpoint
- [x] Enable schemaMap caching for dev
- [x] Cache lexical clientField generation, or add it to the parent clientConfig
Lexical changes
Red: old / removed Green: new
Future plans for a different PR:
While the calculation of the richtext client config / map is now cached and only happens once, we still send the result of it to the client between every single navigation. I would like to only send it to the client once and keep it cached on the client:
Speed up version queries
This PR comes with performance optimizations for fetching versions before a document is loaded. Not only does it use the new select API to limit the fields it queries, it also completely skips a database query if the current document is published.
Speed up lexical init
Removes a bunch of unnecessary deep copying of lexical objects which caused higher memory usage and slower load times. Additionally, the lexical default config sanitization now happens less often.