Home > Article > Web Front-end > Does vue3.0 support server-side rendering?
vue3.0 supports server-side rendering. Vue supports rendering components directly into HTML strings on the server side, returning them to the browser as a server-side response, and finally "activating" (hydrate) the static HTML on the browser side into an interactive client application. A server-rendered Vue application can be considered "isomorphic" or "universal" because most of the application's code runs on both the server and the client. Advantages of Vue using server-side rendering: Faster first screen Loading, unified mental model, better SEO.
The operating environment of this tutorial: windows7 system, vue3 version, DELL G3 computer.
vue supports server-side rendering (SSR).
Vue.js is a framework for building client-side applications. By default, the responsibility of the Vue component is to generate it in the browser and operate DOM. However, Vue also supports rendering components directly into HTML strings on the server side, returning them to the browser as a server-side response, and finally "activating" (hydrate) the static HTML on the browser side for clients who can interact. Side application.
A Vue.js application rendered by the server can also be considered "isomorphic" (Isomorphic) or "universal" (Universal), because most of the application's code runs simultaneously on Server and client.
Why use server-side rendering (SSR)?
Compared with client-side single-page application (SPA) Compared with SSR, the main advantages of SSR are:
Faster first screen loading: This is especially important on slow network speeds or slow-running devices. Server side The rendered HTML doesn't have to wait for all JavaScript to be downloaded and executed before it's displayed, so your users will see the fully rendered page faster. In addition, the data retrieval process is completed server-side on the first visit, There may be a faster database connection than fetching from the client. This usually leads to higher core web metric scores, better user experience, and for those "first screen loading speed is directly related to conversion rate" For applications, this may be crucial. [Related recommendations: vuejs video tutorial, web front-end development]
Unified mental model: You can develop the entire application using the same language and the same declarative, component-oriented mental model without having to switch back and forth between the back-end template system and the front-end framework.
Better SEO: Search engine crawlers can see the fully rendered page directly.
There are some trade-offs when using SSR Things to consider:
Limitations in development. Specific code on the browser side can only be used in certain life cycle hooks; some external libraries may require special processing to be used on the server side. Run within a rendered application.
More requirements related to build configuration and deployment. Server-side rendering applications require an environment that allows the Node.js server to run. Unlike completely static SPA, which can be deployed on any static file server.
Higher server load. Rendering a complete app in Node.js is more CPU intensive than just hosting static files, so if you anticipate high traffic, prepare for the corresponding server load and adopt a sensible caching strategy.
Server Side Rendering (SSR) vs. Static Site Generation (SSG)
Static Site Generation (Static-Site Generation, abbreviated as SSG), also known as Pre-rendering, is another popular technology for building fast websites. If the data required to render a page server-side is the same for every user, then we can render it only once and do it ahead of time during the build process, rather than re-rendering the page every time a request comes in. Pre-rendered pages are generated and hosted on the server as static HTML files.
SSG retains the same performance as SSR applications: it brings excellent first-screen loading performance. At the same time, it is less expensive and easier to deploy than SSR applications because it outputs static HTML and resource files. The key word here is static: SSG can only be used for pages that consume static data, i.e. the data is known during build time and does not change across multiple deployments. Whenever the data changes, it needs to be redeployed.
If you are investigating SSR only to optimize the SEO of a few marketing pages (such as /, /about and /contact, etc.), then you may need SSG instead of SSR. SSG is also great for building content-based websites, such as documentation sites or blogs. In fact, the website you are reading now was statically generated using VitePress, a static site generator powered by Vue.
Hello World
Get ready to experience server-side rendering in action. Server-side rendering (ie SSR) sounds complicated, but a simple Node script only requires 3 steps to achieve this function:
// 步骤 1:创建一个Vue实例 var Vue = require('vue') var app = new Vue({ render: function (h) { return h('p', 'hello world') } }) // 步骤 2: 创建一个渲染器 var renderer = require('vue-server-renderer').createRenderer() // 步骤 3: 将 Vue实例 渲染成 HTML renderer.renderToString(app, function (error, html) { if (error) throw error console.log(html) // => <p server-rendered="true">hello world</p> })
It's not difficult. Of course, this example is simpler than most applications to explore how these functions work
Simple server-side rendering through Express Web server
It's hard to say server-side rendering without a web server, so let's supplement it. We will build a very simple server-side rendering application using only ES5 and no other build steps or Vue plugins.
Launch an app that tells users how much time they spent on a page.
new Vue({ template: '<div>你已经在这花了 {{ counter }} 秒。</div>', data: { counter: 0 }, created: function () { var vm = this setInterval(function () { vm.counter += 1 }, 1000) } })
In order to adapt to server-side rendering, we need to make some modifications so that it can be rendered in the browser and Node:
In the browser, change our The application instance is added to the global context (window) and we can install it.
In Node, exporting a factory function allows us to create an application instance for each request.
A little template is needed to implement this:
// assets/app.js (function () { 'use strict' var createApp = function () { // --------------------- // 开始常用的应用代码 // --------------------- // 主要的Vue实例必须返回,并且有一个根节点在id "app"上,这样客户端可以加载它。 return new Vue({ template: '<div id="app">你已经在这花了 {{ counter }} 秒。</div>', data: { counter: 0 }, created: function () { var vm = this setInterval(function () { vm.counter += 1 }, 1000) } }) // ------------------- // 结束常用的应用代码 // ------------------- } if (typeof module !== 'undefined' && module.exports) { module.exports = createApp } else { this.app = createApp() } }).call(this)
Now that we have the application code, add an html file.
<!-- index.html --> <!DOCTYPE html> <html> <head> <title>My Vue App</title> <script src="/assets/vue.js"></script> </head> <body> <div id="app"></div> <script src="/assets/app.js"></script> <script>app.$mount('#app')</script> </body> </html>
Mainly refer to the app.js we created previously in the assets folder, and the vue.js file, we have a single-page application that can run
Then in order to implement server-side rendering , a step needs to be added on the server side.
// server.js 'use strict' var fs = require('fs') var path = require('path') // 定义全局的Vue为了服务端的app.js global.Vue = require('vue') // 获取HTML布局 var layout = fs.readFileSync('./index.html', 'utf8') // 创建一个渲染器 var renderer = require('vue-server-renderer').createRenderer() // 创建一个Express服务器 var express = require('express') var server = express() // 部署静态文件夹为 "assets"文件夹 server.use('/assets', express.static( path.resolve(__dirname, 'assets') )) // 处理所有的Get请求 server.get('*', function (request, response) { // 渲染我们的Vue应用为一个字符串 renderer.renderToString( // 创建一个应用实例 require('./assets/app')(), // 处理渲染结果 function (error, html) { // 如果渲染时发生了错误 if (error) { // 打印错误到控制台 console.error(error) // 告诉客户端错误 return response .status(500) .send('Server Error') } // 发送布局和HTML文件 response.send(layout.replace('<div id="app"></div>', html)) } ) }) // 监听5000端口 server.listen(5000, function (error) { if (error) throw error console.log('Server is running at localhost:5000') })
That’s it. Entire example, clone it for in-depth experiment. Once it's running locally, you can confirm that the service selected by Renderer is actually running by right-clicking on the page and selecting Page Resources (or similar). You can see in the body:
<div id="app" server-rendered="true">You have been here for 0 seconds.</div>
instead of:
<div id="app"></div>
Streaming response
Vue also supports streaming rendering , the preference applies to web servers that support streaming. Allows HTML to be generated and written generally to the corresponding stream, rather than being written all at once. The result is that requests are served faster, with no drawbacks!
In order to make the application code in the previous section suitable for streaming rendering, you can simply replace server.get('*',...) with the following code:
// 拆分布局成两段HTML var layoutSections = layout.split('<div id="app"></div>') var preAppHTML = layoutSections[0] var postAppHTML = layoutSections[1] // 处理所有的Get请求 server.get('*', function (request, response) { // 渲染我们的Vue实例作为流 var stream = renderer.renderToStream(require('./assets/app')()) // 将预先的HTML写入响应 response.write(preAppHTML) // 每当新的块被渲染 stream.on('data', function (chunk) { // 将块写入响应 response.write(chunk) }) // 当所有的块被渲染完成 stream.on('end', function () { // 将post-app HTML写入响应 response.end(postAppHTML) }) // 当渲染时发生错误 stream.on('error', function (error) { // 打印错误到控制台 console.error(error) // 告诉客服端发生了错误 return response .status(500) .send('Server Error') }) })
This is no better than the previous one Versioning is complex, and even this may not be a new concept to you. We did:
Build the stream
Write the HTML before applying the response
In Apply HTML to write response when available
Write HTML at the end of response
Handle any errors
Component Caching
Vue’s server-side rendering is very fast by default, but you can further improve performance by caching rendered components. This is considered an advanced feature, however, if the wrong component is cached (or the correct component has the wrong content) it will cause the app to render incorrectly. Special note:
Components containing subcomponents that depend on global state (such as state from vuex) should not be cached. If you do this, the subcomponent (in fact the entire subtree) will also be cached. So pay special attention to situations with slots fragments or subcomponents.
Settings
Outside of warning conditions, we can use the following method to cache components.
First, you need to provide a cache object to the renderer. Here's a simple example using lru-cache
var createRenderer = require('vue-server-renderer').createRenderer var lru = require('lru-cache') var renderer = createRenderer({ cache: lru(1000) })
which will cache up to 1000 independent renders. For further configuration of caching into content, see lru-cache settings
Then for the components you want to cache, you can provide them with:
A unique name
A serverCacheKey function, returns a unique component scope
For example:
Vue.component({ name: 'list-item', template: '<li>{{ item.name }}</li>', props: ['item'], serverCacheKey: function (props) { return props.item.type + '::' + props.item.id } })
Ideal components for caching
Any pure component can be safely cached - this is to ensure that passing the same data to any component will produce the same HTML. Examples of these scenarios include:
Static components (e.g. always try the same HTML, so the serverCacheKey function can return true)
List components (caching them can improve performance when you have large lists) )
Now, you should understand the basic concepts behind server-side rendering. However, the build process, routing, and Vuex each have their own considerations. (Learning video sharing:
vuejs introductory tutorial,
Basic programming videoThe above is the detailed content of Does vue3.0 support server-side rendering?. For more information, please follow other related articles on the PHP Chinese website!