前言

最近周末有点时间想着把博客网站再折腾一下,上点流行的技术,提高一下网站交互体验,准备从以下几点入手,也算立个flag,提醒自己不要偷懒:

  • 骨架屏
  • PWA (Progressive Web App)
  • service worker 做离线缓存
  • manifest.json 搞个添加至首屏和启动动画
  • 消息推送

网站概况

前端:

因为工作中用过Angular4和React,所以网站用Vue搭的

角手架是vue-cli 2.9,用到的组件库是: Element-UI

后台:

  1. 阿里云上买了一个的服务器, 操作系统是Linux Unbuntu
    注:有点后悔,感觉现在CentOS用的多一些。内存起码要1G,否则npm run build起不来
  2. nginx服务器指向项目build好的目录(即网站根目录)
  3. 获取数据通过node查询MongoDB数据库。

什么是骨架屏 Skeleton Screen

Google 有一篇很好的文章 User-centric Performance Metrics 是关于网站性能的关键指标以及度量方式。

Android骨架屏recycleview 骨架屏安卓_vue-cli

Android骨架屏recycleview 骨架屏安卓_vue-cli_02

FP/FCP就是我们经常所说的首屏渲染。

最差的体验当然是首屏加载好之前页面一片空白,用户很难知道发生了什么,是正在加载还是加载失败?为了提示用户,我们通常会放一个loading动画,基本上就是菊花图以及各种变种。这会好一些,但是还不足够好。问题就在于从加载中到加载完成是一个粗暴的跳转过程,从白屏直接到内容。如果中间能有个过渡过程,给用户一个如丝般顺滑的感觉,那就完美了。骨架屏就应运而生。

骨架屏就是加载前把内容的大概轮廓预先展现出来,然后再逐步的加载真正的内容,给用户一种内容正在逐渐加载即将呈现的期待,既降低了焦虑,又使得页面加载的过程变得顺畅,会有一种比其他加载方式更快的感觉

骨架屏实现方式

  • SSR (server side rending)服务端渲染
  • 预渲染(prerender)

SSR:

将骨架屏组件的 HTML 片段插入 HTML 页面模版(Template)的挂载点中,样式内联到 head 标签中。当前端真正的内容渲染完成时,Vue 将使用客户端混合,把挂载点中的骨架屏内容替换成真正的页面内容。

注:所谓客户端激活,指的是 Vue 在浏览器端接管由服务端发送的静态 HTML,使其变为由 Vue 管理的动态 DOM 的过程。

预渲染:
无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时(build time)简单地生成针对特定路由的静态 HTML 文件。优点是设置预渲染更简单,并可以将你的前端作为一个完全静态的站点。

事实上作为一个简单的个人网站,其实用预渲染的方式就足够了,为了解一下服务端渲染的知识,我还是采用了SSR的方式。
Vue SSR 指南

vue-skeleton-webpack-plugin

这是一个基于 vue 的 webpack 插件,为单页和多页应用生成 skeleton,提升首屏展示体验。

先来看一下效果:

Android骨架屏recycleview 骨架屏安卓_骨架屏_03

配置步骤

  1. 新建webpack.skeleton.conf.js
'use strict';

const path = require('path')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const nodeExternals = require('webpack-node-externals')

function resolve(dir) {
  return path.join(__dirname, dir)
}

module.exports = merge(baseWebpackConfig, {
  target: 'node',
  devtool: false,
  entry: {
    app: resolve('../src/entry-skeleton.js')
  },
  output: Object.assign({}, baseWebpackConfig.output, {
    libraryTarget: 'commonjs2'
  }),
  externals: nodeExternals({
    whitelist: /\.css$/
  }),
  plugins: []
})
  1. 在webpack.skeleton.conf中entry的路径下添加骨架屏SSR入口:
    entry-skeleton.js
import Vue from 'vue'
import Skeleton from './components/skeleton/Skeleton'

export default new Vue({
  components: {
    Skeleton
  },
  template: '<skeleton />'
})
  1. 骨架屏组件
    这个就不放代码了,根据自己页面的情况手动做一个骨架屏
  2. npm run build
    打开dist目录下的index.html(即网站的入口),可以看到骨架屏组件已经成功添加了。
  3. Android骨架屏recycleview 骨架屏安卓_骨架屏_04

一个小坑

我的项目引用了iconfont和Element-UI,在build时会报一个错,看起来是和css有些关联,可能我哪里还需要再配置一下。但是这个并不影响打包结果,项目仍可顺利运行

Android骨架屏recycleview 骨架屏安卓_Skeleton_05

骨架屏就先告一段落。