Skip to content

Commit

Permalink
feat: converge iframely and unfurl
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-guoba committed Mar 7, 2024
1 parent aa0de9a commit af3166d
Show file tree
Hide file tree
Showing 29 changed files with 254 additions and 352 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

/scripts/load-testing/output.bin
Heap.*.heapsnapshot
69 changes: 67 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,30 @@ Blog build on [Next.js](https://nextjs.org/) and [Notion Public API](https://www

## Features


1. Built using Next.js, TS, Tailwind CSS and other plugins(Shiki、React-pdf and others).
2. Use [Notion Public API](https://developers.notion.com/)
3. Full support for dark mode
4. Support [Static Site Generation](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation)
3. 支持使用 Prisma 缓存Notion数据,减少API访问,提升整体性能。
4. 支持深色模式。
5. 支持 [Static Site Generation](https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation)

## Tech Stack

### Frameworks

1. [Next.js](https://nextjs.org/)
2. [Notion](https://www.notion.so/)
3. [Tailwind CSS ](https://tailwindcss.com/) and [shadcn](https://ui.shadcn.com/)
4. [Prisma](https://www.prisma.io/) : 缓存Notion数据,过期时间可配置。

### Component
1. [Shiki](https://shiki.style/): render `code` blocks
2. [React-pdf](https://react-pdf.org/): render `pdf` blocks
3. [iframely](https://iframely.com/) / [unfurl](https://github.com/jacktuck/unfurl): render `bookmark``link-preview` and `video` blocks(Notion only return url without Open Graph infos)
4. [Katex](https://katex.org/): render `equation` blocks

### Platforms


## ✨ Getting Started

Expand Down Expand Up @@ -72,10 +92,55 @@ Most common block types are supported. But some blocks information not supported
| Divider | ❌ Missing | API Unsupported. |
| Table Of Contents | ❌ Missing | API Unsupported. |

## Performance

1. [dynamic](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic) route

关闭 `dynamic route` 可以减少重复渲染,大幅提升性能。下面为是否开启的性能对比:

- `force-dynamic` :

| Bucket | # | % | Histogram |
|-----------------|------|--------|---------------------------------------------------------------------|
| [0s, 10ms] | 0 | 0.00% | |
| [10ms, 40ms] | 1 | 0.01% | |
| [40ms, 80ms] | 0 | 0.00% | |
| [80ms, 200ms] | 1 | 0.01% | |
| [200ms, 500ms] | 906 | 10.30% | ####### |
| [500ms, 1s] | 7885 | 89.67% | ################################################################### |
| [1s, +Inf] | 0 | 0.00% | |

- `auto` (default):

| Bucket | # | % Histogram | |
|-----------------|------|-------------------|--------------------------------------------------------------|
| [0s, 10ms] | 0 | 0.00% | |
| [10ms, 40ms] | 7727 | 80.49% | ############################################################ |
| [40ms, 80ms] | 1816 | 18.92% | ############## |
| [80ms, 200ms] | 54 | 0.56% | |
| [200ms, 500ms] | 3 | 0.03% | |
| [500ms, 1s] | 0 | 0.00% | |
| [1s, +Inf] | 0 | 0.00% | |



## Learn More

1. 为何选用Notion作为内容编辑器?
本人已有多年使用Notion的习惯,以前博客的做法是将用Notion写好后再copy到Markdown等编辑器,使用hexo发布。这样流程会非常长,而且需要适配markdown格式,非常的不方便。所以直接使用Notion作为CMS,写好的内容可以直接发布。

2. 为何要重造轮子,而不是直接使用`react-notion-x`等已有的能力实现渲染。
原因有几点:
- Git上大部分的类似产品都使用非公开的Notion API,在官网上没有相关文档,只能自己摸索其数据结构。
- 非公开的API要求将Notion数据公开到外网,无法保障数据隐私。
- 非公开的API存在后续可能废弃、变更的隐患。
虽然Public API在能力上有所缺失,比如不支持 Database View 等能力,但是常规的能力基本都可以满足。所以选择采用Notion Public API实现。

3. 为何要采用`Prisma`缓存Notion数据
Notion的API存在频率限制,一些嵌套层次比较深的Page多次访问是很容易超过API的频率限制。而且部分地区API访问不稳定,对页面性能影响较大,所以使用缓存来解决。
另外Notion API返回的部分数据(比如图片url)存在有效期,所以也需要考虑过期时间。详见[notion-hosted-files](https://developers.notion.com/reference/file-object#notion-hosted-files)



## TODO
- [ ] Deploy on Vercel
1 change: 0 additions & 1 deletion app/(blog)/article/[...slug]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// import Script from "next/script"
import React from "react";


export default async function LobyLayout({ children }: { children: React.ReactNode }) {
return <div className="relative flex min-h-screen flex-col">{children}</div>;
}
6 changes: 3 additions & 3 deletions app/(blog)/article/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import { Separator } from "@/components/ui/separator";
import { env } from "@/env.mjs";

// https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#revalidate
// export const revalidate = parseInt(process.env.NEXT_REVALIDATE_PAGES || "", 10) || 300; // revalidate the data interval
export const dynamic = 'force-dynamic';
export const revalidate = 0;
export const revalidate = parseInt(process.env.NEXT_REVALIDATE_PAGES || "", 10) || 300; // revalidate the data interval
// export const dynamic = 'force-dynamic';
// export const revalidate = 0;

// export const dynamicParams = true; // true | false,

Expand Down
3 changes: 0 additions & 3 deletions app/(blog)/db/[...row]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import Shell from "@/components/shells/shell";
import React from "react";

Expand All @@ -11,7 +10,6 @@ import { DatabaseRenderer } from "@/app/notion/_components/db/database";
import { IconRender } from "@/app/notion/_components/emoji";
import RichText from "@/app/notion/text";


export default async function Page({ params }: { params: { row: string[] } }) {
const dbID = params.row[0];
const columns: any = await RetrieveDatabase(dbID);
Expand Down Expand Up @@ -39,7 +37,6 @@ export default async function Page({ params }: { params: { row: string[] } }) {
</PageHeaderDescription>
<Separator className="mb-2.5" />


<DatabaseRenderer property={columns} data={data}></DatabaseRenderer>
</Shell>
);
Expand Down
2 changes: 1 addition & 1 deletion app/(lobby)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default async function Home() {
>
{posts.map((post: any, i) => {
const title = post.properties?.Title.title[0].text.content;
const slug = post.properties?.Slug?.rich_text[0].plain_text + '/' + post.id;
const slug = post.properties?.Slug?.rich_text[0].plain_text + "/" + post.id;
const edit_time = post.last_edited_time;
const image = extractFileUrl(post.cover);
const desc = post.properties?.Summary?.rich_text[0]?.plain_text;
Expand Down
86 changes: 0 additions & 86 deletions app/api/iframely/route.ts

This file was deleted.

29 changes: 3 additions & 26 deletions app/api/mem/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,25 @@

import { NextRequest, NextResponse } from "next/server";
import v8 from "v8";
import { runInNewContext } from 'vm';


export async function GET(req: NextRequest) {
const searchParams = req.nextUrl.searchParams;
const state = searchParams.get("gc");

// enabling trace-gc
if (state === "start") {
v8.setFlagsFromString("--trace-gc");

const gc = runInNewContext('gc'); // nocommit
gc();

return NextResponse.json({
result: "gc success",
});
}

// dump
if (state == "dump") {
const fileName = v8.writeHeapSnapshot();
console.log(`Created heapdump file: ${fileName}`);
const fileName = v8.writeHeapSnapshot();
console.log(`Created heapdump file: ${fileName}`);

return NextResponse.json({
result: "dump success",
fileName: fileName,
});
}

// const searchParams = req.nextUrl.searchParams;
// if (global.gc) {
// global.gc();
// } else {
// console.log(
// "Garbage collection unavailable. Pass --expose-gc when launching node to enable forced garbage collection."
// );
// }
const formatMemoryUsage = (data: number) => `${Math.round((data / 1024 / 1024) * 100) / 100} MB`;

const memoryData = process.memoryUsage();

const memoryUsage = {
rss: `${formatMemoryUsage(memoryData.rss)} -> Resident Set Size - total memory allocated for the process execution`,
heapTotal: `${formatMemoryUsage(memoryData.heapTotal)} -> total size of the allocated heap`,
Expand Down
Loading

0 comments on commit af3166d

Please sign in to comment.