详解Vue SSR服务端渲染

Vue SSR介绍

SSR Github Demo

什么是服务器端渲染?

Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。

为什么使用服务器端渲染 (SSR)?

与传统 SPA (单页应用程序 (Single-Page Application)) 相比,服务器端渲染 (SSR) 的优势主要在于:

更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。
更快的内容到达时间 (time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。无需等待所有的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,所以你的用户将会更快速地看到完整渲染的页面。

SSR渲染过程

image.png

我们可以看到,左侧Source部分就是我们所编写的源代码,所有代码有一个公共入口,就是app.js,紧接着就是服务端的入口
(entry-server.js)和客户端的入口(entry-client.js)。当完成所有源代码的编写之后,我们通过webpack的构建,打包出两个bundle,分别是server bundle和client bundle;当用户进行页面访问的时候,先是经过服务端的入口,将vue组建组装为html字符串,并混入客户端所访问的html模板中,最终就完成了整个ssr渲染的过程。

Nuxt框架

Nuxt 是一个基于 Vue 生态的更高层的框架,为开发服务端渲染的 Vue 应用提供了极其便利的开发体验。更酷的是,你甚至可以用它来做为静态站生成器。

nuxt官网介绍

安装

// init过程中根据提示安装用到的插件灯
npm init nuxt-app 

cd 
npm run dev

配置

nuxt.config.js

const path = require('path')
export default {
  // 允许你在`Javascript`和`Css`中使用别名访问自定义目录
  alias: {
    '~~': ``,
    '@@': ``,
    '~': ``,
    '@': ``,
    'assets': `/assets`, // (unless you have set a custom `dir.assets`)
    'static': `/static`, // (unless you have set a custom `dir.static`)
    'style': path.resolve(__dirname, './assets/style')
  },

  // 定义应用程序的工作区目录,默认值process.cwd()
  rootDir: '',

  // 定义应用程序的source目录,默认值同rootDir
  srcDir: '',

  // server连接配置
  server: {
    port: 3000, // default: 3000
    host: '0.0.0.0', // default: localhost,
    timing: false
  },

  // npm run generate时执行,构建部署静态应用程序
  generate: {
    // 目录名
    dir: 'dist'
  },

  // true启动服务器端渲染,false只启动客户端渲染
  ssr: true,

  // headers设置,Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: 'ssr-demo',
    htmlAttrs: {
      lang: 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  // 全局css,Global CSS: https://go.nuxtjs.dev/config-css
  css: [
    // 'ant-design-vue/dist/antd.css'
    // css后缀可以省略
    'assets/style/common'
  ],

  // 添加plugins目录下的js文件到应用程序中,Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    '@/plugins/antd-ui',
    '@/plugins/veui'
  ],

  // 自动扫描和导入组件,无需在使用时import组件,可直接使用,Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
    // 是否提取css至独立文件中
    // extractCSS: true,
    // babel相关配置
    babel: {
      plugins: [
        'veui',
        ['import', {
          'libraryName': 'ant-design-vue',
          'libraryDirectory': 'es',
          'style': true
            // customStyleName: name => {
            //   return `assets/${name}.css`
            // }
          }
        ] // `style: true` 会加载 less 文件
      ]
    },
    // 可省略的扩展名
    resolve: {
      extensions: ['.js', '.vue', '.json']
    },
    // 需要进行babel编译的包
    transpile: ['veui', 'vue-awesome', 'ant-design-vue'],
    // loader配置
    loaders: {
      vue: {
        extractCSS: true
      },
      less: {
        javascriptEnabled: true
      }
    },
    // 手动扩展客户端和服务端的webpack配置
    extend(config, context){
        //添加loader规则
          config.module.rules.push({
              test: /\.vue$/, //匹配.svg
              include: [path.resolve(__dirname, 'node_modules/veui')], //将存放svg的目录加入到loader处理目录
              use: [{ loader: 'veui-loader', options: {
                modules: [
                  {
                    package: 'veui-theme-blue',
                    fileName: '${module}.less'
                  },
                  {
                    package: 'veui-theme-blue',
                    fileName: '${module}.js',
                    transform: false
                  }
                ]
              }}]
          })
    }
  }
}

Demo示例

1. ssr: true,服务端渲染

服务端渲染时,可以看到入口返回的Preview就是在服务端生成好的页面,这种方式更利于SEO和快速展示页面。


image.png

2. ssr: false,客户端渲染

客户端渲染时,可以看到入口返回的Preview是一个空白页面,页面的Dom是由提取的其他js在浏览器端动态生成的。


image.png

3. BundleRenderer自动内联关键CSS(critical css)

关于critical css的介绍,可以看另一篇文章:https://juejin.cn/post/6946475178188603429/
pages/index.vue为首屏渲染页面



新建pages/test.vue页面,验证SSR是否会自动注入关键css(critical css



  • index.vue中引入test.vue,服务启动后,test.vue样式也以style形式内嵌在页面中
    image.png
  • 不在index.vue中引入test.vue,服务启动后,test.vue样式则没有内嵌在首屏渲染页面中
    image.png

    只有在访问test路由时才显示test.vue相关样式
    image.png

总结:SSR服务端会自动注入首屏渲染关键css,无需引入其他插件。

4. extract提取css

启用extract提取css后,样式被提取到单独的css文件中,以外链的形式引入。

image.png

以上就是Vue SSR nuxt框架相关的整理,每天都有学不完的新知识,加油!!

你可能感兴趣的:(详解Vue SSR服务端渲染)