Skip to content

Commit

Permalink
chore: react optimizations and profiling optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
ovflowd committed Dec 28, 2024
1 parent 3acca71 commit 7dd604c
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 89 deletions.
57 changes: 32 additions & 25 deletions apps/site/components/Common/Select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,37 @@ const Select = <T extends string>({
[mappedValues, value]
);

const memoizedMappedValues = useMemo(() => {
return mappedValues.map(({ label, items }, key) => (
<SelectPrimitive.Group key={label?.toString() ?? key}>
{label && (
<SelectPrimitive.Label
className={classNames(styles.item, styles.label)}
>
{label}
</SelectPrimitive.Label>
)}

{items.map(({ value, label, iconImage, disabled }) => (
<SelectPrimitive.Item
key={value}
value={value}
disabled={disabled}
className={classNames(styles.item, styles.text)}
>
<SelectPrimitive.ItemText>
{iconImage}
<span>{label}</span>
</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))}
</SelectPrimitive.Group>
));
// We explicitly want to recalculate these values only when the values themselves changed
// This is to prevent re-rendering and re-calcukating the values on every render
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [JSON.stringify(values)]);

// Both change the internal state and emit the change event
const handleChange = (value: T) => {
setValue(value);
Expand Down Expand Up @@ -141,31 +172,7 @@ const Select = <T extends string>({
<ScrollPrimitive.Root type="auto">
<SelectPrimitive.Viewport>
<ScrollPrimitive.Viewport>
{mappedValues.map(({ label, items }, key) => (
<SelectPrimitive.Group key={label?.toString() ?? key}>
{label && (
<SelectPrimitive.Label
className={classNames(styles.item, styles.label)}
>
{label}
</SelectPrimitive.Label>
)}

{items.map(({ value, label, iconImage, disabled }) => (
<SelectPrimitive.Item
key={value}
value={value}
disabled={disabled}
className={classNames(styles.item, styles.text)}
>
<SelectPrimitive.ItemText>
{iconImage}
<span>{label}</span>
</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))}
</SelectPrimitive.Group>
))}
{memoizedMappedValues}
</ScrollPrimitive.Viewport>
</SelectPrimitive.Viewport>
<ScrollPrimitive.Scrollbar orientation="vertical">
Expand Down
59 changes: 35 additions & 24 deletions apps/site/components/Downloads/Release/ReleaseCodeBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import type { FC } from 'react';
import { useContext, useMemo } from 'react';

import AlertBox from '@/components/Common/AlertBox';
import CodeBox from '@/components/Common/CodeBox';
import Skeleton from '@/components/Common/Skeleton';
import JSXCodeBox from '@/components/JSX/CodeBox';
import Link from '@/components/Link';
import { createSval } from '@/next.jsx.compiler.mjs';
import { ReleaseContext, ReleasesContext } from '@/providers/releaseProvider';
import type { ReleaseContextType } from '@/types/release';
import { INSTALL_METHODS } from '@/util/downloadUtils';
import { highlightToHtml } from '@/util/getHighlighter';

import LinkWithArrow from './LinkWithArrow';

Expand All @@ -35,46 +36,56 @@ const parseSnippet = (s: string, releaseContext: ReleaseContextType) => {

const ReleaseCodeBox: FC = () => {
const { snippets } = useContext(ReleasesContext);
const {
installMethod: platform,
os,
packageManager,
release,
} = useContext(ReleaseContext);
const { installMethod, os, packageManager, release } =
useContext(ReleaseContext);

const t = useTranslations();

// Retrieves the current platform (Dropdown Item) based on the selected platform value
const currentPlatform = useMemo(
() => INSTALL_METHODS.find(({ value }) => value === platform),
[platform]
() => INSTALL_METHODS.find(({ value }) => value === installMethod),
[installMethod]
);

// Parses the snippets based on the selected platform, package manager, and release context
const parsedSnippets = useMemo(() => {
// Retrieves a snippet for the given Installation Method (aka Platform)
const platformSnippet = snippets.find(
s => s.name === platform.toLowerCase()
const installMethodSnippet = snippets.find(
({ name }) => name === installMethod.toLowerCase()
);

// Retrieves a snippet for the given Package Manager to be bundled with the Platform snippet
const packageManagerSnippet = snippets.find(
s => s.name === packageManager.toLowerCase()
({ name }) => name === packageManager.toLowerCase()
);

return parseSnippet(
// Bundles the Platform and Package Manager snippets
`${platformSnippet?.content ?? ''}\n${packageManagerSnippet?.content ?? ''}`,
// Passes a partial state of only the things we need to the parser
{ release, installMethod: platform, os } as ReleaseContextType
);
}, [snippets, release, platform, os, packageManager]);
// Prevents numerous recalculations of `sval` and `Shiki` when not necessary
// As we only want to parse the snippets when both the Platform and Package Manager snippets are available
if (installMethodSnippet && packageManagerSnippet) {
const content = parseSnippet(
// Bundles the Platform and Package Manager snippets
`${installMethodSnippet.content}\n${packageManagerSnippet.content}`,
// Passes a partial state of only the things we need to the parser
{ release, os } as ReleaseContextType
);

// We use Shikis's `hast-util-to-html` to convert the highlighted code into plain HTML (Pretty much using Rehype)
// This is actually faster than using `hast-util-to-jsx-runtime` and then rendering the JSX
// As it requires React's runtime to interpolate and build these components dynamically
// Which also leads to a lot o GC being emitted. (Tested via Profiling)
return highlightToHtml(content, os === 'WIN' ? 'ps1' : 'bash');
}

return '';
// Only change to these specific properties which are relevant for the re-rendering of the CodeBox
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [release.versionWithPrefix, installMethod, os, packageManager]);

// Determines the code language based on the OS
const codeLanguage = os === 'WIN' ? 'ps1' : 'bash';
const displayName = os === 'WIN' ? 'PowerShell' : 'Bash';

// Determines if the code box should render the skeleton loader
const renderSkeleton = os === 'LOADING' || platform === '';
const renderSkeleton = os === 'LOADING' || installMethod === '';

// Defines fallbacks for the currentPlatform object
const {
Expand All @@ -100,9 +111,9 @@ const ReleaseCodeBox: FC = () => {
)}

<Skeleton loading={renderSkeleton}>
<JSXCodeBox language={codeLanguage} className="min-h-[16rem]">
{parsedSnippets}
</JSXCodeBox>
<CodeBox language={displayName} className="min-h-[16rem]">
<code dangerouslySetInnerHTML={{ __html: parsedSnippets }} />
</CodeBox>
</Skeleton>

<span className="text-center text-xs text-neutral-800 dark:text-neutral-200">
Expand Down
38 changes: 0 additions & 38 deletions apps/site/components/JSX/CodeBox/index.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion apps/site/components/withLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { Layouts } from '@/types';

const layouts = {
about: AboutLayout,
home: props => <GlowingBackdropLayout kind="home" {...props} />,
home: GlowingBackdropLayout,
learn: LearnLayout,
page: DefaultLayout,
'blog-post': PostLayout,
Expand Down
2 changes: 1 addition & 1 deletion apps/site/layouts/GlowingBackdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type GlowingBackdropLayoutProps = PropsWithChildren<{
}>;

const GlowingBackdropLayout: FC<GlowingBackdropLayoutProps> = ({
kind,
kind = 'home',
children,
}) => (
<>
Expand Down

0 comments on commit 7dd604c

Please sign in to comment.