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
- 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)
- CSS outlines messed up

View File

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

View File

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

View File

@@ -1,7 +1,8 @@
"use client";
import { useMemo, useRef, useState } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { useSetSearchText } from "@/contexts/search-text";
import { cn } from "@/lib/style";
import { Button, ButtonProps } from "@/components/ui/button";
@@ -12,10 +13,17 @@ export function SearchBar() {
const router = useRouter();
const inputRef = useRef<HTMLInputElement>(null);
const [text, setText] = useState("");
const setSearchText = useSetSearchText();
// prefetch to speed up the first search
useEffect(() => router.prefetch("/search"), [router]);
const search = () => {
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>
);
};