骨架屏是什么?
在Goole提出的以用戶為中心的四個頁面性能衡量指標中,FP/FCP(首屏渲染)。
關於盡快渲染出首屏,減少白屏時間,常見的優化方式大致有以下幾種:
1. 優化關鍵渲染路徑,盡可能減少阻塞渲染的JavaScript和CSS,常見做法包括使用async/defer讓瀏覽器下載JavaScript的同時不阻塞HTML解析,內聯頁面關鍵部分的 樣式
2. 使用Service Worker 緩存AppShell,加快后續訪問速度。
3. 使用HTTP/2 Server Push,幫助瀏覽器今早發現靜態資源,減少請求數。淺談HTTP/2 Server Push
骨架屏充分利用了前兩點。
實現思路
從H5生成骨架屏方案說起,總得來說H5生成骨架屏的方案有2種
1. 完全靠手寫HTML和CSS方式給每個頁面定制一套骨架屏
2. 利用預渲染的方式生成靜態骨架屏
第一套方案,無疑是最簡單最直白的方式,缺點也很明細,加入頁面布局有修改的話,那么除了修改業務代碼之外還需要額外修改骨架屏,增加了維護的成本。
第二套方案,一定程度上改善了第一套方案帶來的維護成本增加的缺點,主要還是使用工具預渲染頁面,獲取到DOM節點和樣式,保留頁面結構,覆蓋樣式,生成灰色塊蓋在原有文本、圖片或者是canvas等節點上面,最后將生成的HTML和CSS打包出來,就是一個帶有骨架屏的頁面。最后再利用webpack工具將生成的骨架屏插入到HTML頁面,詳細的話可以看看餓了么的分享。
小程序生成骨架屏
1. 預渲染
2. 節點
我們看小程序官網api給的例子
實現方法: 我們根據class或者id獲取節點信息,然后手動添加需要處理的形狀,約定2個特殊的class為獲取節點的標記,在組件里進行相應的繪制就可以了。
SelectQuery NodesRef.boundingClientRect(function callback) 添加節點的布局位置的查詢請求,相對於顯示區域,以像素為單位。其功能類似於DOM的getBoundingClientRect
這里我們需要使用官網的SelectorQuery的selectAll()和exec(function callback)執行所有請求,請求結果按請求次序構成數組
現在我們拿一個簡單的頁面試一下
添加自定義class
1. 獲取首屏的布局位置
打印結果:
2. 接下來我們需要將首屏可視區域的寬高,賦值到我們的組件里
大功告成啦
現在我們利用骨架屏這個小組件,寫一下日志demo的首屏渲染
其中日志列表是請求數據,我們只需要對其進行初始渲染即可。
1. 引入skeleton組件
2. 將列表容器(可以是最外層容器也可以是列表的次級容器)加上skeleton,列表的class加上skeleton-rect
此時我遇到了一個問題,就是有時候重新編譯,找不到skeleton-rect,但是能找到他的最外層容器。最后發現是由於我沒有在組件里加wx:key導致的。加上就可以了。
注意:由於骨架屏組件是通過定位來
現在讓我們暢快的用骨架屏優化用戶體驗吧!!!