阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 服务端渲染API变化

服务端渲染API变化

作者:陈川 阅读数:42745人阅读 分类: Vue.js

服务端渲染API变化

Vue.js 的服务端渲染(SSR)在版本迭代中经历了多次API调整,核心逻辑从vue-server-renderer迁移到@vue/server-renderer,底层实现机制也发生了显著变化。这些改动直接影响着同构应用的生命周期处理、状态管理以及渲染管道的配置方式。

渲染器创建方式重构

早期版本通过createRenderer工厂函数生成渲染器实例:

const { createRenderer } = require('vue-server-renderer')
const renderer = createRenderer({
  template: '<div id="app">{{ html }}</div>'
})

Vue 3 改为使用ES模块导出的独立函数:

import { renderToString } from '@vue/server-renderer'
const html = await renderToString(app)

主要变更点包括:

  • 移除bundleRenderer概念,改为直接渲染Vue应用实例
  • 模板系统改为通过createSSRApp的根组件控制
  • 异步渲染默认返回Promise,需配合async/await使用

生命周期钩子调整

服务端特有的生命周期钩子从serverPrefetch更名为onServerPrefetch,并采用Composition API风格:

<script setup>
import { ref, onServerPrefetch } from 'vue'

const data = ref(null)
onServerPrefetch(async () => {
  data.value = await fetchData()
})
</script>

废弃的beforeCreatecreated钩子在SSR环境下不再被调用,初始化逻辑应迁移到setup()<script setup>中。

状态序列化机制变化

Vue 2使用context.renderState自动序列化状态:

context.renderState = { user: { name: 'Alice' } }

Vue 3改为显式使用useSSRContext组合式函数:

<script setup>
import { useSSRContext } from 'vue'

const ctx = useSSRContext()
ctx.user = { name: 'Alice' }
</script>

客户端注水过程也相应调整为:

const app = createSSRApp(App)
if (typeof window !== 'undefined') {
  const initialState = JSON.parse(window.__INITIAL_STATE__)
  // 手动恢复状态
}

异步组件处理改进

新版SSR对动态导入的组件提供更精细的控制:

defineAsyncComponent({
  loader: () => import('./Component.vue'),
  serverLoader: () => require('./Component.vue') // 专为SSR提供的加载器
})

关键改进包括:

  • 服务端和客户端可分别指定加载逻辑
  • 支持Suspense组件在SSR环境下的降级处理
  • 错误边界机制与SSR兼容性增强

流式渲染API升级

流式渲染接口从renderToStream变更为renderToNodeStream

// Vue 2
renderer.renderToStream(context)

// Vue 3
const stream = renderToNodeStream(app)
stream.pipe(res)

新增renderToWebStream支持Web Streams API:

const readable = renderToWebStream(app)
for await (const chunk of readable) {
  // 处理分块内容
}

白名单与黑名单配置

客户端敏感指令的过滤方式从字符串匹配改为正则表达式:

// 旧版
renderer.directives = {
  show: true // 白名单
}

// 新版
const { compile } = require('@vue/compiler-ssr')
compile(template, {
  directiveTransforms: {
    'my-dir': () => ({ props: [] }) // 自定义指令转换
  }
})

性能追踪API变更

性能分析从context.rendered回调改为独立API:

const { renderToString, performanceMark } = require('@vue/server-renderer')

performanceMark('renderStart')
const html = await renderToString(app)
performanceMark('renderEnd')

新增的指标包括:

  • 组件实例化耗时
  • 虚拟DOM生成时间
  • HTML序列化延迟

错误处理策略优化

错误捕获机制从全局errorHandler改为渲染上下文传递:

try {
  await renderToString(app, {
    onError(err) {
      // 专属错误处理
    }
  })
} catch (e) {
  // 顶层捕获
}

新增的错误类型包括:

  • 组件级SSR异常(错误代码SSR_COMPONENT_ERROR
  • 异步数据加载超时(错误代码SSR_FETCH_TIMEOUT
  • 客户端注水不匹配警告(错误代码HYDRATE_MISMATCH

自定义指令处理

SSR环境下的指令转换需要显式声明:

const app = createSSRApp({
  directives: {
    focus: {
      mounted(el) { /* 客户端实现 */ },
      ssrRender(props, vnode) {
        // 服务端模拟逻辑
        return { class: 'focused' }
      }
    }
  }
})

未实现ssrRender的指令会在服务端被静默忽略。

编译时配置调整

vue-loader的SSR相关配置迁移到编译器选项:

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => ({
        ...options,
        compilerOptions: {
          whitespace: 'condense',
          directiveTransforms: true // 启用指令转换
        }
      }))
  }
}

混合渲染模式支持

新增renderToSimpleStream用于混合渲染场景:

const { renderToSimpleStream } = require('@vue/server-renderer')

// 首屏SSR + 后续CSR
const stream = renderToSimpleStream(app, {
  push(chunk) {
    // 分块发送
  },
  destroy(err) {
    // 错误处理
  }
})

这种模式特别适合:

  • 大型静态页面的渐进式渲染
  • 流式传输中的优先级控制
  • 与CDN边缘计算的集成

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