骨架屏(page-skeleton-webpack-plugin)初探

作者:小土豆biubiubiu

博客园://www.cnblogs.com/HouJiao/

掘金://juejin.im/user/2436173500265335

微信公众号:土豆妈的碎碎念(扫码关注,一起吸猫,一起听故事,一起学习前端技术)

作者文章的内容均来源于自己的实践,如果觉得有帮助到你的话,可以点赞❤️给个鼓励或留下宝贵意见

前言

最近频频看到了骨架屏这个词,其实在这之前鲜少听过骨架屏这个词。只是平时在浏览网站时,会经常看到某个页面在尚未获取到真正数据时展示的一些占位图形

那实际上这个就是前面所描述的骨架屏,即在页面数据尚未加载前先给用户展示出页面的大致结构,在获取到数据以后在具体展示页面的内容。那骨架屏相较于传统的那种loading,在很大程度上提升了用户体验

所以今天这篇文章就是一篇骨架屏的初探与实践,内容本身非常简单,但是其中还是会有一些细节的东西需要注意,否则在实践实总是无法出现正常的结果。

page-skeleton-webpack-plugin

page-skeleton-webpack-plugin饿了么团队开发的一款webpack插件,这个插件可以根据不同的页面生成不同的骨架屏页面。

那接下来就在项目中实践一下page-skeleton-webpack-plugin

项目简介

本次的项目是使用vue-cli2生成的一个项目,项目中组件的内容也非常的简单,可以 戳这里 获取项目代码。

page-skeleton-webpack-plugin安装

安装page-skeleton也非常简单,直接执行命令:npm install --save-dev page-skeleton-webpack-plugin即可。

注意文档中有明确说明还要安装html-webpack-plugin,本项目已经安装了html-webpack-plugin。如果你的项目中没有安装html-webpack-plugin,可以执行npm install --save-dev html-webpack-plugin进行安装。

接下来就需要开始实践了。

webpack配置

首先是需要我们在开发环境中生成骨架屏的代码。

所以第一步是在开发环境中配置SkeletonPlugin

// 代码位置:/skeleton-screen-demo/build/webpack.dev.conf.js

// 步骤1:引入骨架屏模块
const { SkeletonPlugin } = require('page-skeleton-webpack-plugin')

// 省略代码...

plugins: [

    // 省略其他插件的配置代码...
    
    // 步骤2:在插件中进行配置
    new SkeletonPlugin({
      pathname: path.resolve(__dirname, '../shell'), // the path to store shell file
      staticDir: path.resolve(__dirname, '../dist'), // the same as the `output.path`
      routes: ['/', '/home'], // Which routes you want to generate skeleton screen
  })
]

SkeletonPlugin插件必选的三个配置项分别为:pathnamestaticDirroutes,这三个配置项的作用分别如下:

配置项 数据类型 作用
pathname String 开发环境中点击保存按钮生成的骨架屏代码的保存路径
staticDir String 打包时生成的骨架屏的静态资源文件(官方文档指导要和webpack打包输出目录一致)
routes Array 需要生成骨架屏的路由(和项目中路由配置path一致)

运行项目

开发环境中的webpack配置完成以后,使用npm run dev运行项目。
不过不幸的是出现了错误😤 😤 😤。

跟随着错误信息,去查看了/skeleton-screen-demo/node_modules/page-skeleton-webpack-plugin/src/util/index.js文件,发现该文件中确实有引入一个名为webpack-log的模块,所以解决办法就是安装webpack-log: npm install webpack-log --save-dev

安装成功后重新运行项目。

可以发现项目名已经启动成功,页面也能正常访问。

此时如果在控制台能看到下面这样一个打印信息就证明page-skeleton-webpack-plugin配置成功。

生成骨架屏文件

首先在控制台输入toggleBar,然后点击回车。

可以看到页面最上方出现了一个横条点击这个横条开始生成骨架屏的预览页面

生成的过程需要等待十几秒

可以看到我们页面的骨架屏预览效果已经出来了;在预览页面的第三栏,还可以对已经生成的代码进行修改。

接着呢,点击骨架屏预览页面右上角的按钮,就可以将骨架屏代码保存在webpack中配置的目录下。

点击保存按钮后,可以看到本地已经生成了对应的骨架屏代码文件

生产环境中的骨架屏配置

上面的一系列操作都是在开发环境中进行实践的,目的是为了生成骨架屏的代码。那现在就需要将骨架屏应用到生产环境中。

webpack配置

首先,我们需要在生产环境中写入骨架屏的配置。

// 代码位置:/skeleton-screen-demo/build/webpack.pro.conf.js

// 步骤1:引入骨架屏模块
const { SkeletonPlugin } = require('page-skeleton-webpack-plugin')

// 省略代码...

