VUE預渲染 webpack prerender-spa-plugin

預渲染就是在構建階段(npm run build)生成特定路由的html靜態頁面,利用webpack的prerender-spa-plugin 插件。
參考:https://www.npmjs.com/package/prerender-spa-plugin

  1. 安裝 prerender-spa-plugin
    npm install prerender-spa-plugin --save-dev
  2. 配置 vue.config.js
    headless設置爲false的話,構建的時候會彈出瀏覽器窗口,僅在調試時使用,在生成環境中不需要設置爲false。
    server中指定的port是預渲染時的端口。
    預渲染的時候,首先webpack會啓動一個本地環境,然後prerender-spa-plugin插件會依賴puppeteer,也就是谷歌的無頭瀏覽器插件。
    依次爬取routes中設置的頁面,將爬取獲取的內容生成指定的html。
    在這裏插入圖片描述
  3. 使用vue-meta-info組件設置meta和title。
    注意靜態和動態路由設置的方式略有差別。
    參考:https://www.npmjs.com/package/vue-meta-info

那麼經過上面這3步之後,在本地構建時預渲染的頁面就可以正常生成。

接下來就是服務器部署。
在linux上支持prerender-spa-plugin 預渲染,是需要額外手動配置的。

  1. linux服務器編譯報錯
    參考官方解決方案,安裝依賴包。Centos和其他的還不一樣,docker環境也不一樣。
    https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc
  1. nginx配置,加了一個 $uri/,否則預編譯不生效。
    在這裏插入圖片描述

到這爲止,預渲染就基本完成了!

但是仔細觀察,還存在一些問題。

  • 問題1 查看源代碼,發現meta的keywords和description有2個,title有一個爲正常。如果頁面中存在2個meta信息,第一個有效,第二個是無效的。在這裏插入圖片描述
    分析原因: 因爲index.html中已經設置了meta的keywords和description,在vue組件中設置的meta的keywords和description,只會追加,並不會替代。所有就變成2個。
    但是如果刪除掉index.html中設置的meta,就會出現預渲染以外的頁面,沒有title和meta信息,也不合理。
    解決方案: 增加一個模板入口文件index2.html,那麼會有兩個模板文件index.html和index2.html,預編譯indexPath指定使用index2.html,在index2.html中不設置meta和title。正常渲染使用index.html,在index.html中正常設置meta和title。
    這樣預渲染的頁面就會有1個meta,預渲染以外的頁面也可以正常有meta。
    同樣這個也需要nginx設置,如上圖。主頁面請求index2.html,其他頁面請求index.html.
  • 問題2 頁面存在閃屏現象,就是在頁面請求ajax返回數據頁面渲染之前會先加載預渲染的頁面,特別是數據變化大的頁面,比如主頁,過渡效果不自然。
    分析原因: 在ajax請求數據完成之前,頁面顯示的是預渲染頁面,ajax請求完成後會替換掉 <div id="app"></div>中的內容,因此頁面閃屏。
    解決方案: 增加loading效果,loading替換預渲染的內容顯示。預渲染編譯靜態頁面確實會提高加載速度,但是僅限於,比如公司介紹,都是靜態內容的頁面,如果動態內容很多,用戶體驗非常不好。
    注意一點就是預渲染頁面的loading和預渲染以外的loading加的方式會不同。
    這個問題,每個人解決方式可能不同。
    我的實現方式判斷當前port,當port是8001的時候,我會認爲這是預渲染的請求,那麼我會直接加一層Loading。那麼實際上在顯示的時候,就會加載loading然後顯示ajax請求回來渲染的頁面,這樣不會有閃屏。
    預渲染以外的頁面加loading,在index.html和index2.html中加入下面代碼。
    在這裏插入圖片描述
    App.vue的鉤子中,使其隱藏。
    在這裏插入圖片描述

這樣會在刷新頁面的時候,避免白屏時間長,影響用戶體驗,這樣修改之後白屏的時候就會被Loading效果替代。300ms可以根據需求修改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章