一、骨架屏的由来:
单页面应用在现在的前端页面开发是越来越常见了。
它的好处很多,坏处也很明显:就是首屏加载往往很慢,呈现一片空白的页面,这给用户的体验感是很差的。
可资源的加载我们除了尽量地优化,也没有其他很好的办法了。为了解决这个体验感的问题,骨架屏应运而生。
二、骨架屏原理:
<!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没有加载完成的时候,让用户看到的不是一片空白,而是预先写好的骨架页面。这样的体验感是不是会好一点呢。
三、webpack插件的编写:
(1)webpack插件介绍
首先得构建一个简单的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/…
(2)但插件的具体实现
由此可以知道,我们的骨架屏插件要有一个apply的方法,在安装插件时,会被webpack compiler 调用一次。 该apply方法传入compiler参数,该参数暴露了webpack生命周期钩子函数供开发者使用,我们可以使用它来访问 webpack 的主环境。使用方法为:compiler.hooks.钩子函数名称.tap(...)。
//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;
(3)插件的使用
最后在webpack的配置文件webpack.config.js里写上以下代码:
plugins: [
new HtmlWebpackPlugin({
//index.html模板位置,上面代码中出现的htmlData.html就是这个模板解析后的内容。
template: './public/index.html',
inject: 'body',
}),
new SkeletonPlugin(),
]
当webpack打包成功后,dist文件夹下的index.html将变成下图所示:
四、结束语:
到这里简单的骨架屏插件就完成了。但这个插件只会在首次加载页面的时候有骨架屏效果。对于其他页面是没有效果的。
下篇文件将介绍《多页面的骨架屏插件》的编写思路。
(如有错误的内容请大家多多包涵,谢谢)