前端学习笔记-vue加载渲染优化

16 路由懒加载 + 异步组件

一句话理解

别把所有页面的代码打包成一个大 JS 文件------用到哪个页面才加载哪个(按需加载),首屏只加载首页代码。

为什么

SPA(单页应用)默认把所有路由组件打进一个 bundle。用户打开首页,却下载了"设置页、订单页、报表页......"的全部代码------大部分用不上,白等。

懒加载把每个路由拆成独立的小 chunk,访问时才请求。

代码示例

路由懒加载(最常用):

js 复制代码
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/',
    component: () => import('../views/Home.vue'),     // 懒加载
  },
  {
    path: '/dashboard',
    component: () => import('../views/Dashboard.vue'), // 访问 /dashboard 时才加载
  },
  {
    path: '/settings',
    component: () => import('../views/Settings.vue'),  // 访问 /settings 时才加载
  },
]

export default createRouter({ history: createWebHistory(), routes })

组件级异步加载(重组件按需加载):

vue 复制代码
<script setup>
import { defineAsyncComponent, ref } from 'vue'

// 只在需要渲染时才加载这个重组件
const HeavyChart = defineAsyncComponent(() => import('./HeavyChart.vue'))

const showChart = ref(false)
</script>

<template>
  <button @click="showChart = true">加载图表</button>
  <HeavyChart v-if="showChart" />
</template>

带 loading / error 的异步组件:

js 复制代码
import { defineAsyncComponent, h } from 'vue'

const ReportPanel = defineAsyncComponent({
  loader: () => import('./ReportPanel.vue'),
  loadingComponent: () => h('div', '加载中...'),  // 加载时显示
  errorComponent:   () => h('div', '加载失败'),    // 失败时显示
  delay: 200,    // 200ms 后才显示 loading(避免闪烁)
  timeout: 10000,// 10s 超时判定失败
})

新人提示

  • 路由懒加载是 SPA 的标配,几乎是必做的优化,零成本收益大。
  • 异步组件适合重组件(图表、富文本编辑器、大表格),别滥用在小组件上。

17 预渲染(Prerendering)

一句话理解

如果你的页面内容大部分是静态的 (如博客、官网、文档),可以在构建时就把页面渲染成完整 HTML,用户打开直接拿到成品------既快又对 SEO 友好,还不需要服务器实时渲染。

为什么

  • 和 SSR 的区别:预渲染在 build 阶段一次性生成 HTML,运行时服务器只发静态文件;SSR 是每次请求都实时渲染。
  • 预渲染适合内容固定、不随用户变化 的页面;SSR 适合内容动态、千人千面的页面。

代码示例

Vite 项目用 vite-plugin-ssgvite-plugin-prerender

js 复制代码
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { ViteSSG } from 'vite-ssg'

export default defineConfig({
  plugins: [
    vue(),
    // 预渲染:构建时把指定路由生成静态 HTML
    ViteSSG({ /* 配置 */ }),
  ],
})

Vue 2 时代用 prerender-spa-plugin(理解原理):

js 复制代码
// 构建时用无头浏览器访问这些路由,把渲染结果存成 HTML 文件
new PrerenderSPAPlugin({
  routes: ['/', '/about', '/contact'],  // 这些页面会被预渲染成静态 HTML
})

新人提示

  • 适用场景:官网首页、博客文章、文档站、营销页------内容固定,追求首屏速度和 SEO。
  • 不适用:后台管理系统、社交动态流------内容因人而异,预渲染没意义,该上 SSR。
  • 预渲染的产物就是一堆 .html,部署到任何静态服务器(Nginx / CDN)都行。

18 SSR 服务端渲染

一句话理解

Node 服务器 把 Vue 组件渲染成 HTML 字符串发给浏览器,浏览器收到后直接显示(首屏秒开),然后再"激活"(hydrate)成可交互的 SPA。

为什么

指标 纯 CSR(普通 SPA) SSR
首屏白屏时间 长(要下载 JS + 执行 + 渲染) 短(HTML 直接显示)
SEO 差(爬虫看到空壳) 好(直接有内容)
服务器压力 低(只发静态文件) 高(每次请求都要渲染)
开发复杂度 高(要兼容服务端环境)

代码示例

用 Nuxt 3(Vue 官方推荐的 SSR 框架,开箱即用):

bash 复制代码
# 一行命令创建 SSR 项目
npx nuxi init my-ssr-app
cd my-ssr-app
npm install
npm run dev    # 开发
npm run build  # 构建 SSR 产物

服务端数据获取(Nuxt 的 useFetch,服务端执行):

vue 复制代码
<!-- pages/posts/[id].vue -->
<template>
  <article>
    <h1>{{ post.title }}</h1>
    <div>{{ post.content }}</div>
  </article>
</template>

<script setup>
// useFetch 在服务端就执行,HTML 里直接带数据,首屏即有内容
const { data: post } = await useFetch(`/api/posts/${route.params.id}`)
</script>

SSR 的坑(新人必看)

js 复制代码
import { onMounted } from 'vue'

// 错:服务端没有 window / document,setup 顶层直接用会报错
// const width = window.innerWidth

// 对:浏览器专属代码放进 onMounted(只在客户端执行)
onMounted(() => {
  const width = window.innerWidth
  console.log(width)
})

新人提示

  • 别为了"快"就上 SSR------它带来服务器成本、部署复杂度、调试难度。
  • 先问自己:"我真的需要 SEO 吗?首屏真的慢到需要 SSR 吗?" 不需要就别上。
  • 优先级:懒加载 + 预渲染能解决的,就别上 SSR。SSR 是最后的重武器。
相关推荐
l1m0_16 分钟前
智能电动自行车管理后台实战:AI生成页面与React组件化技巧
前端·react.js·ui·ai·设计
xian_wwq23 分钟前
【学习笔记】-深度认知系列-第8讲主流AI模型横向评测——GPT、Claude、Gemini、盘古、文心、通义
人工智能·笔记·学习
Patrick_Wilson31 分钟前
为什么gitlab的MR会默认有一个merge commit
前端·git·gitlab
大牧师31 分钟前
TypeORM 学习教程
数据库·sql·学习·node.js·orm·nest.js·typeorm
en.en..41 分钟前
Linux mmap 内存映射深度解析:基于帧缓冲 /dev/fb0
java·服务器·前端
后台模板学习1 小时前
从0到1用Vite构建电商订单系统前端性能优化方案
前端
Wang's Blog1 小时前
Vibe Coding一人即团队系列58: HTML演示文稿自动生成
前端·人工智能·html
晨欣1 小时前
NVIDIA GPU 架构演进学习笔记(GPT-5.6 Terra 生成)
笔记·学习·gpu·显卡·nvidia·英伟达
FoldWinCard2 小时前
基于k8s高可用web集群
前端·容器·kubernetes
神探小白牙2 小时前
海康视频在vue2.0中的使用
前端·音视频