基於 vue-skeleton-webpack-plugin 的骨架屏實戰

前言

目前正在作的項目,登陸是須要跳轉到別人的頁面的,致使重定向不少,須要優化一下白屏時間,因此就用到了骨架屏,可是此次用的骨架屏不是自動生成的,仍是本身敲的樣式,一步步來吧,先從簡單的用起🤝。css

先上效果圖: vue

什麼是骨架屏

骨架屏,英文 Skeleton screen,是指在頁面開始渲染以前的白屏時間內,先讓用戶看到即將要展示頁面的「骨架」,頁面渲染完成以後再將它替換掉,起到一個從 白屏 → 渲染完成 過程當中的過渡做用,它能夠有效減小用戶的感知時間,讓用戶「感受上」認爲打開頁面比較快(相比較於完整的白屏時間)。webpack

實現

本文主要圍繞一個開源的 Webpack 插件 vue-skeleton-webpack-plugin,來實如今 Vue 項目中加入骨架屏。git

因爲項目對骨架屏的需求不一樣,相應的代碼也會不同。 本文所實現的骨架屏是 基於 Vue-cli 3.x 搭建的項目,根據的不一樣路由,顯示不一樣的骨架屏,如需其餘用法詳見開源插件。github

讓咱們開始吧🏄。web

首先是安裝插件:vue-router

npm install vue-skeleton-webpack-plugin
複製代碼

vue.config.js

安裝完成後在 vue.config.js 中作以下配置:npm

const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
module.exports = {
    configureWebpack: (config) => {
        config.plugins.push(new SkeletonWebpackPlugin({
            webpackConfig: {
                entry: {
                    app: path.join(__dirname, './src/skeleton/skeleton.js')
                }
            },
            // SPA 下是壓縮注入 HTML 的 JS 代碼
            minimize: true,
            // 服務端渲染時是否須要輸出信息到控制檯
            quiet: true,
            // 根據路由顯示骨架屏
            router: {
                    mode: 'history',
                    routes: [
                        {
                            path: '/',
                            skeletonId: 'skeleton-home'
                        },
                        {
                            path: '/message',
                            skeletonId: 'skeleton-message'
                        }
                    ]
            }
        }
    },
    css: {
        // 使用 css 分離插件 mini-css-extract-plugin,否則骨架屏組件裏的 <style> 不起做用,
        extract: true,
    }
}
複製代碼

其中 skeleton.js 是咱們骨架屏的入口,咱們過會再建立。先看來一下其中 router 這個配置項。數組

router 的配置決定了咱們各個路由路徑所對應的骨架屏。bash

  • router.mode 填路由模式,兩個值可選 history | hash.
  • router.routes 填路由數組,其中 path 對應着頁面在 vue-router 中的 pathskeletonId 是骨架屏的 id,後面立刻會說明。

skeleton.js

配置完成後,新建一個骨架屏的入口 skeleton.js。

// src/skeleton/skeleton.js
import Vue from 'vue'

// 引入的骨架屏組件
import skeletonHome from './skeleton/skeletonHome.vue'
import skeletonMessage from './skeleton/skeletonMessage.vue'

export default new Vue({
    components: {
        skeletonHome,
        skeletonMessage,
    },
    template: `
        <div>
            <skeletonHome id="skeleton-home" style="display:none"/>
            <skeletonMessage id="skeleton-message" style="display:none"/>
        </div>
    `
})
複製代碼

上面的代碼中,引入的兩個組件分別對應 首頁(Home)消息頁(Message) 的骨架屏,其中組件的 id 對應以前在 vue.config.jsskeletonId

貼上其中一個骨架屏組件的代碼:

// skeletonMessage.vue
<template>
    <div class="skeleton-block">
      <div class="sk-loanList-header-bg"></div>
      <s-messageItem/>
      <s-messageItem/>
      <s-messageItem/>
      <s-messageItem/>
    </div>
</template>

<script>
import messageItem from './components/s-messageListItem'
export default {
    name: 'skeletonMessage',
    components: {
        's-messageItem': messageItem
    }
}
</script>

<style scoped>
.skeleton-block {
    width:100%;
    height: 100vh;
}
.sk-loanList-header-bg {
    height:88px;
    background:#2954D0;
}
</style>
複製代碼

其實就是很普通的一個 Vue 組件,在組件裏寫本身想要的骨架屏的樣式便可,可複用的地方還能夠再分紅組件。 在路由里加上 skeletonMessage ,看一下效果:

至此,如今骨架屏已經準備就緒了,是否是很簡單🤨。

效果展現

這邊模擬一下移動端訪問環境,先進入 Chrome DevTools 中的 Performance 進行設置。

運行 Performance:

效果:

從骨架屏替換成頁面的過程當中仍是有閃一下的,目前還不知道這個是否能夠優化,嘗試中。

查看一下 Performance 中不一樣頁面展示的時間:

(ps:解釋一下,我也不知道什麼狀況,運行完以後就是尼🐴這麼糊...)

能夠看到在經過本地運行訪問的狀況下(本地訪問較快),在進入頁面後 221ms 頁面先展現骨架屏,隨後在 738ms 時完成頁面的渲染。

這裏若是不加骨架屏的話就是 738ms 的白屏時間,咱們已經經過骨架屏優化了一些白屏時間🏄。

最後

vue-skeleton-webpack-plugin 是較爲初級的骨架屏方案,相信你們也能夠立刻想到許多缺點。

好比:

  • 須要手動去寫骨架屏的樣式。
  • 骨架屏樣式在不一樣尺寸下的響應式問題。
  • 在界面改動以後也須要手動修改對應的骨架屏。

因爲在本人的項目中使用到了 postcss-px2rem 自動 px 轉 rem,因此避開了一些缺點。

其餘方法

此外還有許多使用骨架屏的方法:

  • page-skeleton-webpack-plugin 餓了麼開源的自動生成骨架屏生成插件。
  • 用 base64 的圖片作骨架屏,就讓 UI 在出設計稿的時候順便把骨架屏也給畫了😂。

參考: juejin.im/post/5b79a2…

相關文章
相關標籤/搜索