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

小土豆biubiubiu發表於2020-10-20

作者:小土豆biubiubiu

部落格園:https://www.cnblogs.com/HouJiao/

掘金:https://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為:

http://localhost:8080/#/  
http://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

一個努力學習的前端小菜鳥,知識是無限的。堅信只要不停下學習的腳步,總能到達自己期望的地方

同時還是一個喜歡小貓咪的人,家裡有一隻美短小母貓,名叫土豆

部落格園

https://www.cnblogs.com/HouJiao/

掘金

https://juejin.im/user/2436173500265335

微信公眾號

土豆媽的碎碎念

微信公眾號的初衷是記錄自己和身邊的一些故事,同時會不定期更新一些技術文章

歡迎大家掃碼關注,一起吸貓,一起聽故事,一起學習前端技術

作者寄語

小小總結,歡迎大家指導~

相關文章