Optimize develop performance

This commit is contained in:
DefectingCat
2021-12-30 14:29:54 +08:00
parent 1d53fba072
commit b2698ad3b1
8 changed files with 83 additions and 66 deletions

View File

@ -7,7 +7,7 @@ import {
LinkBox, LinkBox,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FC, MouseEventHandler } from 'react'; import { FC, MouseEventHandler } from 'react';
import { AllPostsData } from 'lib/posts'; import { MyPost } from 'lib/posts';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { setFromPath } from 'features/router/routerSlice'; import { setFromPath } from 'features/router/routerSlice';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
@ -18,7 +18,7 @@ import dynamic from 'next/dynamic';
const Date = dynamic(() => import('./DateFormater')); const Date = dynamic(() => import('./DateFormater'));
interface Props { interface Props {
post: AllPostsData; post: MyPost;
} }
const ArchiveCard: FC<Props> = ({ post }) => { const ArchiveCard: FC<Props> = ({ post }) => {

View File

@ -7,7 +7,7 @@ interface Props {
} }
const PostIframe: FC<Props> = ({ src, children }) => { const PostIframe: FC<Props> = ({ src, children }) => {
const { initSrc, blur, targetRef } = useLazyLoad(src, '20px'); const { initSrc, blur, targetRef } = useLazyLoad(src, '8px');
const [isLargerThan768] = useMediaQuery('(min-width: 768px)'); const [isLargerThan768] = useMediaQuery('(min-width: 768px)');
return ( return (
@ -18,7 +18,13 @@ const PostIframe: FC<Props> = ({ src, children }) => {
transitionDuration="slower" transitionDuration="slower"
ratio={isLargerThan768 ? 16 / 9 : 1} ratio={isLargerThan768 ? 16 / 9 : 1}
> >
<Box as="iframe" src={initSrc} ref={targetRef}> <Box
as="iframe"
src={initSrc}
ref={targetRef}
borderRadius="10px"
overflow="hidden"
>
{children} {children}
</Box> </Box>
</AspectRatio> </AspectRatio>

View File

@ -25,7 +25,7 @@ const Hits: FC<StateResultsProvided<PostHits>> = ({
searchState, searchState,
searchResults, searchResults,
}) => { }) => {
const validQuery = searchState.query && searchState.query?.length >= 3; const validQuery = searchState.query && searchState.query?.length >= 1;
return ( return (
<> <>

View File

@ -69,6 +69,50 @@ export async function getSortedPostsData() {
}); });
} }
/**
* Get all posts without description and sorted.
* @returns
*/
export async function getAllPosts() {
// Get file names under /posts
const fileNames = await fs.readdir(postsDirectory);
const allPosts = await Promise.all(
fileNames.map(async (file) => {
// Remove ".md" from file name to get id
const id = file.replace(/\.md$/, '');
// Read markdown file as string
const fullPath = path.join(postsDirectory, file);
const fileContents = await fs.readFile(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents);
return {
id,
// Post content,
content: matterResult.content,
...({
...matterResult.data,
date: matterResult.data.date.toISOString(),
} as MyMatters),
};
})
);
// Sort posts by date
return allPosts.sort(({ date: a }, { date: b }) => {
if (a < b) {
return 1;
} else if (a > b) {
return -1;
} else {
return 0;
}
});
}
/** /**
* Paging, get all posts length * Paging, get all posts length
* @returns * @returns
@ -111,7 +155,9 @@ export interface PagingData {
postDatas: AllPostsData[]; postDatas: AllPostsData[];
} }
export function getPagingData(allPostsData: AllPostsData[], start?: string) { export async function getPagingData(start?: string) {
const allPostsData = await getSortedPostsData();
const totalNum = allPostsData.length; const totalNum = allPostsData.length;
const pagingSize = 10; const pagingSize = 10;
const allPages = Math.ceil(totalNum / pagingSize); const allPages = Math.ceil(totalNum / pagingSize);
@ -129,8 +175,7 @@ export function getPagingData(allPostsData: AllPostsData[], start?: string) {
} }
export async function getAllPostSlugs() { export async function getAllPostSlugs() {
const fileNames = await fs.readdir(postsDirectory); const allPosts = await getAllPosts();
const allPostsData = await getSortedPostsData();
// Returns an array that looks like this: // Returns an array that looks like this:
// [ // [
@ -145,19 +190,13 @@ export async function getAllPostSlugs() {
// } // }
// } // }
// ] // ]
return await Promise.all( return allPosts.map((post) => {
fileNames.map(async (fileName) => { return {
const slug = allPostsData.find( params: {
(item) => item.id === fileName.replace(/\.md$/, '') slug: post.url,
); },
};
return { });
params: {
slug: slug?.url,
},
};
})
);
} }
export interface MyPost extends MyMatters { export interface MyPost extends MyMatters {
@ -166,31 +205,13 @@ export interface MyPost extends MyMatters {
} }
export async function getPostData(slug: string) { export async function getPostData(slug: string) {
const allPostsData = await getSortedPostsData(); const allPosts = await getAllPosts();
const post = allPostsData.find((item) => item.url === slug); const post = allPosts.find((post) => post.url === slug)!;
const fullPath = path.join(postsDirectory, `${post?.id}.md`);
const fileContents = await fs.readFile(fullPath, 'utf8');
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents);
// Process markdown to html
// const processedContent = await remark()
// .use(html({ sanitize: false }))
// .process(matterResult.content);
// const contentHtml = processedContent.toString();
// Combine the data with the id // Combine the data with the id
return { return {
...post,
id: slug, id: slug,
// contentHtml,
content: matterResult.content,
// Convert Date to locale string.
...({
...matterResult.data,
date: matterResult.data.date.toISOString(),
} as MyMatters),
}; };
} }
@ -201,12 +222,13 @@ export async function getPostData(slug: string) {
* } * }
* @param allPostsData * @param allPostsData
*/ */
export const getArchiveData = (allPostsData: AllPostsData[]) => { export const getArchiveData = async () => {
const archiveData: { const archiveData: {
[key: string]: AllPostsData[]; [key: string]: MyPost[];
} = {}; } = {};
const allPosts = await getAllPosts();
allPostsData.map((post) => { allPosts.map((post) => {
const fullYear = new Date(post.date).getFullYear(); const fullYear = new Date(post.date).getFullYear();
archiveData?.[fullYear] archiveData?.[fullYear]

View File

@ -3,7 +3,7 @@ import { InferGetStaticPropsType } from 'next';
import Head from 'next/head'; import Head from 'next/head';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { Box, Text, Flex } from '@chakra-ui/react'; import { Box, Text, Flex } from '@chakra-ui/react';
import { getArchiveData, getSortedPostsData } from 'lib/posts'; import { getArchiveData } from 'lib/posts';
import useGetColors from 'lib/hooks/useGetColors'; import useGetColors from 'lib/hooks/useGetColors';
import HomeLayout from 'layouts/HomeLayout'; import HomeLayout from 'layouts/HomeLayout';
import ArchiveCardLoading from 'components/loading/ArchiveCardLoading'; import ArchiveCardLoading from 'components/loading/ArchiveCardLoading';
@ -13,11 +13,9 @@ const ArchiveCard = dynamic(() => import('components/ArchiveCard'), {
}); });
export const getStaticProps = async () => { export const getStaticProps = async () => {
const allPostsData = await getSortedPostsData();
return { return {
props: { props: {
...getArchiveData(allPostsData), ...(await getArchiveData()),
}, },
}; };
}; };

View File

@ -2,18 +2,16 @@ import type { ReactElement } from 'react';
import type { InferGetStaticPropsType } from 'next'; import type { InferGetStaticPropsType } from 'next';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import Head from 'next/head'; import Head from 'next/head';
import { getPagingData, getSortedPostsData } from 'lib/posts'; import { getPagingData } from 'lib/posts';
import HomeLayout from 'layouts/HomeLayout'; import HomeLayout from 'layouts/HomeLayout';
const Paging = dynamic(() => import('components/Paging')); const Paging = dynamic(() => import('components/Paging'));
const PostCard = dynamic(() => import('components/PostCard')); const PostCard = dynamic(() => import('components/PostCard'));
export const getStaticProps = async () => { export const getStaticProps = async () => {
const allPostsData = await getSortedPostsData();
return { return {
props: { props: {
...getPagingData(allPostsData), ...(await getPagingData()),
}, },
}; };
}; };

View File

@ -43,9 +43,8 @@ const PostTOC = dynamic(() => import('components/post/PostTOC'), {
}); });
export async function getStaticPaths() { export async function getStaticPaths() {
const paths = await getAllPostSlugs();
return { return {
paths, paths: await getAllPostSlugs(),
fallback: false, fallback: false,
}; };
} }

View File

@ -2,12 +2,7 @@ import { ReactElement } from 'react';
import type { GetStaticProps, InferGetStaticPropsType } from 'next'; import type { GetStaticProps, InferGetStaticPropsType } from 'next';
import Head from 'next/head'; import Head from 'next/head';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { import { AllPostsData, getAllPostNum, getPagingData } from 'lib/posts';
AllPostsData,
getAllPostNum,
getPagingData,
getSortedPostsData,
} from 'lib/posts';
import HomeLayout from 'layouts/HomeLayout'; import HomeLayout from 'layouts/HomeLayout';
import type { PagingData } from 'lib/posts'; import type { PagingData } from 'lib/posts';
@ -15,9 +10,8 @@ const Paging = dynamic(() => import('components/Paging'));
const PostCard = dynamic(() => import('components/PostCard')); const PostCard = dynamic(() => import('components/PostCard'));
export async function getStaticPaths() { export async function getStaticPaths() {
const paths = await getAllPostNum();
return { return {
paths, paths: await getAllPostNum(),
fallback: false, fallback: false,
}; };
} }
@ -25,12 +19,12 @@ export async function getStaticPaths() {
export const getStaticProps: GetStaticProps< export const getStaticProps: GetStaticProps<
{ num: string | undefined } & PagingData { num: string | undefined } & PagingData
> = async ({ params }) => { > = async ({ params }) => {
const allPostsData = await getSortedPostsData(); const num = params?.num?.toString();
return { return {
props: { props: {
num: params?.num?.toString(), num,
...getPagingData(allPostsData, params?.num?.toString()), ...(await getPagingData(num)),
}, },
}; };
}; };