在现代 Web 开发中,性能优化是至关重要的。本文将分享我在 Nuxt 3 项目中积累的性能优化经验和最佳实践。

代码分割和懒加载

路由级别的代码分割

Nuxt 3 默认会为每个页面进行代码分割,但我们可以进一步优化:

JAVASCRIPT
// 使用动态导入进行组件懒加载
const LazyComponent = defineAsyncComponent(() => 
  import('~/components/HeavyComponent.vue')
)

条件性加载

VUE
<template>
  <div>
    <LazyHeavyComponent v-if="showHeavyComponent" />
  </div>
</template>

<script setup>
const LazyHeavyComponent = defineAsyncComponent(() =>
  import('~/components/HeavyComponent.vue')
)

const showHeavyComponent = ref(false)
</script>

图像优化

使用 Nuxt Image 模块

BASH
npm install @nuxt/image
VUE
<template>
  <NuxtImg
    src="/images/hero.jpg"
    alt="Hero image"
    width="800"
    height="600"
    loading="lazy"
    format="webp"
  />
</template>

响应式图像

VUE
<NuxtImg
  src="/images/hero.jpg"
  sizes="sm:100vw md:50vw lg:400px"
  alt="Responsive hero image"
/>

缓存策略

HTTP 缓存头

JAVASCRIPT
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    routeRules: {
      '/': { prerender: true },
      '/blog/**': { isr: 60 }, // ISR with 60s revalidation
      '/api/**': { headers: { 'Cache-Control': 's-maxage=300' } }
    }
  }
})

浏览器缓存

JAVASCRIPT
// 使用 useFetch 的缓存选项
const { data } = await useFetch('/api/posts', {
  key: 'posts',
  server: true,
  default: () => [],
  transform: (data) => data.posts
})

预加载和预获取

关键资源预加载

VUE
<script setup>
useHead({
  link: [
    {
      rel: 'preload',
      href: '/fonts/main.woff2',
      as: 'font',
      type: 'font/woff2',
      crossorigin: 'anonymous'
    }
  ]
})
</script>

路由预获取

VUE
<NuxtLink 
  to="/blog" 
  prefetch
  class="nav-link"
>
  技术分享
</NuxtLink>

构建优化

Tree Shaking

JAVASCRIPT
// nuxt.config.ts
export default defineNuxtConfig({
  build: {
    transpile: ['@iconify/vue']
  },
  
  // 只导入需要的模块
  css: [
    '@/assets/css/main.css'
  ]
})

压缩和混淆

JAVASCRIPT
export default defineNuxtConfig({
  nitro: {
    minify: true,
    compressPublicAssets: true
  }
})

运行时优化

虚拟滚动

对于长列表,使用虚拟滚动:

VUE
<script setup>
import { RecycleScroller } from 'vue-virtual-scroller'

const items = ref([])
</script>

<template>
  <RecycleScroller
    class="scroller"
    :items="items"
    :item-size="80"
    key-field="id"
    v-slot="{ item }"
  >
    <div class="item">
      {{ item.title }}
    </div>
  </RecycleScroller>
</template>

防抖和节流

JAVASCRIPT
import { debounce } from 'lodash-es'

const searchInput = ref('')
const debouncedSearch = debounce((query) => {
  // 执行搜索
}, 300)

watch(searchInput, debouncedSearch)

监控和分析

Web Vitals

JAVASCRIPT
// plugins/web-vitals.client.js
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals'

export default defineNuxtPlugin(() => {
  getCLS(console.log)
  getFID(console.log)
  getFCP(console.log)
  getLCP(console.log)
  getTTFB(console.log)
})

Bundle 分析

BASH
npm run build -- --analyze

总结

性能优化是一个持续的过程,需要从多个维度考虑:

  1. 代码层面 - 代码分割、懒加载、Tree Shaking
  2. 资源层面 - 图像优化、字体优化、压缩
  3. 缓存层面 - HTTP 缓存、浏览器缓存、CDN
  4. 运行时层面 - 虚拟滚动、防抖节流、内存管理

记住,优化前先测量,优化后再验证。使用 Lighthouse、Chrome DevTools 等工具来指导你的优化工作。