feat(website): loading time optimize
This commit is contained in:
@@ -1,15 +1,27 @@
|
|||||||
import FeaturesSection from './home/FeaturesSection'
|
import { Suspense, lazy } from 'react'
|
||||||
|
|
||||||
import HeroSection from './home/HeroSection'
|
import HeroSection from './home/HeroSection'
|
||||||
import OneMoreThingSection from './home/OneMoreThingSection'
|
|
||||||
import ScenariosSection from './home/ScenariosSection'
|
const FeaturesSection = lazy(() => import('./home/FeaturesSection'))
|
||||||
|
const ScenariosSection = lazy(() => import('./home/ScenariosSection'))
|
||||||
|
const OneMoreThingSection = lazy(() => import('./home/OneMoreThingSection'))
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeroSection />
|
<HeroSection />
|
||||||
<FeaturesSection />
|
<Suspense
|
||||||
<ScenariosSection />
|
fallback={
|
||||||
<OneMoreThingSection />
|
<div className="flex items-center justify-center gap-3 py-20 text-gray-400">
|
||||||
|
<div className="w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FeaturesSection />
|
||||||
|
<ScenariosSection />
|
||||||
|
<OneMoreThingSection />
|
||||||
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
} from '../../constants'
|
} from '../../constants'
|
||||||
import { useLanguage } from '../../i18n/context'
|
import { useLanguage } from '../../i18n/context'
|
||||||
|
|
||||||
const pageAgentModule = import('page-agent')
|
let pageAgentModule: Promise<typeof import('page-agent')> | null = null
|
||||||
|
|
||||||
function getInjection(useCN?: boolean) {
|
function getInjection(useCN?: boolean) {
|
||||||
const cdn = useCN ? CDN_DEMO_CN_URL : CDN_DEMO_URL
|
const cdn = useCN ? CDN_DEMO_CN_URL : CDN_DEMO_URL
|
||||||
@@ -59,11 +59,12 @@ export default function HeroSection() {
|
|||||||
|
|
||||||
const [ready, setReady] = useState(false)
|
const [ready, setReady] = useState(false)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
pageAgentModule ??= import('page-agent')
|
||||||
pageAgentModule.then(() => setReady(true))
|
pageAgentModule.then(() => setReady(true))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleExecute = async () => {
|
const handleExecute = async () => {
|
||||||
if (!task.trim() || !ready) return
|
if (!task.trim() || !ready || !pageAgentModule) return
|
||||||
|
|
||||||
const { PageAgent } = await pageAgentModule
|
const { PageAgent } = await pageAgentModule
|
||||||
const win = window as any
|
const win = window as any
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
import { Suspense, lazy, useLayoutEffect } from 'react'
|
import { Suspense, lazy, useEffect, useLayoutEffect } from 'react'
|
||||||
import { Route, Switch, useLocation } from 'wouter'
|
import { Route, Switch, useLocation } from 'wouter'
|
||||||
|
|
||||||
import Footer from './components/Footer'
|
import Footer from './components/Footer'
|
||||||
import Header from './components/Header'
|
import Header from './components/Header'
|
||||||
import { useLanguage } from './i18n/context'
|
|
||||||
import HomePage from './pages/Home'
|
import HomePage from './pages/Home'
|
||||||
import DocsLayout from './pages/docs/Layout'
|
|
||||||
|
|
||||||
const DocsPages = lazy(() => import('./pages/docs/index'))
|
const docsImport = () => import('./pages/docs/index')
|
||||||
|
const DocsPages = lazy(docsImport)
|
||||||
// Prefetch docs chunk during idle time so navigation feels instant
|
|
||||||
if (typeof requestIdleCallback !== 'undefined') {
|
|
||||||
requestIdleCallback(() => import('./pages/docs/index'))
|
|
||||||
}
|
|
||||||
|
|
||||||
function ScrollToTop() {
|
function ScrollToTop() {
|
||||||
const [pathname] = useLocation()
|
const [pathname] = useLocation()
|
||||||
@@ -22,19 +16,12 @@ function ScrollToTop() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function DocsLoadingFallback() {
|
|
||||||
const { isZh } = useLanguage()
|
|
||||||
return (
|
|
||||||
<DocsLayout>
|
|
||||||
<div className="flex items-center gap-3 py-12 text-gray-500 dark:text-gray-400">
|
|
||||||
<div className="w-5 h-5 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
|
|
||||||
{isZh ? '文档加载中...' : 'Loading documentation...'}
|
|
||||||
</div>
|
|
||||||
</DocsLayout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Router() {
|
export default function Router() {
|
||||||
|
useEffect(() => {
|
||||||
|
const id = requestIdleCallback(() => docsImport())
|
||||||
|
return () => cancelIdleCallback(id)
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen flex-col">
|
<div className="flex min-h-screen flex-col">
|
||||||
<Header />
|
<Header />
|
||||||
@@ -52,7 +39,14 @@ export default function Router() {
|
|||||||
|
|
||||||
<Route path="/docs" nest>
|
<Route path="/docs" nest>
|
||||||
<div className="flex-1 bg-white dark:bg-gray-900">
|
<div className="flex-1 bg-white dark:bg-gray-900">
|
||||||
<Suspense fallback={<DocsLoadingFallback />}>
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<div className="flex items-center justify-center gap-3 py-20 text-gray-400">
|
||||||
|
<div className="w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
<DocsPages />
|
<DocsPages />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ export default defineConfig(({ mode }) => ({
|
|||||||
output: {
|
output: {
|
||||||
manualChunks: {
|
manualChunks: {
|
||||||
vendor: ['react', 'react-dom', 'wouter'],
|
vendor: ['react', 'react-dom', 'wouter'],
|
||||||
'page-agent': ['page-agent'],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user