vue骨架屏实践

1.背景

近两年来,前、后端分离的架构得到越来越多的认可,越来越多的团队在尝试、推广这种架构。然而在带来便利的同时,也带来了一些弊端,比如首屏渲染时间(FCP)因为首屏需要请求更多内容,比原来多了更多HTTP的往返时间(RTT),这造成了白屏,如果白屏时间过长,用户体验会大打折扣,如果用户网速差,则FCP会更长。

为了优化首屏渲染时间这个指标,减少白屏时间,前端仔们想了很多办法:

  • 加速或减少HTTP请求损耗
  • 延迟加载
  • 减少请求内容的体积
  • 优化用户等待体验

这里要介绍的就是优化用户等待体验的骨架屏,目前市面上用得比较多的是下面这几个插件:

  • vue-server-renderer
  • vue-skeleton-webpack-plugin
  • page-skeleton-webpack-plugin
插件对比评估
插件 GitHub Start 开发难度(是否需手动写样式) 是否基于vue-cli 是否可配置 开源方
vue-server-renderer 13k Yes No No vue-router团队
vue-skeleton-webpack-plugin 0.5k Yes Yes No 个人
page-skeleton-webpack-plugin 1.3k No Yes Yes 饿了么

对比发现,就开发难度、灵活性和插件开源方来看,如果你的项目是基于vue-cli脚手架的,那么饿了么团队的page-skeleton-webpack-plugin是你的最佳选择,如果不是,那么你可以选择vue-router开源的vue-server-renderer.

2.骨架屏(page-skeleton-webpack-plugin)

一张图读懂什么是骨架屏

优势:

  • 支持多种加载动画
  • 针对移动端 web 页面
  • 支持多路由
  • 可定制化,可以通过配置项对骨架块形状颜色进行配置,同时也可以在预览页面直接修改骨架页面源码
  • 几乎可以零配置使用

安装:

npm install --save-dev page-skeleton-webpack-plugin
npm install --save-dev html-webpack-plugin

配置:

第一步:配置插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { SkeletonPlugin } = require('page-skeleton-webpack-plugin')
const path = require('path')
const webpackConfig = {
  entry: 'index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'index.bundle.js'
  },
  plugin: [
    new HtmlWebpackPlugin({
       // Your HtmlWebpackPlugin config
    }),

    new SkeletonPlugin({
      pathname: path.resolve(__dirname, `${customPath}`), // 用来存储 shell 文件的地址
      staticDir: path.resolve(__dirname, './dist'), // 最好和 `output.path` 相同
      routes: ['/', '/search'], // 将需要生成骨架屏的路由添加到数组中
    })
  ]
}
第二步:修改 HTML Webpack Plugin 插件的模板

在你启动 App 的根元素内部添加




  
  Document


  
第三步:界面操作生成、写入骨架页面
  1. 在开发页面中通过 Ctrl|Cmd + enter 呼出插件交互界面,或者在在浏览器的 JavaScript 控制台内输入toggleBar 呼出交互界面。
  2. 点击交互界面中的按钮,进行骨架页面的预览,这一过程可能会花费 20s 左右时间,当插件准备好骨架页面后,会自动通过浏览器打开预览页面,如下图。


    PSG-Screen2.gif

配置

Server Options
Option Type Required Default Description
routes Array Yes None 需要生成带有骨架屏的静态路由
Port String No 8989 The port of Page Skeleton server
minify false or Object No See defaults 插件默认会压缩生成的 shell.html 文件,默认压缩配置参见本部分默认配置。可以传递 html-minifier 的配置参数给 mimify,进行按需压缩。当配置为 false 时,不压缩生成的 shell.html 文件,并且会对 shell.html 文件进行格式化处理。
Skeleton Page Options
Option Type Required Default Description
loading String No spin spin/chiaroscuro/shine
text Object No See defaults 该配置对象可以配置一个 color 字段,用于决定骨架页面中文字块的的颜色,颜色值支持16进制、RGB等。
button Object No See defaults 该配置接受两个字段,color 和 excludes。color 用来确定骨架页面中被视为按钮块的颜色,excludes 接受一个数组,数组中元素是 DOM 选择器,用来选择元素,该数组中的元素将不被视为按钮块。
excludes Array No [] 如果你有不需要进行骨架处理的元素,那么将该元素的 CSS 选择器写入该数组。
remove Array No [] 不需要生成页面骨架,且需要从 DOM 中移除的元素,配置值为移除元素的 CSS 选择器。
Puppeteer Options
Option Type Required Default Description
device String No iPhone 6 Plus 用来设置你在哪款移动设备的模拟器上生成骨架页面,配置参考puppeteer。
defer Number No 5000 puppeteer 启动 headless Chrome 浏览器,打开页面后的延迟,主要是为了保证页面加载完全,单位是ms。
Default options
const pluginDefaultConfig = {
  port: '8989',
  text: {
    color: '#EEEEEE'
  },
  image: {
    shape: 'rect', // `rect` | `circle`
    color: '#EFEFEF',
    shapeOpposite: []
  },
  button: {
    color: '#EFEFEF',
    excludes: [] 
  },
  svg: {
    color: '#EFEFEF',
    shape: 'circle', // circle | rect
    shapeOpposite: []
  },
  pseudo: {
    color: '#EFEFEF', // or transparent
    shape: 'circle' // circle | rect
  },
  device: 'iPhone 6 Plus',
  debug: false,
  minify: {
    minifyCSS: { level: 2 },
    removeComments: true,
    removeAttributeQuotes: true,
    removeEmptyAttributes: false
  },
  defer: 5000,
  excludes: [],
  remove: [],
  hide: [],
  grayBlock: [],
  cookies: [],
  storagies: {},
  sessionStoragies: {},
  cssUnit: 'rem',
  decimal: 4,
  logLevel: 'info',
  quiet: false,
  noInfo: false,
  logTime: true
}

文章相关链接:

  • Vue项目骨架屏注入实践
  • 服务端渲染(SSR)

你可能感兴趣的:(vue骨架屏实践)