Skip to content

Commit eb94ada

Browse files
committed
fix: delay search
1 parent 244c6ec commit eb94ada

File tree

6 files changed

+66
-13
lines changed

6 files changed

+66
-13
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"@radix-ui/react-tooltip": "^1.2.8",
4343
"@react-three/drei": "^10.7.7",
4444
"@react-three/fiber": "^9.5.0",
45+
"@sentry/browser": "^10.43.0",
4546
"@sentry/node": "^10.42.0",
4647
"@sentry/tanstackstart-react": "^10.43.0",
4748
"@stackblitz/sdk": "^1.11.0",

pnpm-lock.yaml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/markdown/CodeBlock.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { useToast } from '~/components/ToastProvider'
44
import { Copy } from 'lucide-react'
55
import type { Mermaid } from 'mermaid'
66
import { transformerNotationDiff } from '@shikijs/transformers'
7-
import { createHighlighter, type HighlighterGeneric } from 'shiki'
7+
import type { HighlighterGeneric } from 'shiki'
8+
import { createHighlighter } from 'shiki'
89
import { Button } from '~/ui'
910

1011
// Language aliases mapping

src/router.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,45 @@ import { NotFound } from './components/NotFound'
66
import { QueryClient } from '@tanstack/react-query'
77
import * as Sentry from '@sentry/tanstackstart-react'
88

9+
function deferSentryReplayIntegration() {
10+
if (typeof window === 'undefined') {
11+
return
12+
}
13+
14+
const loadReplay = async () => {
15+
try {
16+
const client = Sentry.getClient()
17+
18+
if (client?.getIntegrationByName('Replay')) {
19+
return
20+
}
21+
22+
const { replayIntegration } = await import('@sentry/browser')
23+
24+
Sentry.getClient()?.addIntegration(replayIntegration())
25+
} catch {
26+
// Ignore replay load failures and preserve core error reporting.
27+
}
28+
}
29+
30+
if ('requestIdleCallback' in window) {
31+
window.requestIdleCallback(
32+
() => {
33+
void loadReplay()
34+
},
35+
{ timeout: 2500 },
36+
)
37+
return
38+
}
39+
40+
globalThis.setTimeout(() => {
41+
void loadReplay()
42+
}, 2500)
43+
}
44+
945
if (typeof document !== 'undefined') {
1046
Sentry.init({
1147
dsn: 'https://ac4bfc43ff4a892f8dc7053c4a50d92f@o4507236158537728.ingest.us.sentry.io/4507236163649536',
12-
integrations: [Sentry.replayIntegration()],
1348
sendDefaultPii: true,
1449
// Performance Monitoring
1550
tracesSampleRate: 1.0, // Capture 100% of the transactions
@@ -19,6 +54,8 @@ if (typeof document !== 'undefined') {
1954
replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
2055
replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
2156
})
57+
58+
deferSentryReplayIntegration()
2259
}
2360

2461
export function getRouter() {

src/routes/__root.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ const LazyRouterDevtools = React.lazy(() =>
1919
import { NotFound } from '~/components/NotFound'
2020
import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary'
2121
import { SearchProvider, useSearchContext } from '~/contexts/SearchContext'
22-
import { SearchModal } from '~/components/SearchModal'
2322
import { ToastProvider } from '~/components/ToastProvider'
2423
import { LoginModalProvider } from '~/contexts/LoginModalContext'
24+
25+
const LazySearchModal = React.lazy(() =>
26+
import('~/components/SearchModal').then((m) => ({ default: m.SearchModal })),
27+
)
2528
import { Spinner } from '~/components/Spinner'
2629
import { ThemeProvider, useHtmlClass } from '~/components/ThemeProvider'
2730
import { Navbar } from '~/components/Navbar'
@@ -207,7 +210,8 @@ function ShellComponent({ children }: { children: React.ReactNode }) {
207210
}
208211

209212
function SearchHotkeyController() {
210-
const { openSearch } = useSearchContext()
213+
const { isOpen, openSearch } = useSearchContext()
214+
const [hasOpenedSearch, setHasOpenedSearch] = React.useState(false)
211215

212216
React.useEffect(() => {
213217
const handleGlobalKeyDown = (event: KeyboardEvent) => {
@@ -216,6 +220,7 @@ function SearchHotkeyController() {
216220
if (event.key.toLowerCase() !== 'k') return
217221

218222
event.preventDefault()
223+
setHasOpenedSearch(true)
219224
openSearch()
220225
}
221226

@@ -225,7 +230,19 @@ function SearchHotkeyController() {
225230
}
226231
}, [openSearch])
227232

228-
return <SearchModal />
233+
React.useEffect(() => {
234+
if (isOpen) {
235+
setHasOpenedSearch(true)
236+
}
237+
}, [isOpen])
238+
239+
if (!hasOpenedSearch) return null
240+
241+
return (
242+
<React.Suspense fallback={null}>
243+
<LazySearchModal />
244+
</React.Suspense>
245+
)
229246
}
230247

231248
function IdleGtmLoader() {

vite.config.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,6 @@ export default defineConfig({
6363
manualChunks: (id) => {
6464
// Vendor chunk splitting for better caching
6565
if (id.includes('node_modules')) {
66-
// Search-related deps (only loaded when search modal opens)
67-
if (
68-
id.includes('algoliasearch') ||
69-
id.includes('instantsearch') ||
70-
id.includes('react-instantsearch')
71-
) {
72-
return 'search'
73-
}
7466
// Lucide icons (tree-shaken but still significant)
7567
if (id.includes('lucide-react')) {
7668
return 'icons'

0 commit comments

Comments
 (0)