question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

mdx-js/runtime: Avoid unstable element type to improve render performance

See original GitHub issue

Heya! We’re using the runtime package to live-render a preview window in netlify-cms-app. Naturally, the performance of this use case is never going to be amazing, but I believe I found a way to improve it noticeably.

Subject of the feature

mdx-js/runtime currently creates and calls a function that defines and returns an <MDXContent> component containing the desired content. I believe that, because this is a function that is defined on every render, its type is different on every render, so React’s reconciler will always tear down the DOM component tree rather than diffing the DOM elements, if mdx-js/runtime is used live.

https://github.com/mdx-js/mdx/blob/952f6dc5244013346ecf028a4d6d8973053de38f/packages/runtime/src/index.js#L6-L10

To test this, I made this change, and it seemed in a quick test to drop our render times by 4x. (From 4000ms… don’t ask 😛)

- React.createElement(MDXContent, props)
+ React.createElement(React.Fragment, null, MDXContent(props))

I’m anything but a React DOM expert or familiar with this codebase, so I imagine there’s a much, much better way to do this.

Expected behavior

The MDX runtime creates the same component type tree when given the same input, as far as the React reconciler is concerned.

Alternatives

I can’t think of any, besides “the performance is not quite as good as it could be.”

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
wooormcommented, Oct 20, 2021

evaluate is now used here too, in the RC for version 2. See: https://v2.mdxjs.com. I’ve added a note to the docs on evaluate so other folks repeat-evaluating stuff can use it too. Thanks or reporting!

0reactions
marcustyphooncommented, Sep 18, 2021

Memoizing the input doesn’t have anything to do with this PR, though I have of course done that!

Right now, when the input is changed, the entire DOM is unmounted and remounted. With this proposed change, the DOM is not unmounted, and only the changes that are made are applied to the DOM (i.e. a few keystrokes). See the React documentation here: https://reactjs.org/docs/reconciliation.html#the-diffing-algorithm.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Improve React Performance - Medium
This article highlights some optimizations we used to eliminate unnecessary re-rendering and improve the performance of our React ...
Read more >
Top 7 Tweaks and Tricks to Improve React Performance
Here we will explore 7 tweaks and tricks that will help to avoid most of the React performance issues for building any type...
Read more >
Analyze runtime performance - Microsoft Edge Development
Avoid layout as much as possible. Choose CSS that doesn't trigger layout at all. Painting may take up more time than any other...
Read more >
10 Ways to Minimize Reflows and Improve Performance
Craig provides ten tips to help improve responsiveness. ... of positions and dimensions of all elements, which leads to re-rendering part or ...
Read more >
content-visibility: the new CSS property that boosts ... - web.dev
Improve initial load time by skipping the rendering of offscreen ... most impactful new CSS properties for improving page load performance.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found