自從前端三大框架React、Vue、Angular面世以來,前端開發逐漸趨向規範化、統一化,大多數時候新建前端項目,首先想到使用的技術必定是三大框架之一,框架給前端開發帶來了極大的便利和規範,可是因爲這三大框架都是JS驅動,在JS沒有解析加載完成以前頁面沒法展現,會處於長時間的白屏,帶來了必定的用戶體驗問題,接下來本篇文章會介紹本人最近在白屏優化時遇到的一些問題和思考javascript
想到白屏問題,首先想到的解決方案通常都是服務端渲染,在服務端將渲染邏輯處理好,而後將處理好的HTML直接返回給前端展現,這樣就能夠解決白屏的問題,也能夠解決seo的問題,由於不須要動態獲取數據了,可是,這和我早期的寫後端時的開發模式很像,前端和後端關聯在了一塊兒,不利於維護,同時,對於前端工程師來講,要求變高來,須要瞭解必定的後端知識,雖然有相似Nuxt.js這類的SSR框架幫咱們簡化了服務端的部分,可是在要作定製或是解決bug時仍是沒法避免要對服務端部分進行調試、維護,成本頗高,還有須要考慮的服務端渲染會增長服務器壓力,要處理併發、運行速度問題等等html
這個方案是相對簡單直接的一個解決辦法,嘗試成本也比較低,這裏介紹如何用prerender-spa-plugin作預渲染,這樣就能夠在瀏覽器進行渲染,而不須要將Vue或者React代碼部署到服務器上,以vue-cli3的官方demo爲例作配置,看具體的配置文件:前端
const path = require('path') const PrerenderSPAPlugin = require('prerender-spa-plugin') const Renderer = PrerenderSPAPlugin.PuppeteerRenderer module.exports = { configureWebpack: config => { let plugins = [] plugins.push(new PrerenderSPAPlugin({ staticDir: path.resolve(__dirname, 'dist'), routes: ['/', '/about'], minify: { collapseBooleanAttributes: true, collapseWhitespace: true, decodeEntities: true, keepClosingSlash: true, sortAttributes: true }, renderer: new Renderer({ renderAfterDocumentEvent: 'custom-render-trigger' }) })) config.plugins = [ ...config.plugins, ...plugins ] } }
上面代碼是經常使用prerender-spa-plugin的配置,staticDir預渲染輸出的文件地址,routes要作預渲染的路由,minify壓縮相關的配置,renderer渲染引擎相關的配置,能夠傳入自定以的渲染引擎或者直接使用默認的PuppeteerRenderer,renderAfterDocumentEvent是渲染引擎配置中的一個屬性,指當某個事件觸發時才執行預渲染,這裏 有關於渲染引擎的完整屬性介紹,這很重要,尤爲是對一些特定場景的下的需求,固然簡單場景下徹底能夠不配置renderer渲染引擎選項,直接用默認選項。
接下來執行編譯,看看會發生什麼?
dist目錄下會生成路由對應的文件夾,打開index.htmlvue
<div id="app"> <div id="nav"> <a href="/" class="router-link-exact-active router-link-active">Home</a> | <a href="/about" class="">About</a> </div> <div class="home"> <img alt="Vue logo" src="/img/logo.82b9c7a5.png" /> <div class="hello" data-v-7b2de9b7=""> <h1 data-v-7b2de9b7="">Welcome to Your Vue.js App</h1> <p data-v-7b2de9b7="">For a guide and recipes on how to configure / customize this project,<br data-v-7b2de9b7="" />check out the <a href="https://cli.vuejs.org" data-v-7b2de9b7="" rel="noopener" target="_blank">vue-cli documentation</a>.</p> <h3 data-v-7b2de9b7="">Installed CLI Plugins</h3> <ul data-v-7b2de9b7=""> <li data-v-7b2de9b7=""><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" data-v-7b2de9b7="" rel="noopener" target="_blank">babel</a></li> <li data-v-7b2de9b7=""><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" data-v-7b2de9b7="" rel="noopener" target="_blank">eslint</a></li> <li data-v-7b2de9b7=""><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-jest" data-v-7b2de9b7="" rel="noopener" target="_blank">unit-jest</a></li> </ul> <h3 data-v-7b2de9b7="">Essential Links</h3> <ul data-v-7b2de9b7=""> <li data-v-7b2de9b7=""><a href="https://vuejs.org" data-v-7b2de9b7="" rel="noopener" target="_blank">Core Docs</a></li> <li data-v-7b2de9b7=""><a href="https://forum.vuejs.org" data-v-7b2de9b7="" rel="noopener" target="_blank">Forum</a></li> <li data-v-7b2de9b7=""><a href="https://chat.vuejs.org" data-v-7b2de9b7="" rel="noopener" target="_blank">Community Chat</a></li> <li data-v-7b2de9b7=""><a href="https://twitter.com/vuejs" data-v-7b2de9b7="" rel="noopener" target="_blank">Twitter</a></li> <li data-v-7b2de9b7=""><a href="https://news.vuejs.org" data-v-7b2de9b7="" rel="noopener" target="_blank">News</a></li> </ul> <h3 data-v-7b2de9b7="">Ecosystem</h3> <ul data-v-7b2de9b7=""> <