资讯专栏INFORMATION COLUMN

用纯 DOM 的方式结合 Puppeteer 自动生成网页骨架屏

BlackHole1 / 2607人阅读

摘要:可以通过的提供的直接控制模拟大部分用户操作来进行或者作为爬虫访问页面来收集数据。

  骨架屏是在页面数据尚未加载完成前先给用户展示出页面的大致结构,直到请求数据返回后再显示真正的页面内容;随着单页应用( SPA )的越来越流行,单页应用的用户体验也越来越得到前端开发者的关注;为了优化用户体验,在数据到达用户之前,往往会在页面上加上 loading 的效果,而现在,越来越多的场景倾向于使用页面的骨架替代单一的 loading 效果;

为什么需要自动生成骨架屏?

提高效率,节约多带带编写骨架屏代码的时间

替换原来单一的 loading 图片效果

可以优化用户体验,在页面数据尚未加载完成前先给用户展示出页面的大致结构,配合动画效果,给用户一种平滑切换的感觉

常见的方案:

手动编写骨架屏代码

通过预渲染手动书写的代码生成相应的骨架屏,比如:vue-skeleton-webpack-plugin

饿了么内部的生成骨架页面的工具page-skeleton-webpack-plugin

..

a. 前两者的前提都是需要开发者自己编写骨架屏代码
b. 饿了么的做的比较强大了,还有 UI 界面专门调整骨架屏

对于复杂的页面也会有不尽如人意的地方

生成的骨架屏节点是基于页面本身的结构和 CSS,存在嵌套比较深的情况,体积不会太小

只支持 history 模式.

我们的方案是:用纯 DOM 的方式结合 Puppeteer 自动生成网页骨架屏

编写操作 DOM 的 Javascript 脚本

遍历可见区域可见的 DOM 节点,包括:非隐藏元素、宽高大于 0 的元素、非透明元素、内容不是空格的元素、位于浏览窗口可见区域内的元素

针对(背景)图片、文字、表单项、音频视频等区域,算出其所占区域的宽、高、距离视口的绝对距离等信息

对于符合生成条件的区域,一视同仁,生成相应区域的颜色块

“一视同仁”即对于符合条件的区域,不区分具体元素,不用考虑结构层级,不考虑样式,统一生成 div 的颜色块

该脚本的运行环境决定了获取到的元素尺寸与相关距离单位不可控,可能需要做转换,比如用的 rem、em、vh 等;我们采用比较简单的方式,不取 style 的尺寸相关的值,而是通过 getBoundingClientRect 获取宽、高、距离视口距离的绝对值,与当前设备的宽高,计算出相应的百分比作为颜色块的单位,这样来适配不同设备

对于页面结构比较复杂或者大图片比较多的页面,会出现不尽如人意的地方,我们通过 includeElement(node, draw)和 init 两个钩子函数来支持自定义的微调

以上就能够直接跑在浏览器生成骨架屏代码了,手动添加到应用页面

    const createSkeletonHTML = require("DrawPageStructure/evalDOM")

    createSkeletonHTML({
        // ...
        background: "red",
        animation: "opacity 1s linear infinite;"
    }).then(skeletonHTML => {
        console.log(skeletonHTML)
    }).catch(e => {
        console.error(e)
    })

  直接在浏览器端运行,在控制台打印当前页面骨架屏节点,复制添加到应用页面,但是该方式不够自动化,我们该让骨架屏自动生成并添加到应用页面

Puppeteer

Puppeteer 是谷歌官方出品的一个可以控制 headless Chrome 的 Node 库。可以通过 Puppeteer 的提供的 api 直接控制 Chrome 模拟大部分用户操作来进行 UI Test 或者作为爬虫访问页面来收集数据。

Puppeteer 提供运行环境和导出方式

使用 puppeteer 运行需要生成骨架屏的页面

将之前编写的 Javascript 脚本通过 puppeteer 提前注入到该页面,这样即可运行该脚本,并生成骨架屏所需的 DOM 节点

