前端学习笔记-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 是最后的重武器。
相关推荐
用户985033593281 小时前
OpenLayers 热力图从原理到 Vue 组件一键接入
前端
颜酱2 小时前
01 | 骨架搭建:FastAPI + Vue 跑通第一个 SSE 流式问答
前端·人工智能·后端
hoLzwEge2 小时前
解码 IDE 智能提示:jsconfig.json 辅助开发全攻略
前端·前端框架
leoZ2312 小时前
记忆系统与 Agent 定制完全指南(四):自定义 Agent 开发(一)
前端·chrome
慧一居士2 小时前
Element Plus 按需引入的配置使用说明和完整示例
前端·vue.js
程序员黑豆2 小时前
鸿蒙应用开发实战:从零学会自定义组件
前端·华为·harmonyos
leoZ2312 小时前
记忆系统与 Agent 定制完全指南(三):记忆的检索与使用
前端·chrome
遇乐的果园2 小时前
前端学习笔记-vue状态管理优化
前端·笔记·学习
从零开始的代码生活_3 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法