plugins: [

    // 省略其他插件的配置代码...
    
    // 步骤2:在插件中进行配置
    new SkeletonPlugin({
      pathname: path.resolve(__dirname, '../shell'), // the path to store shell file
      staticDir: path.resolve(__dirname, '../dist'), // the same as the `output.path`
      routes: ['/', '/home'], // Which routes you want to generate skeleton screen
  })
]

这个配置和前面在webpack.dev.conf.js中的配置一样。
可以将其直接写在webpack.base.conf.js中,这样可以避免重复写两次配置。

模板文件配置

在项目的跟模板中添加注释<!-- shell -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>骨架屏初探</title>
  </head>
  <body>
    <div id="app">
      <!-- shell -->
    </div>
    <!-- built files will be auto injected -->
  </body>
</html>

👉👉👉这里需要注意👉👉👉

webpack的html-webpack-plugin有一项关于压缩移除注释的配置,手脚架在生成项目的时侯,这个配置项默认设置为true,即移除模板中的注释。但是在骨架屏这里,这个<!-- shell -->注释是必须存在的。因此我们需要将这个压缩移除注释的配置项修改为false,即保留注释,否则在后面的项目打包部署后,骨架屏是不会生效的。

new HtmlWebpackPlugin({
   minify: {
     removeComments: false   // 压缩移除注释的配置项修改为false
},

打包编译项目

接着对项目进行打包编译。

部署项目查看结果

最后一步就是将项目进行部署,本次我用的是nginx部署项目。项目部署成功以后我们打开浏览器就能看到骨架屏的效果。

因为组件内容本身非常简单,加载时间短,所以需要设置一下浏览器调试工具下的NetWork -> Disable cache,即禁用缓存;同时将加载网速设置为3G(或者自定义加载网速)。
这样就能很清楚的看到骨架屏的效果。

多页面骨架屏生成

多页面骨架屏的生成也非常的简单,除了新建组件配置路由之外,还需要对SkeletonPlugin进行配置。

new SkeletonPlugin({
      pathname: path.resolve(__dirname, '../shell'), // the path to store shell file
      staticDir: path.resolve(__dirname, '../dist'), // the same as the `output.path`
      routes: ['/', '/test'], // Which routes you want to generate skeleton screen
})

SkeletonPlugin.routes中添加新的路由,之后在骨架屏的预览界面就可以切换新增的路由,生成新的骨架屏预览界面。

生成之后需要点击保存按钮保存骨架屏代码。

保存之后会在本地生成一个新的骨架屏代码。

之后在进行打包部署即可。

注意注意

这里特别特别注意的是,page-skeleton-webpack-plugin的骨架屏预览界面中有一个Routes按钮用于切换路由生成不同页面的骨架屏预览

可以看到点击切换按钮后显示的这个路由是不带#符号的,而我们在配置路由时是默认的hash模式,所以在浏览器中访问两个组件的完整url为:

//localhost:8080/#/  
//localhost:8080/#/test

那这样的不同导致在新增了test路由以后,我在预览界面切换到了/test路由的时候,预览界面依然生成的是/路由的骨架屏页面。

这个问题出现的原因其实需要追溯到page-skeleton-webpack-plugin的实现,当我们在预览页面切换路由时,page-skeleton-webpack-plugin插件会根据我们选择的路由去获取该路由对应的组件的内容,然后根据组件的内容生成骨架屏页面

由于page-skeleton-webpack-plugin的路由是不带#符号的history模式,而实际项目中的路由模式是hash模式,所以导致SkeletonPlugin匹配不到实际的组件,也就无法正确的生成骨架屏。

那对于这个问题的解决办法也非常的简单,就是将项目的路由设置为history模式。

// 代码位置:/skeleton-screen-demo/src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Test from '@/components/Test'
Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/test',
      name: 'Test',
      component: Test
    }
  ]
})

这个问题在实践的时候确实困扰了我很长时间,新增的页面总是不能出现正常的效果,而且在文档中也并没有提及此事。后来对比了一下官方给的一个sale示例才恍然大悟。

最后我们在来看一下多页面骨架屏的效果。

最后

到这里,这篇骨架屏的初探就完成了,内容非常的简单,但是也有一两个小小的坑需要避过才能完美实现骨架屏的效果。

关于

作者

小土豆biubiubiu

一个努力学习的前端小菜鸟,知识是无限的。坚信只要不停下学习的脚步,总能到达自己期望的地方

同时还是一个喜欢小猫咪的人,家里有一只美短小母猫,名叫土豆

博客园

//www.cnblogs.com/HouJiao/

掘金

//juejin.im/user/2436173500265335

微信公众号

土豆妈的碎碎念

微信公众号的初衷是记录自己和身边的一些故事,同时会不定期更新一些技术文章

欢迎大家扫码关注,一起吸猫,一起听故事,一起学习前端技术

作者寄语

小小总结,欢迎大家指导~