Understanding Server‑Side Rendering (SSR) with Vue: Principles, Architecture, and Implementation
This article explains the concepts, use cases, advantages, and limitations of server‑side rendering (SSR) for Vue applications, details the Vue SSR architecture and core packages, and provides practical code examples and ready‑to‑use scaffolds for building SSR projects.
Preface
In front‑end development, when first‑screen rendering speed is critical, server‑side rendering (SSR) is often mentioned. This article uses Vue to dissect SSR implementation logic, covering its usage scenarios, core principles, and ready‑to‑use scaffolds.
Server‑Side Rendering
SSR (Server‑Side Rendering) means assembling the page’s HTML on the server, sending it to the browser, and then binding events and state on the client to produce a fully interactive application.
Applicable Scenarios
Better SEO support : Search engines crawl the HTML synchronously, so SSR helps when the page relies on asynchronous data.
Faster time‑to‑content : In slow‑network or low‑performance device contexts, SSR shows the first screen earlier than a full SPA.
Unsuitable Scenarios
Handling universal resources : Only beforeCreate and created lifecycle hooks run in SSR, requiring special handling for third‑party APIs.
Deployment and build configuration : The code must run in a Node.js server environment.
Server‑side caching preparation : High‑traffic scenarios need extra caching strategies, and SSR consumes more CPU.
Vue SSR Implementation Principles
Prerequisites
Component Rendering Based on VNode
VNode is a JavaScript object with strong compatibility, allowing rendering on both server and client. Virtual DOM diffing enables partial rendering and reduces performance loss.
vue‑server‑renderer
This package provides the core SSR capabilities for Vue.
SSR Rendering Architecture
Combining the official diagram and project structure gives a full view of SSR.
src
├── components
├── App.vue
├── app.js ---- common entry
├── entry-client.js ---- runs only in the browser
└── entry-server.js ---- runs only on the server import Vue from 'vue'
import App from './App.vue'
// Export a factory function that creates a new app instance
export function createApp () {
const app = new Vue({
render: h => h(App)
})
return { app }
} import { createApp } from './app'
const { app } = createApp()
// #app is the root element
app.$mount('#app') import { createApp } from './app'
export default context => {
const { app } = createApp()
return app
}Server and Client Code Writing Principles
Two principles guide code separation:
Common code: Shared between client and server, configured via webpack resolve.alias.
Non‑common code: Client entry mounts DOM and loads third‑party libraries; server entry only creates the Vue instance.
Two Build Outputs
After webpack bundling, two bundles are produced:
vue‑SSR‑server‑bundle.json
{
"entry": ...,
"files": {
// All server‑side code files
// Entry file
}
} vue‑SSR‑client‑manifest.json
{
"publicPath": ...,
"all": [...],
"initial": "html string",
"async": [...],
"modules": {...}
}vue‑server‑renderer Core
The package focuses on application initialization and output.
Application Initialization
Key steps:
Generate Vue object.
Create renderer with render and templateRenderer objects.
Create sandbox VM and load the entry file.
Handle errors with renderToString and renderToStream promises.
const renderer = require('vue-server-renderer').createRenderer()
function createRenderer (ref) {
// render: renders HTML components
var render = createRenderFunction(modules, directives, isUnaryTag, cache)
// templateRenderer: handles template rendering
var templateRenderer = new TemplateRenderer({
template, inject, shouldPreload, shouldPrefetch, clientManifest, serializer
})
} function createBundleRunner (entry, files, basedir, runInNewContext) {
var evaluate = compileModule(files, basedir, runInNewContext)
} function getCompiledScript (filename) {
if (compiledScripts[filename]) return compiledScripts[filename]
var code = files[filename]
var wrapper = NativeModule.wrap(code)
var script = new vm.Script(wrapper, { filename, displayErrors: true })
compiledScripts[filename] = script
return script
} function evaluateModule (filename, sandbox, evaluatedFiles) {
var script = getCompiledScript(filename)
var compiledWrapper = runInNewContext === false
? script.runInThisContext()
: script.runInNewContext(sandbox)
var m = { exports: {} }
var r = function (file) { return require(file) }
}Preventing Cross‑Pollution
Node.js processes run long‑lived, so shared state can leak between requests. Using rendererOptions.runInNewContext (true, false, once) isolates each render.
// rendererOptions.runInNewContext options
true: create a new context for each render (isolated but slower)
false: reuse the same context (faster, but must avoid state leakage)
once: initial context for style collection onlyApplication Output
During output, SSR focuses on loading script content and template rendering. templateRenderer assembles HTML with resource hints, state, scripts, and styles.
TemplateRenderer.prototype.bindRenderFns = function (context) {
var renderer = this
['ResourceHints','State','Scripts','Styles'].forEach(function (type) {
context['render' + type] = renderer['render' + type].bind(renderer, context)
})
} TemplateRenderer.prototype.render = function (content, context) {
if (!this.parsedTemplate) throw new Error('render cannot be called without a template.')
if (typeof this.parsedTemplate === 'function') {
return this.parsedTemplate(content, context)
}
if (this.inject) {
return (
this.parsedTemplate.head(context) +
(context.head || '') +
this.renderResourceHints(context) +
this.renderStyles(context) +
this.parsedTemplate.neck(context) +
content +
this.renderState(context) +
this.renderScripts(context) +
this.parsedTemplate.tail(context)
)
} else {
// ...
}
}Ready‑to‑Use SSR Scaffolds
Popular front‑end stacks provide out‑of‑the‑box SSR frameworks:
React: Next.js
Vue: Nuxt.js
Angular: Nest.js
Conclusion
SSR is a universal rendering technique; its adoption depends on the importance of initial load time for the application. For learning purposes, studying the source helps understand advanced architecture, while ready‑made scaffolds offer a smoother setup experience.
References
Vue SSR Official Site (https://ssr.vuejs.org/zh)
Vue Guide (https://www.w3cschool.cn/vuessr/vuessr-jep83epx.html)
Vue SSR Source Analysis (https://juejin.cn/post/6844903812700831757)
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
