performance
This commit is contained in:
parent
b8723bc952
commit
3cae2eca2c
4 changed files with 32 additions and 23 deletions
3
bun.lock
3
bun.lock
|
|
@ -15,6 +15,7 @@
|
||||||
"base65536": "^5.0.0",
|
"base65536": "^5.0.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"lucide-react": "^0.510.0",
|
"lucide-react": "^0.510.0",
|
||||||
"pako": "^2.1.0",
|
"pako": "^2.1.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
|
|
@ -705,6 +706,8 @@
|
||||||
|
|
||||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||||
|
|
||||||
|
"lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
|
||||||
|
|
||||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||||
|
|
||||||
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
|
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
"base65536": "^5.0.0",
|
"base65536": "^5.0.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
"lucide-react": "^0.510.0",
|
"lucide-react": "^0.510.0",
|
||||||
"pako": "^2.1.0",
|
"pako": "^2.1.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
|
|
|
||||||
48
src/App.tsx
48
src/App.tsx
|
|
@ -1,5 +1,6 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
import { encode, decode } from "base65536";
|
import { encode, decode } from "base65536";
|
||||||
|
import debounce from "lodash.debounce";
|
||||||
import pako from "pako";
|
import pako from "pako";
|
||||||
|
|
||||||
import "@blocknote/core/fonts/inter.css";
|
import "@blocknote/core/fonts/inter.css";
|
||||||
|
|
@ -47,30 +48,33 @@ export default function App() {
|
||||||
loadContentFromURL();
|
loadContentFromURL();
|
||||||
}, [editor]);
|
}, [editor]);
|
||||||
|
|
||||||
const handleChange = async () => {
|
// useCallback을 사용해 debounce 유지
|
||||||
if (!editor) return;
|
const debouncedHandleChange = useCallback(
|
||||||
|
debounce(async () => {
|
||||||
|
if (!editor) return;
|
||||||
|
|
||||||
const newContentMarkdown = await editor.blocksToMarkdownLossy(
|
const newContentMarkdown = await editor.blocksToMarkdownLossy(
|
||||||
editor.topLevelBlocks
|
editor.topLevelBlocks
|
||||||
);
|
);
|
||||||
setContentForURL(newContentMarkdown);
|
setContentForURL(newContentMarkdown);
|
||||||
|
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
let encodedString: string;
|
let encodedString: string;
|
||||||
|
|
||||||
if (newContentMarkdown.length >= 40) {
|
if (newContentMarkdown.length >= 40) {
|
||||||
const encodedBytes = encoder.encode(newContentMarkdown);
|
const encodedBytes = encoder.encode(newContentMarkdown);
|
||||||
const compressed = pako.gzip(encodedBytes);
|
const compressed = pako.gzip(encodedBytes);
|
||||||
encodedString = encode(compressed); // 압축 + 인코딩
|
encodedString = encode(compressed);
|
||||||
} else {
|
} else {
|
||||||
const plainBytes = encoder.encode(newContentMarkdown);
|
const plainBytes = encoder.encode(newContentMarkdown);
|
||||||
encodedString = encode(plainBytes); // 압축 없이 인코딩
|
encodedString = encode(plainBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const newUrl = `${window.location.pathname}?c=${encodedString}`;
|
||||||
|
window.history.replaceState({}, "", newUrl);
|
||||||
|
}, 250), [editor] // 500ms 대기
|
||||||
|
);
|
||||||
|
|
||||||
const newUrl = `${window.location.pathname}?c=${encodedString}`;
|
|
||||||
window.history.replaceState({}, "", newUrl);
|
|
||||||
window.dispatchEvent(new Event("url-changed"));
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="flex flex-col w-full h-screen">
|
<main className="flex flex-col w-full h-screen">
|
||||||
|
|
@ -86,7 +90,7 @@ export default function App() {
|
||||||
<div id="editor-container" className="w-full p-4 h-full max-h-screen">
|
<div id="editor-container" className="w-full p-4 h-full max-h-screen">
|
||||||
<BlockNoteView
|
<BlockNoteView
|
||||||
editor={editor}
|
editor={editor}
|
||||||
onChange={handleChange}
|
onChange={debouncedHandleChange}
|
||||||
className="w-full h-full"
|
className="w-full h-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,11 @@ export default function CopyLink() {
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="outline" size="icon">
|
<Button variant="outline" size="icon" onClick={updateLink}>
|
||||||
<Share2 className="h-4 w-4" />
|
<Share2 className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
||||||
<DialogContent className="sm:max-w-md">
|
<DialogContent className="sm:max-w-md">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Share link</DialogTitle>
|
<DialogTitle>Share link</DialogTitle>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue