Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tough-days-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/react': major
---

Fix StaticHtml performance by implementing `React.memo` for proper re-render prevention.
16 changes: 7 additions & 9 deletions packages/integrations/react/src/static-html.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createElement as h } from 'react';
import { createElement as h, memo } from 'react';

/**
* Astro passes `children` as a string of HTML, so we need
Expand Down Expand Up @@ -26,12 +26,10 @@ const StaticHtml = ({
};

/**
* This tells React to opt-out of re-rendering this subtree,
* In addition to being a performance optimization,
* this also allows other frameworks to attach to `children`.
*
* See https://preactjs.com/guide/v8/external-dom-mutations
* React.memo is the modern functional equivalent of shouldComponentUpdate.
*
* By returning `true` in the comparison function (the second argument),
* we tell React that the props are "equal" and it should skip re-rendering,
* effectively making this subtree static.
*/
StaticHtml.shouldComponentUpdate = () => false;

export default StaticHtml;
export default memo(StaticHtml, () => true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that memo is indeed noted as the equivalent at the end of https://react.dev/reference/react/Component#shouldcomponentupdate. Memo docs: https://react.dev/reference/react/memo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that memo is indeed noted as the equivalent at the end of https://react.dev/reference/react/Component#shouldcomponentupdate. Memo docs: https://react.dev/reference/react/memo

Thanks for checking! You are correct that they serve the same purpose. But actually, shouldComponentUpdate is only for Class components, so it gets ignored here. The old code wasn't really running. Switching to memo ensures it works properly.

Sorry if I am wrong

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't be surprised if it worked, undocumented

Loading