詳解Vue SSR服務(wù)端渲染

Vue SSR介紹

SSR Github Demo

什么是服務(wù)器端渲染霹陡?

Vue.js 是構(gòu)建客戶端應(yīng)用程序的框架奄喂。默認情況下,可以在瀏覽器中輸出 Vue 組件媒怯,進行生成 DOM 和操作 DOM推正。然而觅赊,也可以將同一個組件渲染為服務(wù)器端的 HTML 字符串龙助,將它們直接發(fā)送到瀏覽器,最后將這些靜態(tài)標記"激活"為客戶端上完全可交互的應(yīng)用程序康震。

為什么使用服務(wù)器端渲染 (SSR)燎含?

與傳統(tǒng) SPA (單頁應(yīng)用程序 (Single-Page Application)) 相比,服務(wù)器端渲染 (SSR) 的優(yōu)勢主要在于:

更好的 SEO腿短,由于搜索引擎爬蟲抓取工具可以直接查看完全渲染的頁面屏箍。
更快的內(nèi)容到達時間 (time-to-content),特別是對于緩慢的網(wǎng)絡(luò)情況或運行緩慢的設(shè)備橘忱。無需等待所有的 JavaScript 都完成下載并執(zhí)行赴魁,才顯示服務(wù)器渲染的標記,所以你的用戶將會更快速地看到完整渲染的頁面钝诚。

SSR渲染過程

image.png

我們可以看到擂啥,左側(cè)Source部分就是我們所編寫的源代碼编整,所有代碼有一個公共入口呕缭,就是app.js,緊接著就是服務(wù)端的入口
(entry-server.js)和客戶端的入口(entry-client.js)敢课。當完成所有源代碼的編寫之后,我們通過webpack的構(gòu)建,打包出兩個bundle,分別是server bundle和client bundle瘪弓;當用戶進行頁面訪問的時候,先是經(jīng)過服務(wù)端的入口盔腔,將vue組建組裝為html字符串杠茬,并混入客戶端所訪問的html模板中,最終就完成了整個ssr渲染的過程弛随。

Nuxt框架

Nuxt 是一個基于 Vue 生態(tài)的更高層的框架,為開發(fā)服務(wù)端渲染的 Vue 應(yīng)用提供了極其便利的開發(fā)體驗宁赤。更酷的是舀透,你甚至可以用它來做為靜態(tài)站生成器。

nuxt官網(wǎng)介紹

安裝

// init過程中根據(jù)提示安裝用到的插件燈
npm init nuxt-app <project-name>

cd <project-name>
npm run dev

配置

nuxt.config.js

const path = require('path')
export default {
  // 允許你在`Javascript`和`Css`中使用別名訪問自定義目錄
  alias: {
    '~~': `<rootDir>`,
    '@@': `<rootDir>`,
    '~': `<srcDir>`,
    '@': `<srcDir>`,
    'assets': `<srcDir>/assets`, // (unless you have set a custom `dir.assets`)
    'static': `<srcDir>/static`, // (unless you have set a custom `dir.static`)
    'style': path.resolve(__dirname, './assets/style')
  },

  // 定義應(yīng)用程序的工作區(qū)目錄决左,默認值process.cwd()
  rootDir: '',

  // 定義應(yīng)用程序的source目錄愕够,默認值同rootDir
  srcDir: '',

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

  // npm run generate時執(zhí)行,構(gòu)建部署靜態(tài)應(yīng)用程序
  generate: {
    // 目錄名
    dir: 'dist'
  },

  // true啟動服務(wù)器端渲染佛猛,false只啟動客戶端渲染
  ssr: true,

  // headers設(shè)置惑芭,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文件到應(yīng)用程序中继找,Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    '@/plugins/antd-ui',
    '@/plugins/veui'
  ],

  // 自動掃描和導(dǎo)入組件遂跟,無需在使用時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相關(guān)配置
    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
      }
    },
    // 手動擴展客戶端和服務(wù)端的webpack配置
    extend(config, context){
        //添加loader規(guī)則
          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幻锁,服務(wù)端渲染

服務(wù)端渲染時,可以看到入口返回的Preview就是在服務(wù)端生成好的頁面边臼,這種方式更利于SEO和快速展示頁面哄尔。


image.png

2. ssr: false,客戶端渲染

客戶端渲染時柠并,可以看到入口返回的Preview是一個空白頁面岭接,頁面的Dom是由提取的其他js在瀏覽器端動態(tài)生成的。


image.png

3. BundleRenderer自動內(nèi)聯(lián)關(guān)鍵CSS(critical css)

關(guān)于critical css的介紹臼予,可以看另一篇文章:https://juejin.cn/post/6946475178188603429/
pages/index.vue為首屏渲染頁面

<template>
    <div class="index">首頁</div>
</template>
<style>
.index {
    color: red;
}
</style>

新建pages/test.vue頁面鸣戴,驗證SSR是否會自動注入關(guān)鍵css(critical css

<template>
    <div class="test">測試</div>
</template>
<style>
.test {
    color: red;
}
</style>
  • index.vue中引入test.vue,服務(wù)啟動后瘟栖,test.vue樣式也以style形式內(nèi)嵌在頁面中
    image.png
  • 不在index.vue中引入test.vue葵擎,服務(wù)啟動后,test.vue樣式則沒有內(nèi)嵌在首屏渲染頁面中
    image.png

    只有在訪問test路由時才顯示test.vue相關(guān)樣式
    image.png

總結(jié):SSR服務(wù)端會自動注入首屏渲染關(guān)鍵css半哟,無需引入其他插件酬滤。

4. extract提取css

啟用extract提取css后签餐,樣式被提取到單獨的css文件中,以外鏈的形式引入盯串。

image.png

以上就是Vue SSR nuxt框架相關(guān)的整理氯檐,每天都有學不完的新知識,加油L迥蟆冠摄!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市几缭,隨后出現(xiàn)的幾起案子河泳,更是在濱河造成了極大的恐慌,老刑警劉巖年栓,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拆挥,死亡現(xiàn)場離奇詭異,居然都是意外死亡某抓,警方通過查閱死者的電腦和手機纸兔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來否副,“玉大人汉矿,你說我怎么就攤上這事”纲鳎” “怎么了洲拇?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長痹届。 經(jīng)常有香客問我呻待,道長,這世上最難降的妖魔是什么队腐? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任蚕捉,我火速辦了婚禮,結(jié)果婚禮上柴淘,老公的妹妹穿的比我還像新娘迫淹。我一直安慰自己,他們只是感情好为严,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布敛熬。 她就那樣靜靜地躺著,像睡著了一般第股。 火紅的嫁衣襯著肌膚如雪应民。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音诲锹,去河邊找鬼繁仁。 笑死,一個胖子當著我的面吹牛归园,可吹牛的內(nèi)容都是我干的黄虱。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼庸诱,長吁一口氣:“原來是場噩夢啊……” “哼捻浦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起桥爽,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤朱灿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后聚谁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體母剥,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年形导,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片习霹。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡朵耕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淋叶,到底是詐尸還是另有隱情阎曹,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布煞檩,位于F島的核電站处嫌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏斟湃。R本人自食惡果不足惜熏迹,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凝赛。 院中可真熱鬧注暗,春花似錦、人聲如沸墓猎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毙沾。三九已至骗卜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寇仓。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工举户, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人焚刺。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓敛摘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乳愉。 傳聞我的和親對象是個殘疾皇子兄淫,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容