国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解如何在webpack中做預渲染降低首屏空白時間

2019-11-19 13:11:14
字體:
來源:轉載
供稿:網友

一、瀏覽器渲染過程

1、用戶打開頁面,空白屏,等待html的返回

2、html下載完畢,開始解析html,初始渲染

3、下載css、js等資源,執行js渲染虛擬DOM

4、發起請求、獲取數據,渲染內容

下面我們主要是討論一下如何通過預渲染的方式降低空白屏的時間

縮小首屏載時間是一個重要的優化項,總結來主要有以下幾種方式:

1、盡可能的縮小webpack或者其他打包工具生成的包的大小
2、使用服務端渲染的方式
3、使用預渲染的方式
4、使用gzip減小網絡傳輸的流量大小
5、按照頁面或者組件分塊懶加載

二、傳統頁面開發

在React、Vue這種數據驅動的框架還沒盛行的時候,一般我們都是直接在html上寫dom結構的,要不就是直接服務端直出,所以我們在下載完html頁面后,空白屏的時間是非常短的,因為dom是在html中的,并不是像現在以虛擬dom的方式寫在js中,所以,我們不需要等待js下載完畢后才開始渲染頁面,而是html下載完畢后直接渲染出dom結構。

如今我們運用Vue等框架進行開發的時候,一般在html結構都是下面這樣的

<!DOCTYPE html><html lang="en">  <head>   <meta charset="UTF-8">   <title>title</title>  </head>  <body>   <div id="app"></div>   <script src="/bound.js"></script>  </body></html>

在js資源沒有下載完畢的情況下,頁面一直都是處于空白的頁面,一直要等到虛擬dom插入到id為app的div中,這時候白屏才消失開始展現頁面,反正就是讓人感覺特別慢就是了!

既然知道了白屏是怎么產生的,那我們下面就來嘗試一下如何在webpack中集成預渲染的功能,來降低白屏的時間。

三、在webpack中集成預渲染功能

github:webpack中如何集成預渲染功能

這里我們嘗試將一個使用vue編寫的loading組件在webpack編譯過程中將虛擬dom預渲染到html中,下面是loading組件的內容

<template> <div class="loading-img"></div></template><script>export default {}</script><style>.loading-img { position: fixed; top: 0; bottom: 0; right: 0; left: 0; margin: auto; display: inline-block; width: 60px; height: 60px; background: url(__inline__) no-repeat center center; background-size: contain;}</style>

上面__inline__是用于后面圖片插入的標記,這里先不用管,其實這個組件就是一個簡單的loading組件

最終我們想要的效果是,將這個vue組件的虛擬dom預渲染到html文件當中

<html> <head>  <meta charset="UTF-8">  <title>test</title>  <!-- pre-render-loading抽出的css -->  <style>   .loading-img {    position: fixed;    top: 0;    bottom: 0;    right: 0;    left: 0;    margin: auto;    display: inline-block;    width: 60px;    height: 60px;    <!-- 這里我們會將loading圖編譯成base64直接插入到html中 -->    background: url(data:image/gif;base64,.....) no-repeat center center;    background-size: contain;   }  </style>  ... </head> <body>  <div id="app">   <!-- loading base64圖 -->   <div class="loading-img"></div>  </div>    ... </body></html>

向上面那樣,在html頁面返回時編譯成base64內嵌到html中的loading就會馬上顯示,大大降低了白屏的時間,基本可以達到秒開頁面,這時候我們不需要等待js資源的下載以及虛擬dom的插入,當然這里loading中的內容可以是任何你想要預先渲染的模板

因為這里我們的loading組件是用vue寫的,所以我們試著看看如何來做預渲染并集成到webpack中(可以合著倉庫的代碼一起看,代碼挺簡單的,只是一個demo)

這里我們先把vue單文件中的html與css單獨抽離出來

// render-loading.jslet vueAssets = nulllet vueTplPath = resolvePath('./src/loading/pre-render-loading.vue')const extractAssetsInVueTpl = (vueTplPath) => { let vueTpl = clearEnter(fs.readFileSync(vueTplPath).toString()) let html = /<template>(.*)<//template>/g.exec(vueTpl)[1] let css = /<style>(.*)<//style>/g.exec(vueTpl)[1] return {  html,  css }}vueAssets = extractAssetsInVueTpl(vueTplPath)

這里我們通過正則的方式將template與style標簽中匹配到的內容單獨抽離了出來,接下來我們需要將gif圖轉成base64并插入到我們抽出的css代碼當中

let gifPath = resolvePath('./src/loading/imgs/loading.gif')const transGifToCSSFile = (imgPath) => { let ext = path.extname(imgPath).slice(1) let preStr = `data:image/${ext};base64,` // 根據尾綴自動拼接對應base64前綴 let bitDate = fs.readFileSync(imgPath) let base64Str = bitDate.toString('base64') let dataURL = preStr + base64Str return dataURL}let dataURL = transGifToCSSFile(gifPath)

上面我們通過extractAssetsInVueTpl函數抽離出了css,這里我們通過一個簡單的函數將占位符替換成base64圖片

const injectDataURLToCSS = (cssStr, dataURL) => { return cssStr.replace(/__inline__/, dataURL)}let cssStr = injectDataURLToCSS(vueAssets.css, dataURL)

下面我們就導出loading配置,包含了html模板與style樣式字符串

loading.html = vueAssets.htmlloading.css = '<style>' + cssStr + '</style>'module.exports = loading

簡單寫一個webpack入口配置,這里我們需要使用html-webpack-plugin將loading插入到html中(這里用到了插件的自定義模板)

const HtmlWebpackPlugin = require('html-webpack-plugin')const loading = require('./render-loading')module.exports = { entry: './src/index.js', output: {  path: __dirname + '/dist',  filename: 'index_bundle.js' }, plugins: [  new HtmlWebpackPlugin({   template: './src/index.html',   loading: loading  }) ]}

在html中我們通過模板語法將loading的內容插入到html模板中對應的位置了

<html> <head>  <meta charset="UTF-8">  <title>test</title>  ...  <%= htmlWebpackPlugin.options.loading.css %> </head> <body>  <div id="app">   <!-- loading base64圖 -->   <%= htmlWebpackPlugin.options.loading.html %>  </div>    ... </body></html>

四、總結

這里只是寫一個demo介紹一下原理,更復雜的可以使用vue-server-render來做同構直出或者使用一些像handlebars的模板引擎來生成模板,其實就是將服務端的渲染工作放到了編譯的過程當中。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 兴山县| 西乡县| 文登市| 松滋市| 望城县| 平塘县| 古交市| 新田县| 仙桃市| 万年县| 正镶白旗| 富顺县| 威信县| 景宁| 乌拉特中旗| 论坛| 青龙| 融水| 禄劝| 石泉县| 日喀则市| 阿拉尔市| 工布江达县| 筠连县| 南乐县| 德安县| 达拉特旗| 东光县| 中江县| 收藏| 高密市| 万荣县| 随州市| 普格县| 石台县| 黔江区| 灵山县| 浪卡子县| 上蔡县| 曲阜市| 正蓝旗|