摘要:可以通過的提供的直接控制模擬大部分用戶操作來進行或者作為爬蟲訪問頁面來收集數(shù)據(jù)。
??骨架屏是在頁面數(shù)據(jù)尚未加載完成前先給用戶展示出頁面的大致結(jié)構(gòu),直到請求數(shù)據(jù)返回后再顯示真正的頁面內(nèi)容;隨著單頁應(yīng)用( SPA )的越來越流行,單頁應(yīng)用的用戶體驗也越來越得到前端開發(fā)者的關(guān)注;為了優(yōu)化用戶體驗,在數(shù)據(jù)到達用戶之前,往往會在頁面上加上 loading 的效果,而現(xiàn)在,越來越多的場景傾向于使用頁面的骨架替代單一的 loading 效果;
為什么需要自動生成骨架屏?
提高效率,節(jié)約多帶帶編寫骨架屏代碼的時間
替換原來單一的 loading 圖片效果
可以優(yōu)化用戶體驗,在頁面數(shù)據(jù)尚未加載完成前先給用戶展示出頁面的大致結(jié)構(gòu),配合動畫效果,給用戶一種平滑切換的感覺
常見的方案:
手動編寫骨架屏代碼
通過預(yù)渲染手動書寫的代碼生成相應(yīng)的骨架屏,比如:vue-skeleton-webpack-plugin
餓了么內(nèi)部的生成骨架頁面的工具page-skeleton-webpack-plugin
..
a. 前兩者的前提都是需要開發(fā)者自己編寫骨架屏代碼
b. 餓了么的做的比較強大了,還有 UI 界面專門調(diào)整骨架屏
對于復(fù)雜的頁面也會有不盡如人意的地方
生成的骨架屏節(jié)點是基于頁面本身的結(jié)構(gòu)和 CSS,存在嵌套比較深的情況,體積不會太小
只支持 history 模式.
我們的方案是:用純 DOM 的方式結(jié)合 Puppeteer 自動生成網(wǎng)頁骨架屏
編寫操作 DOM 的 Javascript 腳本
遍歷可見區(qū)域可見的 DOM 節(jié)點,包括:非隱藏元素、寬高大于 0 的元素、非透明元素、內(nèi)容不是空格的元素、位于瀏覽窗口可見區(qū)域內(nèi)的元素
針對(背景)圖片、文字、表單項、音頻視頻等區(qū)域,算出其所占區(qū)域的寬、高、距離視口的絕對距離等信息
對于符合生成條件的區(qū)域,一視同仁,生成相應(yīng)區(qū)域的顏色塊
“一視同仁”即對于符合條件的區(qū)域,不區(qū)分具體元素,不用考慮結(jié)構(gòu)層級,不考慮樣式,統(tǒng)一生成 div 的顏色塊
該腳本的運行環(huán)境決定了獲取到的元素尺寸與相關(guān)距離單位不可控,可能需要做轉(zhuǎn)換,比如用的 rem、em、vh 等;我們采用比較簡單的方式,不取 style 的尺寸相關(guān)的值,而是通過 getBoundingClientRect 獲取寬、高、距離視口距離的絕對值,與當(dāng)前設(shè)備的寬高,計算出相應(yīng)的百分比作為顏色塊的單位,這樣來適配不同設(shè)備
對于頁面結(jié)構(gòu)比較復(fù)雜或者大圖片比較多的頁面,會出現(xiàn)不盡如人意的地方,我們通過 includeElement(node, draw)和 init 兩個鉤子函數(shù)來支持自定義的微調(diào)
以上就能夠直接跑在瀏覽器生成骨架屏代碼了,手動添加到應(yīng)用頁面
const createSkeletonHTML = require("DrawPageStructure/evalDOM") createSkeletonHTML({ // ... background: "red", animation: "opacity 1s linear infinite;" }).then(skeletonHTML => { console.log(skeletonHTML) }).catch(e => { console.error(e) })
??直接在瀏覽器端運行,在控制臺打印當(dāng)前頁面骨架屏節(jié)點,復(fù)制添加到應(yīng)用頁面,但是該方式不夠自動化,我們該讓骨架屏自動生成并添加到應(yīng)用頁面
Puppeteer
Puppeteer 是谷歌官方出品的一個可以控制 headless Chrome 的 Node 庫??梢酝ㄟ^ Puppeteer 的提供的 api 直接控制 Chrome 模擬大部分用戶操作來進行 UI Test 或者作為爬蟲訪問頁面來收集數(shù)據(jù)。
Puppeteer 提供運行環(huán)境和導(dǎo)出方式
使用 puppeteer 運行需要生成骨架屏的頁面
將之前編寫的 Javascript 腳本通過 puppeteer 提前注入到該頁面,這樣即可運行該腳本,并生成骨架屏所需的 DOM 節(jié)點
將自動生成的骨架屏 DOM 片段插入到應(yīng)用頁面的入口節(jié)點
const evalDOM = require("../evalDOM"); await page.goto(url, {waitUntil: "networkidle0"}); const skeletonHTML = await page.evaluate.call(page, evalDOM, ...args);
小結(jié)
核心在于 DOM 操作,puppeteer 僅提供運行環(huán)境和導(dǎo)出方式
只要能訪問的頁面都能生成,history 與 hash 模式無限制
不受項目和框架的限制,vue 和 react 等項目零修改即可復(fù)用
生成色塊的單位為百分比,不同設(shè)備自適應(yīng)
不需要 css-tree 來提取樣式,不依賴頁面本身的布局結(jié)構(gòu),生成扁平的 DOM 節(jié)點體積特別小
支持自定義生成方式與導(dǎo)出方式
還有很多細(xì)節(jié)優(yōu)化中,歡迎感興趣的小伙伴一起加入!
詳細(xì)代碼和使用方式請移步: https://github.com/famanoder/...
歡迎 star !,歡迎提 PR !
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/98301.html
摘要:常用于文章列表動態(tài)列表頁等相對比較規(guī)則的列表頁面。很多項目中都有應(yīng)用餓了么版本知乎等網(wǎng)站中都有應(yīng)用。歡迎討論,點個贊再走吧 骨架屏 最近在項目不時有用到骨架屏的需求,所以抽時間對骨架屏的方案作了一下調(diào)研,骨架屏的實踐已經(jīng)有很多了,也有很多人對自己的方案作了介紹.在這里按照個人的理解做了一個匯總和分類,分享給大家. 關(guān)于骨架屏(簡介) 骨架屏就是在頁面數(shù)據(jù)尚未加載前先給用戶展示出頁面的大...
摘要:常用于文章列表動態(tài)列表頁等相對比較規(guī)則的列表頁面。很多項目中都有應(yīng)用餓了么版本知乎等網(wǎng)站中都有應(yīng)用。歡迎討論,點個贊再走吧 骨架屏 最近在項目不時有用到骨架屏的需求,所以抽時間對骨架屏的方案作了一下調(diào)研,骨架屏的實踐已經(jīng)有很多了,也有很多人對自己的方案作了介紹.在這里按照個人的理解做了一個匯總和分類,分享給大家. 關(guān)于骨架屏(簡介) 骨架屏就是在頁面數(shù)據(jù)尚未加載前先給用戶展示出頁面的大...
摘要:常用于文章列表動態(tài)列表頁等相對比較規(guī)則的列表頁面。很多項目中都有應(yīng)用餓了么版本知乎等網(wǎng)站中都有應(yīng)用。歡迎討論,點個贊再走吧 骨架屏 最近在項目不時有用到骨架屏的需求,所以抽時間對骨架屏的方案作了一下調(diào)研,骨架屏的實踐已經(jīng)有很多了,也有很多人對自己的方案作了介紹.在這里按照個人的理解做了一個匯總和分類,分享給大家. 關(guān)于骨架屏(簡介) 骨架屏就是在頁面數(shù)據(jù)尚未加載前先給用戶展示出頁面的大...
摘要:第二套方案,一定程度上改善了第一套方案帶來的維護成本增加的缺點,主要還是使用工具預(yù)渲染頁面,獲取到節(jié)點和樣式,保留頁面結(jié)構(gòu),覆蓋樣式,生成灰色塊蓋在原有文本圖片或者是等節(jié)點上面,最后將生成的和打包出來,就是一個帶有骨架屏的頁面。 首屏 一般情況下,在首屏數(shù)據(jù)未拿到之前,為了提升用戶的體驗,會在頁面上展示一個loading的圖層,類似下面這個showImg(https://segment...
閱讀 2607·2021-09-24 10:29
閱讀 3881·2021-09-22 15:46
閱讀 2628·2021-09-04 16:41
閱讀 3038·2019-08-30 15:53
閱讀 1325·2019-08-30 14:24
閱讀 3115·2019-08-30 13:19
閱讀 2233·2019-08-29 14:17
閱讀 3583·2019-08-29 12:55