• vue-ssr技术分析与实践


    demo 

    https://github.com/flzCoder/rich

    一、优劣分析

    优点:

    更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面

    更快的内容到达时间 (time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备

    权衡点:

    开发条件所限(浏览器特定的代码)

    涉及构建设置和部署的更多要求(server端)

    更多的服务器端负载(每一个请求生成一个vue实例;在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源 )

    nuxt.js

    如果你倾向于使用提供了平滑开箱即用体验的更高层次解决方案,你应该去尝试使用 Nuxt.js如果你需要更直接地控制应用程序的结构,Nuxt.js 并不适合这种使用场景。

    二、原理分析:

    1.核心方法

    const { createBundleRenderer } = require('vue-server-renderer')

    2.参数:

    服务器 bundle: vue-ssr-server-bundle.json

    const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')

    客户端构建清单: vue-ssr-client-manifest.json

    const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')

    模板index.template.html

     

    3.集成到服务器渲染

    renderer 现在具有了服务器和客户端的构建信息,因此它可以自动推断和注入资源预加载 / 数据预取指令(preload / prefetch directive),以及 css 链接 / script 标签到所渲染的 HTML。

    app.get('*', (req,res) {

    renderer.renderToString(context, (err, html) => {
       res.send(html)
    })

    })

    4.简单同构应用已实现

    虚拟DOM让服务端渲染vue应用成为可能;

    具体实现依赖 vue-server-renderer包的方法和插件,将vue实例渲染为html;

    Vue 在浏览器端接管由服务端发送的静态 HTML,使其变为由 Vue 管理的动态 DOM 状态。

    三、构建环境搭建:

    架构

    0.目录结构

    1.node应用程序

    express

     

    2.简易模板

     

    3.简易vue应用程序

    为每个请求创建一个新的根 Vue 实例,避免状态单例;暴露一个可以重复执行的工厂函数,为每个请求创建新的应用程序实例:

    vue应用程序通用entry:app.js

     

    4.构建入口文件

    entry-client.js

    const { app } = createApp()

    app.$mount('#app')

    entry-server.js

    5.构建配置

    webpack.client.config.js

    webpack.server.config.js

    target: 'node',

    output.libraryTarget =  'commonjs2';

    6.本地开发&线上打包

    线上打包

    createBundleRenderer 直接调用打包后的文件即可

    本地开发

    index.html

    chokidar监听文件变化,将最新的模板传给createBundleRenderer 

    vue-ssr-client-manifest.json

    使用express中间件webpack-dev-middleware && webpack-hot-middleware/client,在每次打包结束时将最新的vue-ssr-client-manifest.json传给createBundleRenderer 

    vue-ssr-server-bundle.json

    watch监听到文件变化,webpack重新打包,新文件vue-ssr-server-bundle.json传给createBundleRenderer 

    四、路由相关处理

    1.服务器代码使用了一个 * 处理程序,它接受任意 URL。这允许我们将访问的 URL 传递到我们的 Vue 应用程序中,然后对客户端和服务器复用相同的路由配置!

    2.路由配置router.js

    每个请求一个新的 router 实例,所以文件导出一个 createRouter 函数

    应用程序的代码分割或惰性加载,有助于减少浏览器在初始渲染中下载的资源体积,可以极大地改善大体积 bundle 的可交互时间(TTI - time-to-interactive)。

    3.路由逻辑

    entry-server.js

     

    entry-client.js

    挂载 app 之前调用 router.onReady,因为路由器必须要提前解析路由配置中的异步组件,才能正确地调用组件中可能存在的路由钩子。

     

    五、数据预取及状态

    在服务器端渲染(SSR)期间,我们本质上是在渲染我们应用程序的"快照",所以如果应用程序依赖于一些异步数据,那么在开始渲染过程之前,需要先预取和解析好这些数据。

    在客户端,在挂载 (mount) 到客户端应用程序之前,需要获取到与服务器端应用程序完全相同的数据 - 否则,客户端应用程序会因为使用与服务器端应用程序不同的状态,然后导致混合失败。

     

    1.数据预取存储容器 (vuex)

    配置vuex state、action、mutation

    action:获取异步数据

    2.路由组件所需数据通过访问路由,决定了哪些组件需要渲染。约定在该组件放置数据预取逻辑获取所需数据。

    路由组件提供asyncData静态方法,dispatch对应action,获取该路由所需数据存入state.items;

    各路由以路由名字区分 route.name

    3.服务端数据预取 entry-server.js

    通过路由获得与 router.getMatchedComponents() 相匹配的组件,如果组件暴露出 asyncData,我们就调用这个方法。

    然后我们需要将解析完成的状态,附加到渲染上下文

    当使用 template 时,context.state 将作为 window.__INITIAL_STATE__ 状态,自动嵌入到最终的 HTML 中。而在客户端,在挂载到应用程序之前,store 就应该获取到状态:

    4.客户端数据预取 entry-client.js

    在路由导航之前解析数据

     使用 `router.beforeResolve()`,以便确保所有异步组件都 resolve。

     
    对比得出非预渲染的组件,找出两个匹配列表的差异组件然后预取数据。

    当路由组件重用(同一路由,但是 params 或 query 已更改,例如,从 user/1 到 user/2)时,也应该调用 asyncData 函数。我们也可以通过纯客户端 (client-only) 的全局 mixin 来处理这个问题:

     
  • 相关阅读:
    圣诞树
    删除临时表并且插入数据
    sql语句中查询用in的时候,按in的顺序来输出
    xmlhelper and excelhelper
    几个小知识点。
    根据页面上记录数和页面大小获取总页数
    SQL语句的疑问
    katie melua the closest thing to crazy
    something about table
    little things
  • 原文地址:https://www.cnblogs.com/fengluzheweb/p/13570675.html
Copyright © 2020-2023  润新知