Adopting the compiler in Sanity Studio #33
stipsan
started this conversation in
Case Studies
Replies: 1 comment 2 replies
-
Hello, very interesting insights, thank you so much for sharing ! |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
At Sanity we've been testing the compiler on Sanity Studio, to help improve the end user experience for people that are creating content, editing content, simply working with all sorts of content.
As the Studio is a real-time application (no save button here!), multiplayer and collaborative (constant state reconciliation of your local mutations and the remote "source of truth"), with potentially large documents, deeply nested fields, granular revision history, complex custom validation rules, sophisticated ACL that's also real-time. Let's just say that there are a lot of stuff going on that can interrupt you typing into a field and then cause jank.
When the React Compiler was announced, and given that its main focus is rerender performance, it made sense for us to join the WG and test out its potential.
While we've been testing the compiler internally ever since, we haven't been able to test it in production on our npm libraries, and Sanity Studio is distributed on npm, since we have to maintain compatibility with React 18.
With the beta launch adding official support for React 18 that changed, and we have so far this week shipped these libraries that are optimised by the compiler, and thus depend on the
react-compiler-runtime
dependency:react-rx
– which lives on the hottest paths on our state management in the Sanity Studio, as well as many other apps in our production.@sanity/ui
– our design system, used by all our apps, and the Studio, one of our most performance sensitive libraries and the most hand-optimised of them all.@portabletext/editor
– our rich text editor, extremely hand-optimised, and performance sensitive as it has to grapple with Google-Docs-style problems.The rollout has been pretty painless, and we have so far not encountered an issue where we had to turn off the compiler or add
'use no memo'
directives. Onlyreact-rx
has zero warnings fromeslint-plugin-react-compiler
, while@sanity/ui
and@portabletext/editor
have some warnings. What that has meant in practice to us is that there are opportunities where we can refactor code so that the compiler can optimise it, and reap further performance improvements.The only issues we've encountered that we've forwarded to the core team has been cases where the compiler thinks we're violating a rule of react, that has turned out to be a valid pattern that the compiler needs to support.
For example for a while the compiler refused to optimise this pattern:
The compiler have since added full support for this pattern ❤
In practice this means that the compiler has either skipped over a component it could've optimised safely, or it'll uncover a bug in our code that we should fix any way.
In fact, some of the bugs it has helped us uncover have been pretty wild.
It's not just that the
eslint-plugin-react-compiler
itself works really well as a bug detection tool, I'm talking about howbabel-plugin-react-compiler
has helped solve "cold case" bugs by forcing them to the surface.While enabling the compiler on
@portabletext/editor
we saw a couple of tests failing in its gherkin testing suite, that runs e2e tests with playwright.@christianhg dove in to verify what was going on and uncovered that the failing tests had actually been false positives all along. For a long time we've seen that our editor sometimes failed to toggle bold/italics at the edge of decorators, and we couldn't find a way to reliably reproduce this case. Enabling the compiler on our vitest testing suite forced this edge case to the surface and made it consistently happen and lead to us resolving the case 🥳
The next step for us is to enable the compiler on the Sanity Studio codebase itself, we're currently testing it, and our eFPS suite is reporting really good numbers:
Our eFPS suite measures the FPS during editing interactions, like typing into a title field, rich text fields, different scenarios where any latency really impacts the user experience and can prevent a creative professional from being able to stay in a good and productive feedback loop.
A 20-30% increase in how many frames that can render per second is really significant! I want to put it into context:
@portabletext/editor
,@sanity/ui
and@portabletext/editor
.babel-plugin-react-compiler
and simply turned it on for thesanity
codebase, which drives Sanity Studio.Some more context, in
@sanity/ui
and@portabletext/editor
the compiler is skipping components on some really hot paths. Some of the components will need to be refactored, as they are genuinely breaking the rules of react. Others will need to wait for the compiler to support use cases that are on its todo-list, for example code that usestry/catch
.In other words we see massive untapped potential that we'll be able to reap as we incrementally refactor the codebase and report issues to the core team so that the compiler can learn to handle valid cases that it's currently skipping over and not optimising.
For the Sanity Studio itself this is especially true as the linter currently reports 80(!) issues, which happens to be most of the hottest paths in our codebase. A lot of them are already hand optimised, but we know that there are cases where a couple of unstable dependencies are able to poke holes through these manual optimisations that the react compiler is doing a good job at solving. We expect a significant impact once we're able to have the compiler handle those.
All in all, don't sleep on the compiler! Incrementally adopt it like we have:
eslint-plugin-react-compiler
and use it to detect bugs that need to be fixed.babel-plugin-react-compiler
to staged envs to measure its impact and verify it doesn't cause regressions.react-compiler-runtime
to ship optimised code for react 18.Beta Was this translation helpful? Give feedback.
All reactions