阿里云主机折上折
  • 微信号
Current Site:Index > Server-side rendering API changes

Server-side rendering API changes

Author:Chuan Chen 阅读数:42746人阅读 分类: Vue.js

Changes in Server-Side Rendering APIs

Vue.js' Server-Side Rendering (SSR) has undergone multiple API adjustments during version iterations. The core logic has migrated from vue-server-renderer to @vue/server-renderer, with significant changes in the underlying implementation mechanisms. These modifications directly impact the lifecycle handling of isomorphic applications, state management, and the configuration of rendering pipelines.

Renderer Creation Method Refactoring

Earlier versions used the createRenderer factory function to generate renderer instances:

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

Vue 3 now uses standalone functions exported via ES modules:

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

Key changes include:

  • Removal of the bundleRenderer concept, replaced by direct rendering of Vue app instances
  • The template system is now controlled via the root component of createSSRApp
  • Asynchronous rendering now returns a Promise by default, requiring async/await usage

Lifecycle Hook Adjustments

The server-specific lifecycle hook has been renamed from serverPrefetch to onServerPrefetch and adopts the Composition API style:

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

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

The deprecated beforeCreate and created hooks are no longer called in SSR environments, and initialization logic should be migrated to setup() or <script setup>.

State Serialization Mechanism Changes

Vue 2 used context.renderState for automatic state serialization:

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

Vue 3 now explicitly uses the useSSRContext composable function:

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

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

The client-side hydration process has also been adjusted accordingly:

const app = createSSRApp(App)
if (typeof window !== 'undefined') {
  const initialState = JSON.parse(window.__INITIAL_STATE__)
  // Manually restore state
}

Async Component Handling Improvements

The new SSR provides finer control over dynamically imported components:

defineAsyncComponent({
  loader: () => import('./Component.vue'),
  serverLoader: () => require('./Component.vue') // Loader specifically for SSR
})

Key improvements include:

  • Separate loading logic can be specified for server and client
  • Support for Suspense component fallback handling in SSR environments
  • Enhanced compatibility of error boundary mechanisms with SSR

Streaming Rendering API Upgrade

The streaming rendering interface has changed from renderToStream to renderToNodeStream:

// Vue 2
renderer.renderToStream(context)

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

Added renderToWebStream to support the Web Streams API:

const readable = renderToWebStream(app)
for await (const chunk of readable) {
  // Process chunked content
}

Whitelist and Blacklist Configuration

The filtering of client-sensitive directives has changed from string matching to regular expressions:

// Old version
renderer.directives = {
  show: true // Whitelist
}

// New version
const { compile } = require('@vue/compiler-ssr')
compile(template, {
  directiveTransforms: {
    'my-dir': () => ({ props: [] }) // Custom directive transformation
  }
})

Performance Tracking API Changes

Performance analysis has moved from the context.rendered callback to a standalone API:

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

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

New metrics include:

  • Component instantiation time
  • Virtual DOM generation time
  • HTML serialization delay

Error Handling Strategy Optimization

The error capture mechanism has changed from global errorHandler to rendering context passing:

try {
  await renderToString(app, {
    onError(err) {
      // Dedicated error handling
    }
  })
} catch (e) {
  // Top-level capture
}

New error types include:

  • Component-level SSR exceptions (error code SSR_COMPONENT_ERROR)
  • Async data loading timeout (error code SSR_FETCH_TIMEOUT)
  • Client-side hydration mismatch warnings (error code HYDRATE_MISMATCH)

Custom Directive Handling

Directive transformations in SSR environments now require explicit declaration:

const app = createSSRApp({
  directives: {
    focus: {
      mounted(el) { /* Client-side implementation */ },
      ssrRender(props, vnode) {
        // Server-side simulation logic
        return { class: 'focused' }
      }
    }
  }
})

Directives without ssrRender will be silently ignored on the server.

Compile-Time Configuration Adjustments

SSR-related configurations in vue-loader have migrated to compiler options:

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => ({
        ...options,
        compilerOptions: {
          whitespace: 'condense',
          directiveTransforms: true // Enable directive transformations
        }
      }))
  }
}

Hybrid Rendering Mode Support

Added renderToSimpleStream for hybrid rendering scenarios:

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

// Initial SSR + Subsequent CSR
const stream = renderToSimpleStream(app, {
  push(chunk) {
    // Send chunks
  },
  destroy(err) {
    // Error handling
  }
})

This mode is particularly suitable for:

  • Progressive rendering of large static pages
  • Priority control during streaming
  • Integration with CDN edge computing

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

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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.