單頁面應用在如今的前端頁面開發是愈來愈常見了。
它的好處不少,壞處也很明顯:就是首屏加載每每很慢,呈現一片空白的頁面,這給用戶的體驗感是不好的。
可資源的加載咱們除了儘可能地優化,也沒有其餘很好的辦法了。爲了解決這個體驗感的問題,骨架屏應運而生。
複製代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>skeleton-plugin</title>
<style></style>
</head>
<body>
<div id="root"></div>
</body>
</html>
複製代碼
單頁面應用其實就是一個html文件,html結構裏面有一個div#root,當js加載完畢而且執行完成後,id爲root的div會被整個替換掉。因此由此咱們能夠想到,咱們在div#root裏面寫一些動畫之類的html結構,在js沒有加載完成的時候,讓用戶看到的不是一片空白,而是預先寫好的骨架頁面。這樣的體驗感是否是會好一點呢。html
首先得構建一個簡單的webpack項目(這個過程不詳細說了)。在根目錄下新建一個skeleton-plugin.js文件。因爲咱們須要在每次打包的時候都從新生成新的骨架屏的index.html文件,因此這裏須要用到html-webpack-plugin插件。咱們在skeleton-plugin.js插件注入html-webpack-plugin插件的監聽器,在html-webpack-plugin插件生成index.html以前作骨架屏代碼的插入。前端
在此以前。咱們須要瞭解一下webpack得plugin編寫知識。下圖是截於官方的一段話:(www.webpackjs.com/contribute/… webpack
由此能夠知道,咱們的骨架屏插件要有一個apply的方法,在安裝插件時,會被webpack compiler 調用一次。 該apply方法傳入compiler參數,該參數暴露了webpack生命週期鉤子函數供開發者使用,咱們可使用它來訪問 webpack 的主環境。使用方法爲:compiler.hooks.鉤子函數名稱.tap(...)。web
//skeleton-plugin.js
//引入html-webpack-plugin插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
//建立一個SkeletonPlugin類
class SkeletonPlugin {
apply (compiler) {
//咱們這裏監聽compilation鉤子函數,目的是編譯建立以後,執行咱們的SkeletonPlugin插件的主要代碼
compiler.hooks.compilation.tap('SkeletonPlugin', (compilation) => {
//在html-webpack-plugin插件生成資源到output目錄以前,咱們完成對骨架屏代碼的插入
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
'SkeletonPlugin',
(htmlData, cb) => {
//咱們在這個回調中作骨架屏代碼的插入
//htmlData.html是html-webpack-plugin插件的template模板解析後的字符串
//在輸出index.html以前,咱們將template模板裏的<div id="root"></div>替換成骨架屏代碼。
htmlData.html = htmlData.html.replace(
'<div id="root"></div>',
`<div id="root">
<div style="background-color:red;height:300px;display:none;" id="default" >
我是骨架屏頁面
</div>
</div>`);
//最後執行cb回調,告訴webpack,咱們的插件已經操做完成,讓它繼續執行其餘的操做
cb(null, htmlData)
}
)
});
}
}
//導出SkeletonPlugin插件
module.exports = SkeletonPlugin;
複製代碼
最後在webpack的配置文件webpack.config.js裏寫上如下代碼:app
plugins: [
new HtmlWebpackPlugin({
//index.html模板位置,上面代碼中出現的htmlData.html就是這個模板解析後的內容。
template: './public/index.html',
inject: 'body',
}),
new SkeletonPlugin(),
]
複製代碼
當webpack打包成功後,dist文件夾下的index.html將變成下圖所示: 函數
到這裏簡單的骨架屏插件就完成了。但這個插件只會在首次加載頁面的時候有骨架屏效果。對於其餘頁面是沒有效果的。post
下篇文件將介紹《多頁面的骨架屏插件》的編寫思路。優化
(若有錯誤的內容請你們多多包涵,謝謝)動畫