refactor: memoize everything

This commit is contained in:
iCrawl
2022-08-23 19:39:31 +02:00
parent abd3fc8ceb
commit 92933c2b61
5 changed files with 150 additions and 129 deletions

View File

@@ -21,5 +21,5 @@ export function RouterTransition() {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [router.asPath]); }, [router.asPath]);
return <NavigationProgress />; return <NavigationProgress color="blurple" />;
} }

View File

@@ -1,7 +1,7 @@
import { createStyles, Group, Text, NavLink, Box } from '@mantine/core'; import { createStyles, Group, Text, NavLink, Box } from '@mantine/core';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { type Dispatch, type SetStateAction, useEffect, useState } from 'react'; import { type Dispatch, type SetStateAction, useEffect, useState, useMemo } from 'react';
import { import {
VscSymbolClass, VscSymbolClass,
VscSymbolEnum, VscSymbolEnum,
@@ -101,7 +101,7 @@ export function SidebarItems({
const router = useRouter(); const router = useRouter();
const [asPathWithoutQueryAndAnchor, setAsPathWithoutQueryAndAnchor] = useState(''); const [asPathWithoutQueryAndAnchor, setAsPathWithoutQueryAndAnchor] = useState('');
const { classes } = useStyles(); const { classes } = useStyles();
const groupItems = groupMembers(members); const groupItems = useMemo(() => groupMembers(members), [members]);
useEffect(() => { useEffect(() => {
setAsPathWithoutQueryAndAnchor(router.asPath.split('?')[0]?.split('#')[0] ?? ''); setAsPathWithoutQueryAndAnchor(router.asPath.split('?')[0]?.split('#')[0] ?? '');

View File

@@ -28,7 +28,7 @@ import type { MDXRemoteSerializeResult } from 'next-mdx-remote';
import Image from 'next/future/image'; import Image from 'next/future/image';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { type PropsWithChildren, useState, useEffect } from 'react'; import { type PropsWithChildren, useState, useEffect, useMemo } from 'react';
import { VscChevronDown, VscGithubInverted, VscPackage, VscVersions } from 'react-icons/vsc'; import { VscChevronDown, VscGithubInverted, VscPackage, VscVersions } from 'react-icons/vsc';
import { WiDaySunny, WiNightClear } from 'react-icons/wi'; import { WiDaySunny, WiNightClear } from 'react-icons/wi';
import useSWR from 'swr'; import useSWR from 'swr';
@@ -170,18 +170,25 @@ export function SidebarLayout({
const { classes } = useStyles({ openedLib: openedLibPicker, openedVersion: openedVersionPicker }); const { classes } = useStyles({ openedLib: openedLibPicker, openedVersion: openedVersionPicker });
const versionMenuItems = const versionMenuItems = useMemo(
() =>
versions?.map((item) => ( versions?.map((item) => (
<Menu.Item key={item} component={NextLink} href={`/docs/packages/${packageName ?? 'builders'}/${item}`}> <Menu.Item key={item} component={NextLink} href={`/docs/packages/${packageName ?? 'builders'}/${item}`}>
{item} {item}
</Menu.Item> </Menu.Item>
)) ?? []; )) ?? [],
[versions],
);
const breadcrumbs = asPathWithoutQueryAndAnchor.split('/').map((path, idx, original) => ( const breadcrumbs = useMemo(
() =>
asPathWithoutQueryAndAnchor.split('/').map((path, idx, original) => (
<Link key={idx} href={original.slice(0, idx + 1).join('/')} passHref> <Link key={idx} href={original.slice(0, idx + 1).join('/')} passHref>
<Anchor component="a">{path}</Anchor> <Anchor component="a">{path}</Anchor>
</Link> </Link>
)); )),
[asPathWithoutQueryAndAnchor],
);
return ( return (
<AppShell <AppShell

View File

@@ -1,4 +1,5 @@
import { createStyles, Group, Text, Box, Stack, ThemeIcon, useMantineColorScheme } from '@mantine/core'; import { createStyles, Group, Text, Box, Stack, ThemeIcon, useMantineColorScheme } from '@mantine/core';
import { useMemo } from 'react';
import { VscListSelection, VscSymbolMethod, VscSymbolProperty } from 'react-icons/vsc'; import { VscListSelection, VscSymbolMethod, VscSymbolProperty } from 'react-icons/vsc';
import type { ApiClassJSON, ApiInterfaceJSON } from '~/DocModel/ApiNodeJSONEncoder'; import type { ApiClassJSON, ApiInterfaceJSON } from '~/DocModel/ApiNodeJSONEncoder';
@@ -36,7 +37,9 @@ export function TableOfContentItems({
const { colorScheme } = useMantineColorScheme(); const { colorScheme } = useMantineColorScheme();
const { classes } = useStyles(); const { classes } = useStyles();
const propertyItems = properties.map((prop) => ( const propertyItems = useMemo(
() =>
properties.map((prop) => (
<Box<'a'> key={prop.name} href={`#${prop.name}`} component="a" className={classes.link}> <Box<'a'> key={prop.name} href={`#${prop.name}`} component="a" className={classes.link}>
<Group> <Group>
<Text sx={{ textOverflow: 'ellipsis', overflow: 'hidden' }} className="line-clamp-1"> <Text sx={{ textOverflow: 'ellipsis', overflow: 'hidden' }} className="line-clamp-1">
@@ -44,10 +47,16 @@ export function TableOfContentItems({
</Text> </Text>
</Group> </Group>
</Box> </Box>
)); )),
[properties],
);
const methodItems = methods.map((member) => { const methodItems = useMemo(
const key = `${member.name}${member.overloadIndex && member.overloadIndex > 1 ? `:${member.overloadIndex}` : ''}`; () =>
methods.map((member) => {
const key = `${member.name}${
member.overloadIndex && member.overloadIndex > 1 ? `:${member.overloadIndex}` : ''
}`;
return ( return (
<Box<'a'> key={key} component="a" href={`#${key}`} className={classes.link}> <Box<'a'> key={key} component="a" href={`#${key}`} className={classes.link}>
@@ -63,7 +72,9 @@ export function TableOfContentItems({
</Group> </Group>
</Box> </Box>
); );
}); }),
[methods],
);
return ( return (
<Box sx={{ wordBreak: 'break-all' }} pb="xl"> <Box sx={{ wordBreak: 'break-all' }} pb="xl">

View File

@@ -1,7 +1,7 @@
import { Anchor, Box, Code, Text, useMantineColorScheme } from '@mantine/core'; import { Anchor, Box, Code, Text, useMantineColorScheme } from '@mantine/core';
import { DocNodeKind, StandardTags } from '@microsoft/tsdoc'; import { DocNodeKind, StandardTags } from '@microsoft/tsdoc';
import Link from 'next/link'; import Link from 'next/link';
import { Fragment, type ReactNode } from 'react'; import { Fragment, useCallback, type ReactNode } from 'react';
import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter'; import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus, ghcolors } from 'react-syntax-highlighter/dist/cjs/styles/prism'; import { vscDarkPlus, ghcolors } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { BlockComment } from './BlockComment'; import { BlockComment } from './BlockComment';
@@ -16,10 +16,11 @@ import type { DocCommentJSON } from '~/DocModel/comment/RootComment';
export function TSDoc({ node }: { node: AnyDocNodeJSON }): JSX.Element { export function TSDoc({ node }: { node: AnyDocNodeJSON }): JSX.Element {
const { colorScheme } = useMantineColorScheme(); const { colorScheme } = useMantineColorScheme();
const createNode = useCallback(
(node: AnyDocNodeJSON, idx?: number): ReactNode => {
let numberOfExamples = 0; let numberOfExamples = 0;
let exampleIndex = 0; let exampleIndex = 0;
const createNode = (node: AnyDocNodeJSON, idx?: number): ReactNode => {
switch (node.kind) { switch (node.kind) {
case DocNodeKind.PlainText: case DocNodeKind.PlainText:
return ( return (
@@ -114,7 +115,9 @@ export function TSDoc({ node }: { node: AnyDocNodeJSON }): JSX.Element {
} }
return null; return null;
}; },
[colorScheme],
);
return ( return (
<Box> <Box>