perf: speed up search

This commit is contained in:
rusconn
2023-05-24 13:17:20 +00:00
parent f1c3bd2971
commit 0cf5774e16
5 changed files with 48 additions and 15 deletions

View File

@@ -4,6 +4,8 @@ A web clone of [DevToys](https://github.com/veler/DevToys)
## Known issues ## Known issues
- Tool search does not set query parameters
- [(Shallow routing) updating search params causes server code to rerun.](https://github.com/vercel/next.js/issues/49668)
- [Editor may not resize to fit container size](https://github.com/suren-atoyan/monaco-react/issues/346) - [Editor may not resize to fit container size](https://github.com/suren-atoyan/monaco-react/issues/346)
- CSS outlines messed up - CSS outlines messed up

View File

@@ -1,5 +1,6 @@
import "@/styles/globals.css"; import "@/styles/globals.css";
import { Metadata } from "next"; import { Metadata } from "next";
import { SearchTextProvider } from "@/contexts/search-text";
import { siteConfig } from "@/config/site"; import { siteConfig } from "@/config/site";
import { fontMono, fontSans } from "@/lib/fonts"; import { fontMono, fontSans } from "@/lib/fonts";
@@ -44,16 +45,18 @@ export default function RootLayout({ children }: RootLayoutProps) {
)} )}
> >
<ThemeProvider attribute="class" defaultTheme="system" disableTransitionOnChange> <ThemeProvider attribute="class" defaultTheme="system" disableTransitionOnChange>
<div className="relative flex h-full flex-col"> <SearchTextProvider>
<SiteHeader /> <div className="relative flex h-full flex-col">
<div className="flex flex-1 overflow-y-hidden"> <SiteHeader />
<Sidebar /> <div className="flex flex-1 overflow-y-hidden">
<main className="h-full flex-1 overflow-y-auto rounded-tl-md border bg-page p-12"> <Sidebar />
{children} <main className="h-full flex-1 overflow-y-auto rounded-tl-md border bg-page p-12">
</main> {children}
</main>
</div>
</div> </div>
</div> <TailwindIndicator />
<TailwindIndicator /> </SearchTextProvider>
</ThemeProvider> </ThemeProvider>
</body> </body>
</html> </html>

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
import { useSearchParams } from "next/navigation"; import { useSearchText } from "@/contexts/search-text";
import Fuse from "fuse.js"; import Fuse from "fuse.js";
import { homeTools } from "@/config/tools"; import { homeTools } from "@/config/tools";
@@ -8,9 +8,8 @@ import { PageRootSection } from "@/components/page-root-section";
import { ToolCards } from "@/components/tool-cards"; import { ToolCards } from "@/components/tool-cards";
export default function Page() { export default function Page() {
const params = useSearchParams(); // use search params in context
const q = useSearchText();
const q = params.get("q")?.trim() ?? "";
const fuse = new Fuse(homeTools, { keys: ["keywords"], threshold: 0.45 }); const fuse = new Fuse(homeTools, { keys: ["keywords"], threshold: 0.45 });
const keyWordsOptions = q.split(" ").map(word => ({ keywords: word })); const keyWordsOptions = q.split(" ").map(word => ({ keywords: word }));

View File

@@ -1,7 +1,8 @@
"use client"; "use client";
import { useMemo, useRef, useState } from "react"; import { useEffect, useMemo, useRef, useState } from "react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useSetSearchText } from "@/contexts/search-text";
import { cn } from "@/lib/style"; import { cn } from "@/lib/style";
import { Button, ButtonProps } from "@/components/ui/button"; import { Button, ButtonProps } from "@/components/ui/button";
@@ -12,10 +13,17 @@ export function SearchBar() {
const router = useRouter(); const router = useRouter();
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [text, setText] = useState(""); const [text, setText] = useState("");
const setSearchText = useSetSearchText();
// prefetch to speed up the first search
useEffect(() => router.prefetch("/search"), [router]);
const search = () => { const search = () => {
if (text.trim()) { if (text.trim()) {
router.push(`/search?q=${text.trim()}`); // next/navigation doesn't support shallow routing, use context instead of query params for speed
// https://github.com/vercel/next.js/issues/49668
setSearchText(text.trim());
router.push("/search");
} }
}; };

21
contexts/search-text.tsx Normal file
View File

@@ -0,0 +1,21 @@
"use client";
import { PropsWithChildren, createContext, useContext, useState } from "react";
const SearchTextContext = createContext("");
const SetSearchTextContext = createContext<(text: string) => void>(() => {});
export const useSearchText = () => useContext(SearchTextContext);
export const useSetSearchText = () => useContext(SetSearchTextContext);
export const SearchTextProvider = ({ children }: PropsWithChildren) => {
const [searchText, setSearchText] = useState("");
return (
<SearchTextContext.Provider value={searchText}>
<SetSearchTextContext.Provider value={setSearchText}>
{children}
</SetSearchTextContext.Provider>
</SearchTextContext.Provider>
);
};