
Use Server-Side Rendering
Use Server-Side Rendering 관련
In client-side rendering, you get the HTML file, download JavaScript files as needed, run the files, generate the DOM, and then render.
And in server-side rendering, the server returns the HTML file, and the client only needs to parse the HTML.
- Pros: Faster first-screen rendering, better SEO.
- Cons: Complicated configuration, increases the computational load on the server.
Below, I'll use Vue SSR as an example to briefly describe the SSR process.
Client-side rendering process
- Visit a client-rendered website.
- The server returns an HTML file containing resource import statements and
<div id="app"></div>
. - The client requests resources from the server via HTTP, and when the necessary resources are loaded, it executes
new Vue()
to instantiate and render the page.
Example of client-side rendered app (Vue):
<!DOCTYPE html>
<html>
<head>
<title>Client-side Rendering Example</title>
</head>
<body>
<!-- Initially empty container -->
<div id="app"></div>
<!-- JavaScript bundle that will render the content -->
<script src="/dist/bundle.js"></script>
</body>
</html>
import Vue from 'vue';
import App from './App.vue';
// Client-side rendering happens here - after JS loads and executes
new Vue({
render: h => h(App)
}).$mount('#app');
<template>
<div>
<h1>{{ title }}</h1>
<p>This content is rendered client-side.</p>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Hello World'
}
},
// In client-side rendering, this lifecycle hook runs in the browser
mounted() {
console.log('Component mounted in browser');
}
}
</script>
Server-side rendering process
- Visit a server-rendered website.
- The server checks which resource files the current route component needs, then fills the content of these files into the HTML file. If there are AJAX requests, it will execute them for data pre-fetching and fill them into the HTML file, and finally return this HTML page.
- When the client receives this HTML page, it can start rendering the page immediately. At the same time, the page also loads resources, and when the necessary resources are fully loaded, it begins to execute
new Vue()
to instantiate and take over the page.
Example of server-side rendered app (Vue):
const express = require('express');
const server = express();
const { createBundleRenderer } = require('vue-server-renderer');
// Create a renderer based on the server bundle
const renderer = createBundleRenderer('./dist/vue-ssr-server-bundle.json', {
template: require('fs').readFileSync('./index.template.html', 'utf-8'),
clientManifest: require('./dist/vue-ssr-client-manifest.json')
});
// Handle all routes with the same renderer
server.get('*', (req, res) => {
const context = { url: req.url };
// Render our Vue app to a string
renderer.renderToString(context, (err, html) => {
if (err) {
// Handle error
res.status(500).end('Server Error');
return;
}
// Send the rendered HTML to the client
res.end(html);
});
});
server.listen(8080);
<!DOCTYPE html>
<html>
<head>
<title>Server-side Rendering Example</title>
<!-- Resources injected by the server renderer -->
</head>
<body>
<!-- This will be replaced with the app's HTML -->
<!--vue-ssr-outlet-->
</body>
</html>
import { createApp } from './app';
export default context => {
return new Promise((resolve, reject) => {
const { app, router } = createApp();
// Set server-side router's location
router.push(context.url);
// Wait until router has resolved possible async components and hooks
router.onReady(() => {
const matchedComponents = router.getMatchedComponents();
// No matched routes, reject with 404
if (!matchedComponents.length) {
return reject({ code: 404 });
}
// The Promise resolves to the app instance
resolve(app);
}, reject);
});
}
From the two processes above, you can see that the difference lies in the second step. A client-rendered website will directly return the HTML file, while a server-rendered website will render the page completely before returning this HTML file.
What's the benefit of doing this? It's a faster time-to-content.
Suppose your website needs to load four files (a, b, c, d) to render completely. And each file is 1 MB in size.
Calculating this way: a client-rendered website needs to load 4 files and an HTML file to complete the home page rendering, totaling 4MB (ignoring the HTML file size). While a server-rendered website only needs to load a fully rendered HTML file to complete the home page rendering, totaling the size of the already rendered HTML file (which isn't usually too large, generally a few hundred KB; my personal blog website (SSR) loads an HTML file of 400KB). This is why server-side rendering is faster.