search
HomeWeb Front-endVue.jsWhat is SSR? How to implement SSR server-side rendering in vue?

What is SSR? The following article will introduce to you how to implement SSR server-side rendering in vue. I hope it will be helpful to you!

What is SSR? How to implement SSR server-side rendering in vue?

1. What is SSR

Server-Side Rendering We call it SSR , meaning server-side rendering

refers to the page processing technology that completes the HTML structure splicing of the page on the server side, sends it to the browser, and then binds status and events to it. The process of becoming a fully interactive page. [Related recommendations: vuejs video tutorial]

Let’s first take a look at the development history of Web in three stages:

  • Traditional server Rendering SSR
  • Single page application SPA
  • Server-side rendering SSR

Traditional web development

Web page content is served End-side rendering is completed and transferred to the browser in one go

What is SSR? How to implement SSR server-side rendering in vue?

Open the page to view the source code. What the browser gets is the entire dom structure

Single Page Application SPA

The excellent user experience of single page applications has gradually made it become mainstream. The page content is rendered by JS. This method is called Render for the client

What is SSR? How to implement SSR server-side rendering in vue?

#Open the page to view the source code, the browser only gets the host element#app, and no content

Server-side rendering SSR

SSRSolution, the backend renders the complete first screen dom structure return, the front end gets it The content includes the first screen and the complete spa structure. After the application is activated, it will still run in the spa way

What is SSR? How to implement SSR server-side rendering in vue?

After reading the front-end development, we Let’s take a look at Vue’s official explanation of SSR:

Vue.js is a framework for building client applications. By default, Vue components can be output in the browser to generate DOM and manipulate DOM. However, it is also possible to render the same components as server-side HTML strings, send them directly to the browser, and finally "activate" these static tags into a fully interactive application on the client

Server Rendering Vue.js applications can also be considered "isomorphic" or "universal" because most of the application's code can run on both the server and the client

We get it from Home Explained The following conclusions:

  • Vue SSR is an improved server-side rendering on SPA
  • Vue SSR
  • The rendered page needs to be activated on the client to achieve interaction
  • Vue SSR
  • will contain two parts: the first screen rendered by the server, and the interactive SPA
2. What is solved

SSR mainly solves the following two problems:

seo: search engine priority crawling Take the page
    HTML
  • structure and use ssr, the server has already generated the HTML associated with the business, which is beneficial to seoFirst screen rendering: Users can see the page view without waiting for all
  • js
  • of the page to be loaded (the pressure comes to the server, so it is necessary to weigh which should be rendered on the server side and which should be left to the client)
  • But using
SSR

also has the following shortcomings:

    Complexity: the complexity of the entire project
  • Library support, code compatibility
  • Performance issues
  • Each request is
      n
    • instances Creation, otherwise it will be polluted and the consumption will become very large cache
    • node serve
    • , nginx determine whether the current user has expired, and cache it if it has not expired , use the result just now. Downgrade: Monitor
    • cpu
    • , if the memory usage is too much, spa, return a single shell
  • The server load increases. Compared with the front-end and back-end separated servers that only need to provide static resources, the server load is greater, so we must use it carefully
  • So when we choose whether to use
Before SSR

