进阶指南
性能优化
构建体积优化、渲染速度优化、CSS 优化、开发服务器性能与实际优化案例
模板项目的性能优化涉及构建体积、渲染速度、CSS 大小和开发体验。本页讲解实用优化技巧和实际案例。
构建体积优化
Tree-shaking
确保只打包使用的代码:
export default ({
: {
: {
: {
: {
: false // 移除无副作用的未使用代码
}
}
}
}
})具名导入而非全量导入:
// ✅ 好:tree-shakable
import { , } from '@heroui/react'
export const = <>好的写法</>// ❌ 差:命名空间导入,打包器无法 tree-shake,整库进产物
import * as from '@heroui/react'
export const = <.>差的写法</.>动态导入
大组件或第三方库按需加载:
import { , type } from '@karinjs/template-react'
import { , } from 'react'
// 懒加载图表库
const = (() => import('react-chartjs-2').(() => ({ : . })))
interface StatsData {
: string[]
: number[]
}
const = ({ }: <StatsData>) => (
< ={<>加载中...</>}>
< ={{ : ., : [{ : . }] }} />
</>
)
export default ({
:
})依赖分析
使用 rollup-plugin-visualizer 查看打包体积:
export default ({
: ({ }) =>
=== 'build'
? {
: [
({
: 'dist/stats.html',
: true,
: true,
: true
})
]
}
: {}
})外部化依赖
生产环境不打包 React(假设运行时已提供):
export default ({
: {
: {
: ['react', 'react-dom', 'react/jsx-runtime'],
: {
: {
: 'React',
'react-dom': 'ReactDOM'
}
}
}
}
})压缩优化
export default ({
: {
: [
({
: 'brotliCompress',
: '.br',
: 1024 // 只压缩 > 1KB 的文件
})
],
: {
: 'esbuild',
: 'lightningcss'
}
}
})渲染速度优化
组件懒加载
仅在使用时加载组件:
import { , type } from '@karinjs/template-react'
import { , } from 'react'
const = (() => import('../../components/HeavyChart'))
const = (() => import('../../components/HeavyTable'))
interface DashboardData {
: boolean
: boolean
}
const = ({ }: <DashboardData>) => (
<>
{. && (
< ={<>加载图表...</>}>
< />
</>
)}
{. && (
< ={<>加载表格...</>}>
< />
</>
)}
</>
)
export default ({
:
})React.memo 避免重渲染
import React from 'react'
interface UserCardProps {
: string
: string
}
export const = React.<UserCardProps>(({ , }) => {
.('UserCard 渲染')
return (
< ="flex items-center gap-3">
< ={} ={} ="size-12 rounded-full" />
< ="font-medium">{}</>
</>
)
})useMemo 缓存计算
import { } from 'react'
interface Item {
: number
}
interface Props {
: Item[]
}
function ({ }: Props) {
const = (() => {
.('计算总分')
return .((, ) => + ., 0)
}, [])
return <>总分: {}</>
}虚拟列表
长列表使用 react-window:
import { , type } from '@karinjs/template-react'
import { , type } from 'react-window'
interface User {
: string
: string
}
interface ListData {
: User[]
}
const = ({ , , }: <{ : User[] }>) => (
< ={} ="px-4 py-2 border-b">
{[].}
</>
)
const = ({ }: <ListData>) => (
< ={} ={..} ={48} ={{ : . }} ={{ : 600 }} />
)
export default ({
:
})图片优化
使用现代图片格式和懒加载:
import React from 'react'
const : React.<{ : string; : string }> = ({ , }) => (
<>
< ={`${}?format=avif`} ="image/avif" />
< ={`${}?format=webp`} ="image/webp" />
< ={} ={} ="lazy" ="async" ="w-full" />
</>
)CSS 优化
按需生成 Tailwind
只打包使用的类名:
@import 'tailwindcss';
@import '@karinjs/template-react/styles';
/* 限制扫描范围 */
@source '../ktr/template';
/* 或手动指定 */
@source '../ktr/template/**/*.tsx';PurgeCSS 移除未使用样式
export default ({
: {
: {
: {
: [
({
: ['./ktr/template/**/*.{tsx,ts}'],
: [/^bg-/, /^text-/, /^hover:/] // 保留动态类名
})
]
}
}
}
})CSS 压缩
使用 Lightning CSS:
export default ({
: {
: {
: 'lightningcss'
},
: {
: 'lightningcss'
}
}
})内联关键 CSS
小文件内联到 HTML:
import type { RenderPlugin } from '@karinjs/template-react'
import from 'node:fs'
const : RenderPlugin = {
: 'inline-critical-css',
: () => {
const = .('dist/critical.css', 'utf-8')
// afterRender 拿到的是包装前的模板片段,直接把 <style> 拼到片段前
return `<style>${}</style>\n${.}`
}
}拆分 CSS
按模板拆分 CSS 文件:
export default ({
: {
: {
: true // 每个入口生成独立 CSS
}
}
})开发服务器性能
预构建依赖
加速首次启动:
export default ({
: {
: {
: ['react', 'react-dom', '@heroui/react', 'framer-motion']
}
}
})减少文件监听
排除不必要的目录:
export default ({
: {
: {
: {
: ['**/node_modules/**', '**/dist/**', '**/.git/**', '**/coverage/**']
}
}
}
})HMR 优化
限制热更新边界:
import { } from '@karinjs/template-react'
const = () => <>User Card</>
export default ({
:
})
// HMR 边界
if (import.meta.) {
import.meta..()
}并发限制
控制并发请求数:
export default ({
: {
: {
: {
: true
},
: true
}
}
})实际优化案例
案例 1:减少首屏体积 70%
问题:首次加载需要下载 800KB JS。
优化:
import { } from '@karinjs/template-react'
import { } from 'rollup-plugin-visualizer'
export default ({
: {
: [
({ : true }) // 1. 分析体积
],
: {
: {
: {
() {
// 2. 拆分第三方库(vite 8 / rolldown 的 manualChunks 是函数形式)
if (.('node_modules/react')) return 'vendor'
if (.('@heroui')) return 'ui'
}
}
}
}
}
})import { } from 'react'
// 3. 懒加载重组件
const = (() => import('./HeavyChart'))结果:首屏减少到 240KB。
案例 2:优化大列表渲染
问题:渲染 1000 个用户卡片卡顿。
优化:
import { , type } from '@karinjs/template-react'
import React from 'react'
import { , type } from 'react-window'
interface User {
: string
: string
: string
}
interface ListData {
: User[]
}
// 1. memo 避免重渲染
const = React.<{ : User }>(({ }) => (
< ="flex items-center gap-3 px-4 py-2">
< ={.} ="" ="size-10 rounded-full" />
<>{.}</>
</>
))
// 2. 虚拟列表
const = ({ , , }: <{ : User[] }>) => (
< ={}>
< ={[]} />
</>
)
const = ({ }: <ListData>) => (
< ={} ={..} ={56} ={{ : . }} ={{ : 600 }} />
)
export default ({
:
})结果:渲染时间从 2.5s 降到 80ms。
案例 3:CSS 体积减少 60%
问题:Tailwind CSS 产物 350KB。
优化:
/* 1. 样式基座整包引入:@karinjs/template-react/styles 已包含 HeroUI 语义色和 dark: 变体,
不能再按 @heroui/theme/button 这种 v2 包路径分包导入 */
@import 'tailwindcss';
@import '@karinjs/template-react/styles';
/* 2. 限制扫描范围:Tailwind 只编译扫描到的类名,未使用的类不进产物 */
@source '../ktr/template';import { } from '@karinjs/template-react'
export default ({
: {
: {
: 'lightningcss' // 3. 使用更好的压缩
}
}
})结果:CSS 减少到 140KB。
案例 4:开发启动加速 3 倍
问题:开发服务器启动需要 12s。
优化:
import { } from '@karinjs/template-react'
export default ({
: {
// 1. 预构建常用依赖
: {
: ['react', 'react-dom', '@heroui/react', 'framer-motion', 'date-fns']
},
// 2. 减少监听范围
: {
: {
: ['**/node_modules/**', '**/dist/**']
}
},
// 3. 关闭不必要的功能
: {
: false
}
}
})结果:启动时间降到 4s。
案例 5:SSR 渲染性能
问题:单个模板 SSR 渲染耗时 800ms。
优化:
import { , type } from '@karinjs/template-react'
import { } from 'react'
interface Data {
: <{ : string; : number }>
}
const = ({ }: <Data>) => {
// 1. 缓存计算结果
const = (() => [....].((, ) => . - .), [.])
return (
<>
{.(() => (
// 2. 使用 key 优化 reconciliation
< ={.}>{.}</>
))}
</>
)
}
export default ({
:
})import type { RenderPlugin } from '@karinjs/template-react'
// 3. 性能监控插件
const : RenderPlugin = {
: 'perf',
: () => {
;( as any).__startTime = .()
},
: () => {
const = .() - ( as any).__startTime
if ( > 500) {
.(`[慢渲染] ${.}: ${}ms`)
}
}
}结果:渲染时间降到 120ms。
案例 6:图片优化
问题:模板包含大量高清图片,加载慢。
优化:
import React from 'react'
// 1. 响应式图片
const : React.<{ : string; : string }> = ({ , }) => (
<>
< ={`${}?w=64&format=avif 1x, ${}?w=128&format=avif 2x`} ="image/avif" />
< ={`${}?w=64&format=webp 1x, ${}?w=128&format=webp 2x`} ="image/webp" />
< ={`${}?w=64`} ={} ="lazy" ="async" ="size-16 rounded-full" />
</>
)import type { RenderPlugin } from '@karinjs/template-react'
import from 'node:fs'
import from 'node:path'
// 2. 小图片内联(框架已内置该能力:html.assetsInlineLimit 默认 4096 字节,
// 需要更定制的规则时才用这种 afterRender 插件,比如按路径前缀区分阈值)
const : RenderPlugin = {
: 'inline-small-images',
: () => {
return ..(/<img[^>]+src="\/assets\/([^"]+\.(?:png|jpg|svg))"[^>]*>/g, (, ) => {
const = .(., '../assets', )
if (!.()) return
const = .()
if (. > 5120) return // 只内联 < 5KB
const = .().(1)
const = .(, 'base64')
return .(`src="/assets/${}"`, `src="data:image/${};base64,${}"`)
})
}
}结果:图片加载时间减少 80%。
案例 7:减少重渲染
问题:父组件更新导致子组件不必要的重渲染。
优化:
import React, { } from 'react'
interface User {
: string
: string
}
// 1. memo + 原始值 props
const = React.<{ : User }>(({ }) => {
.('UserCard 渲染')
return <>{.}</>
})
// 2. 回调使用 useCallback
const : React.<{ : User[] }> = ({ }) => {
const [, ] = <string | null>(null)
const = React.((: string) => {
()
}, [])
return (
<>
{.(() => (
< ={.} ={} />
))}
</>
)
}结果:更新时只重渲染必要的组件。
案例 8:Monorepo 构建缓存
问题:Monorepo 每次全量构建耗时 5 分钟。
优化:
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", "lib/**"],
"cache": true
}
}
}# 使用 Turborepo 缓存
pnpm turbo build
# 或使用 Nx
pnpm nx run-many --target=build --all结果:增量构建只需 30s。
性能监控
构建时监控
import { } from '@karinjs/template-react'
export default ({
: {
: {
: true, // 报告压缩后大小
: 500 // 超过 500KB 警告
}
}
})运行时监控
import type { RenderPlugin } from '@karinjs/template-react'
import from 'node:fs'
import from 'node:path'
const : RenderPlugin = {
: 'metrics',
: 'post',
: async () => {
const = {
: .,
: ..,
: .()
}
const = .(., 'metrics.jsonl')
await ..(, .() + '\n')
}
}性能预算
import { } from '@karinjs/template-react'
export default ({
: {
: {
: {
: {
: () => {
// 检查文件大小
if (.?.('.css')) {
.(`CSS: ${.}`)
}
return 'assets/[name]-[hash][extname]'
}
}
}
}
}
})优化检查清单
构建优化
- 启用 tree-shaking
- 动态导入大组件
- 分析打包体积
- 外部化运行时依赖
- 启用 Brotli 压缩
- 拆分 vendor chunk
- 移除 console 和 debugger
渲染优化
- 使用 React.memo
- useMemo 缓存计算
- useCallback 稳定回调
- 虚拟列表处理长列表
- 懒加载非关键组件
- 优化图片格式和大小
- 避免内联大对象
CSS 优化
- PurgeCSS 移除未使用样式
- 限制 Tailwind 扫描范围
- 使用 Lightning CSS
- 内联关键 CSS
- 按需导入组件库样式
- 压缩 CSS
开发优化
- 预构建依赖
- 减少文件监听
- HMR 边界优化
- 关闭 sourcemap(生产)
- 使用 SWC/esbuild