将自动生成的骨架屏 DOM 片段插入到应用页面的入口节点

const evalDOM = require("../evalDOM");

await page.goto(url, {waitUntil: "networkidle0"});
const skeletonHTML = await page.evaluate.call(page, evalDOM, ...args);

小结

核心在于 DOM 操作,puppeteer 仅提供运行环境和导出方式

只要能访问的页面都能生成,history 与 hash 模式无限制

不受项目和框架的限制,vue 和 react 等项目零修改即可复用

生成色块的单位为百分比,不同设备自适应

不需要 css-tree 来提取样式,不依赖页面本身的布局结构,生成扁平的 DOM 节点体积特别小

支持自定义生成方式与导出方式

还有很多细节优化中,欢迎感兴趣的小伙伴一起加入!

详细代码和使用方式请移步: https://github.com/famanoder/...

欢迎 star !,欢迎提 PR !

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98301.html

相关文章

  • 摩拜前端周刊第8期

    摘要:地址前端词典提高幸福感的个技巧推荐文章介绍了个更加简洁优雅的使用技巧。这些技巧确实在实际开发中十分常用,作者总结的很好,特别是针对降级问题又学到了一个新思路。值得奋战在一线的攻城狮们阅读学习。Ladies and 乡亲们,摩拜前端周刊起航啦~ 摩拜前端团队会收集每周前端优秀文章,每周五发布至掘金平台,欢迎关注我们~ 过个没什么了不起的一天,耀眼一些,你有资格 Top 榜 「中高级前端」...

    lykops 评论0 收藏0
  • 前端骨架方案小结

    摘要:常用于文章列表动态列表页等相对比较规则的列表页面。很多项目中都有应用饿了么版本知乎等网站中都有应用。欢迎讨论,点个赞再走吧 骨架屏 最近在项目不时有用到骨架屏的需求,所以抽时间对骨架屏的方案作了一下调研,骨架屏的实践已经有很多了,也有很多人对自己的方案作了介绍.在这里按照个人的理解做了一个汇总和分类,分享给大家. 关于骨架屏(简介) 骨架屏就是在页面数据尚未加载前先给用户展示出页面的大...

    IntMain 评论0 收藏0
  • 前端骨架方案小结

    摘要:常用于文章列表动态列表页等相对比较规则的列表页面。很多项目中都有应用饿了么版本知乎等网站中都有应用。欢迎讨论,点个赞再走吧 骨架屏 最近在项目不时有用到骨架屏的需求,所以抽时间对骨架屏的方案作了一下调研,骨架屏的实践已经有很多了,也有很多人对自己的方案作了介绍.在这里按照个人的理解做了一个汇总和分类,分享给大家. 关于骨架屏(简介) 骨架屏就是在页面数据尚未加载前先给用户展示出页面的大...

    TerryCai 评论0 收藏0
  • 前端骨架方案小结

    摘要:常用于文章列表动态列表页等相对比较规则的列表页面。很多项目中都有应用饿了么版本知乎等网站中都有应用。欢迎讨论,点个赞再走吧 骨架屏 最近在项目不时有用到骨架屏的需求,所以抽时间对骨架屏的方案作了一下调研,骨架屏的实践已经有很多了,也有很多人对自己的方案作了介绍.在这里按照个人的理解做了一个汇总和分类,分享给大家. 关于骨架屏(简介) 骨架屏就是在页面数据尚未加载前先给用户展示出页面的大...

    MasonEast 评论0 收藏0
  • 小程序构建骨架探索

    摘要:第二套方案,一定程度上改善了第一套方案带来的维护成本增加的缺点,主要还是使用工具预渲染页面,获取到节点和样式,保留页面结构,覆盖样式,生成灰色块盖在原有文本图片或者是等节点上面,最后将生成的和打包出来,就是一个带有骨架屏的页面。 首屏 一般情况下,在首屏数据未拿到之前,为了提升用户的体验,会在页面上展示一个loading的图层,类似下面这个showImg(https://segment...

    shiweifu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<