, we need to carefully ask ourselves these questions:

    Are there only a few pages that require
  • SEO

    , and can these use pre-rendering ( How Implementation

    For isomorphic development, we still use
  • webpack
  • for packaging. We have to solve two problems: server-side first screen rendering and client-side activation

    Here you need to generate a serverbundle file for server first screen rendering and a clientbundle file for client activation

    What is SSR? How to implement SSR server-side rendering in vue?

    Except for two different entrances, the code structure is exactly the same as the previous vueapplication

    src 
    ├── router 
    ├────── index.js # 路由声明 
    ├── store 
    ├────── index.js # 全局状态 
    ├── main.js # ⽤于创建vue实例 
    ├── entry-client.js # 客户端⼊⼝,⽤于静态内容“激活” 
    └── entry-server.js # 服务端⼊⼝,⽤于⾸屏内容渲染

    Routing configuration

    import Vue from "vue"; import Router from "vue-router"; Vue.use(Router);
    //导出⼯⼚函数
    export function createRouter(){
        return new Router({
        mode: 'history',
        routes: [ 
           // 客户端没有编译器,这⾥要写成渲染函数 
            { path: "/", component: { render: h => h('div', 'index page') } }, 
            { path: "/detail", component: { render: h => h('div', 'detail page') }} 
        ] 
      });
     }

    Main file main.js

    Different from before, the main file is the factory responsible for creating vue instances. Each request will have an independent vue instance created

    import Vue from "vue";
    import App from "./App.vue";
    import { createRouter } from "./router"; 
    // 导出Vue实例⼯⼚函数,为每次请求创建独⽴实例 
    // 上下⽂⽤于给vue实例传递参数
    export function createApp(context) {
        const router = createRouter();
        const app = new Vue({ router, context, render: h => h(App) });
        return { app, router };
      }

    Write the server entry src/entry-server.js

    Its task is to create a Vue instance and specify the first screen based on the incoming url

    import { createApp } from "./main";
    // 返回⼀个函数,接收请求上下⽂,返回创建的vue实例
    export default context => {
    // 这⾥返回⼀个Promise,确保路由或组件准备就绪
        return new Promise((resolve, reject) => {
            const { app, router } = createApp(context);
            // 跳转到⾸屏的地址
            router.push(context.url);
            // 路由就绪,返回结果
            router.onReady(() => {
            resolve(app);
            }, reject);
        }); 
    };

    Writing the client entryentry-client.js

    The client entry only needs to create the vue instance and perform mounting. This step Called activation

    import { createApp } from "./main"; 
    // 创建vue、router实例
    const { app, router } = createApp();
    // 路由就绪,执⾏挂载
    router.onReady(() => { app.$mount("#app"); });

    Configurewebpack

    Install dependencies

    npm install webpack-node-externals lodash.merge -D

    Configure vue.config.js

    // 两个插件分别负责打包客户端和服务端
    const VueSSRServerPlugin = require("vue-server-renderer/server-plugin");
    const VueSSRClientPlugin = require("vue-server-renderer/client-plugin");
    const nodeExternals = require("webpack-node-externals");
    const merge = require("lodash.merge");
    // 根据传⼊环境变量决定⼊⼝⽂件和相应配置项
    const TARGET_NODE = process.env.WEBPACK_TARGET === "node";
    const target = TARGET_NODE ? "server" : "client";
    module.exports = {
        css: {
            extract: false
        },
        outputDir: './dist/'+target,
        configureWebpack: () => ({
            // 将 entry 指向应⽤程序的 server / client ⽂件
            entry: `./src/entry-${target}.js`,
            // 对 bundle renderer 提供 source map ⽀持
            devtool: 'source-map',
            // target设置为node使webpack以Node适⽤的⽅式处理动态导⼊,
            // 并且还会在编译Vue组件时告知`vue-loader`输出⾯向服务器代码。
            target: TARGET_NODE ? "node" : "web",
            // 是否模拟node全局变量
            node: TARGET_NODE ? undefined : false,
            output: {
                // 此处使⽤Node⻛格导出模块
                libraryTarget: TARGET_NODE ? "commonjs2" : undefined
            },
            // https://webpack.js.org/configuration/externals/#function
            // https://github.com/liady/webpack-node-externals
            // 外置化应⽤程序依赖模块。可以使服务器构建速度更快,并⽣成较⼩的打包⽂件。
            externals: TARGET_NODE
            ? nodeExternals({
                // 不要外置化webpack需要处理的依赖模块。
                // 可以在这⾥添加更多的⽂件类型。例如,未处理 *.vue 原始⽂件,
                // 还应该将修改`global`(例如polyfill)的依赖模块列⼊⽩名单
                whitelist: [/\.css$/]
            })
            : undefined,
            optimization: {
                splitChunks: undefined
            },
            // 这是将服务器的整个输出构建为单个 JSON ⽂件的插件。
            // 服务端默认⽂件名为 `vue-ssr-server-bundle.json`
            // 客户端默认⽂件名为 `vue-ssr-client-manifest.json`。
            plugins: [TARGET_NODE ? new VueSSRServerPlugin() : new
                      VueSSRClientPlugin()]
        }),
        chainWebpack: config => {
            // cli4项⽬添加
            if (TARGET_NODE) {
                config.optimization.delete('splitChunks')
            }
    
            config.module
                .rule("vue")
                .use("vue-loader")
                .tap(options => {
                merge(options, {
                    optimizeSSR: false
                });
            });
        }
    };

    Configure the script and install dependencies

    npm i cross-env - D

    "scripts": {
     "build:client": "vue-cli-service build",
     "build:server": "cross-env WEBPACK_TARGET=node vue-cli-service build",
     "build": "npm run build:server && npm run build:client"
    }

    Execute packaging: npm run build

    Last modification of the host file/public/index.html

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width,initial-scale=1.0">
            <title>Document</title>
        </head>
        <body>
            <!--vue-ssr-outlet-->
        </body>
    </html>

    is the server-side rendering entry location. Be careful not to add spaces before and after it for the sake of appearance.

    Installationvuex

    npm install -S vuex

    Create vuexFactory function

    import Vue from &#39;vue&#39;
    import Vuex from &#39;vuex&#39;
    Vue.use(Vuex)
    export function createStore () {
        return new Vuex.Store({
            state: {
                count:108
            },
            mutations: {
                add(state){
                    state.count += 1;
                }
            }
        })
    }

    Mount in main.js filestore

    import { createStore } from &#39;./store&#39;
    export function createApp (context) {
        // 创建实例
        const store = createStore()
        const app = new Vue({
            store, // 挂载
            render: h => h(App)
        })
        return { app, router, store }
    }

    Server-side rendering is a "snapshot" of the application. If the application relies on some asynchronous data, then the data needs to be prefetched and parsed before starting rendering

    InstorePerform one-step data acquisition

    export function createStore() {
        return new Vuex.Store({
            mutations: {
                // 加⼀个初始化
                init(state, count) {
                    state.count = count;
                },
            },
            actions: {
                // 加⼀个异步请求count的action
                getCount({ commit }) {
                    return new Promise(resolve => {
                        setTimeout(() => {
                            commit("init", Math.random() * 100);
                            resolve();
                        }, 1000);
                    });
                },
            },
        });
    }

    Data prefetch logic in the component

    export default {
        asyncData({ store, route }) { // 约定预取逻辑编写在预取钩⼦asyncData中
            // 触发 action 后,返回 Promise 以便确定请求结果
            return store.dispatch("getCount");
        }
    };

    Server-side data prefetch, entry-server.js

    import { createApp } from "./app";
    export default context => {
        return new Promise((resolve, reject) => {
            // 拿出store和router实例
            const { app, router, store } = createApp(context);
            router.push(context.url);
            router.onReady(() => {
                // 获取匹配的路由组件数组
                const matchedComponents = router.getMatchedComponents();
    
                // 若⽆匹配则抛出异常
                if (!matchedComponents.length) {
                    return reject({ code: 404 });
                }
    
                // 对所有匹配的路由组件调⽤可能存在的`asyncData()`
                Promise.all(
                    matchedComponents.map(Component => {
                        if (Component.asyncData) {
                            return Component.asyncData({
                                store,
                                route: router.currentRoute,
                            });
                        }
                    }),
                )
                    .then(() => {
                    // 所有预取钩⼦ resolve 后,
                    // store 已经填充⼊渲染应⽤所需状态
                    // 将状态附加到上下⽂,且 `template` 选项⽤于 renderer 时,
                    // 状态将⾃动序列化为 `window.__INITIAL_STATE__`,并注⼊ HTML
                    context.state = store.state;
    
                    resolve(app);
                })
                    .catch(reject);
            }, reject);
        });
    };

    Before the client is mounted to the application, store should obtain the status, entry-client.js

    // 导出store
    const { app, router, store } = createApp();
    // 当使⽤ template 时,context.state 将作为 window.__INITIAL_STATE__ 状态⾃动嵌⼊到最终的 HTML 
    // 在客户端挂载到应⽤程序之前,store 就应该获取到状态:
    if (window.__INITIAL_STATE__) {
        store.replaceState(window.__INITIAL_STATE__);
    }

    Client data prefetching Processing, main.js

    Vue.mixin({
        beforeMount() {
            const { asyncData } = this.$options;
            if (asyncData) {
                // 将获取数据操作分配给 promise
                // 以便在组件中,我们可以在数据准备就绪后
                // 通过运⾏ `this.dataPromise.then(...)` 来执⾏其他任务
                this.dataPromise = asyncData({
                    store: this.$store,
                    route: this.$route,
                });
            }
        },
    });

    Modify the server startup file

    // 获取⽂件路径
    const resolve = dir => require(&#39;path&#39;).resolve(__dirname, dir)
    // 第 1 步:开放dist/client⽬录,关闭默认下载index⻚的选项,不然到不了后⾯路由
    app.use(express.static(resolve(&#39;../dist/client&#39;), {index: false}))
    // 第 2 步:获得⼀个createBundleRenderer
    const { createBundleRenderer } = require("vue-server-renderer");
    // 第 3 步:服务端打包⽂件地址
    const bundle = resolve("../dist/server/vue-ssr-server-bundle.json");
    // 第 4 步:创建渲染器
    const renderer = createBundleRenderer(bundle, {
        runInNewContext: false, // https://ssr.vuejs.org/zh/api/#runinnewcontext
        template: require(&#39;fs&#39;).readFileSync(resolve("../public/index.html"), "utf8"), // 宿主⽂件
        clientManifest: require(resolve("../dist/client/vue-ssr-clientmanifest.json")) // 客户端清单
    });
    app.get(&#39;*&#39;, async (req,res)=>{
        // 设置url和title两个重要参数
        const context = {
            title:&#39;ssr test&#39;,
            url:req.url
        }
        const html = await renderer.renderToString(context);
        res.send(html)
    })

    Summary

    • UsessrThere is no singleton mode. Each user request will create a new vue instance

    • implementationssrrequired Realize server-side first screen rendering and client activation

    • Server-side asynchronous data acquisitionasyncData can be divided into first screen asynchronous acquisition and switching component acquisition

      • The first screen obtains data asynchronously, which should have been completed during server-side pre-rendering
      • The switching component is mixed in through mixin, and the data acquisition is completed through the beforeMount hook

    (Learning video sharing: vuejs tutorial, web front-end)

The above is the detailed content of What is SSR? How to implement SSR server-side rendering in vue?. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:掘金社区. If there is any infringement, please contact admin@php.cn delete
Vue常见面试题汇总(附答案解析)Vue常见面试题汇总(附答案解析)Apr 08, 2021 pm 07:54 PM

本篇文章给大家分享一些Vue面试题(附答案解析)。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

5 款适合国内使用的 Vue 移动端 UI 组件库5 款适合国内使用的 Vue 移动端 UI 组件库May 05, 2022 pm 09:11 PM

本篇文章给大家分享5 款适合国内使用的 Vue 移动端 UI 组件库,希望对大家有所帮助!

一文探究Angular中的服务端渲染(SSR)一文探究Angular中的服务端渲染(SSR)Dec 27, 2022 pm 07:24 PM

你知道 Angular Universal 吗?可以帮助网站提供更好的 SEO 支持哦!

如何覆盖组件库样式?React和Vue项目的解决方法浅析如何覆盖组件库样式?React和Vue项目的解决方法浅析May 16, 2022 am 11:15 AM

如何覆盖组件库样式?下面本篇文章给大家介绍一下React和Vue项目中优雅地覆盖组件库样式的方法,希望对大家有所帮助!

聊聊vue指令中的修饰符,常用事件修饰符总结聊聊vue指令中的修饰符,常用事件修饰符总结May 09, 2022 am 11:07 AM

本篇文章带大家聊聊vue指令中的修饰符,对比一下vue中的指令修饰符和dom事件中的event对象,介绍一下常用的事件修饰符,希望对大家有所帮助!

Vue 3中的SSR技术应用实践,提升应用的SEO效果Vue 3中的SSR技术应用实践,提升应用的SEO效果Sep 08, 2023 pm 12:15 PM

Vue3中的SSR技术应用实践,提升应用的SEO效果随着前端开发的快速发展,SPA(单页面应用)已经成为了主流。SPA的好处不言而喻,可以提供流畅的用户体验,但却在SEO(搜索引擎优化)方面有一些挑战。由于SPA在前端渲染阶段只返回一个HTML模板,大部分内容是通过JavaScript动态加载的,导致搜索引擎在抓取、索引和排名方面的困难。为了解决这个问题,

通过9个Vue3 组件库,看看聊前端的流行趋势!通过9个Vue3 组件库,看看聊前端的流行趋势!May 07, 2022 am 11:31 AM

本篇文章给大家分享9个开源的 Vue3 组件库,通过它们聊聊发现的前端的流行趋势,希望对大家有所帮助!

react与vue的虚拟dom有什么区别react与vue的虚拟dom有什么区别Apr 22, 2022 am 11:11 AM

react与vue的虚拟dom没有区别;react和vue的虚拟dom都是用js对象来模拟真实DOM,用虚拟DOM的diff来最小化更新真实DOM,可以减小不必要的性能损耗,按颗粒度分为不同的类型比较同层级dom节点,进行增、删、移的操作。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!