精华内容
下载资源
问答
  • 前端骨架屏实践

    2019-12-10 14:18:36
    前端骨架屏的实践: 在众多的前端开发产品中,对于loadding的致敬是非常多的,今天讨论下骨架屏(Skeleton Screen)实现的几种方式以及实例。 一、 gif动画形式 在pc端这种菊花图已经占领很大市场了,具体的应用如下...

    前端骨架屏的实践:

    在众多的前端开发产品中,对于loadding的致敬是非常多的,今天讨论下骨架屏(Skeleton Screen)实现的几种方式以及实例。

    一、 gif动画形式
    在这里插入图片描述
    在pc端这种菊花图已经占领很大市场了,具体的应用如下:

    <template>
    	<div>
    		<img v-if="iShowLoading" src="loading.gif" />
    		<div v-else>
    			....具体节点
    		</div>
    	</div>
    </template>
    <script>
    	data() {
    		iShowLoading: true
    	},
    	async mounted() {
    		let res = await api.post('api/data');
    		if (res.code == 200) {
    			// 返回数据成功
    			this.iShowLoading = false;
    		}
    	}
    </script>
    

    在mounted钩子里面讲loadding关闭的处理方式表示在数据请求成功之后,关闭loadding此时开始渲染页面。

    二、手写HTML和CSS方式给每个页面定制一套骨架屏

    <style lang="less">
    	.skeletons .skeletons-rect {
    		background: #F2F2F2 !important;
    		color: transparent !important;
    		animation: gradient linear 1s infinite;
    	}
    	.content1 {
    		height: 90px;
    		width: 200px;
    		margin: 0 auto;
    	}
    	.content2 {
    		height: 100px;
    		width: 300px;
    		margin: 50px auto;
    	}
    </style>
    <template>
    	<view class="{{iShowLoading ? 'skeletons' : ''}}">
    		<view class="content1 skeletons-rect">
    		</view>
    		<view class="content2 skeletons-rect">
    		</view>
    		<view class="content2 skeletons-rect">
    		</view>
    		<view class="content2 skeletons-rect">
    		</view>
    		<view class="content2 skeletons-rect">
    		</view>
    	</view>
    </template>
    
    <script>
    	data() {
    		iShowLoading: true
    	},
    	async mounted() {
    		let res = await api.post('api/data');
    		if (res.code == 200) {
    			// 返回数据成功
    			this.iShowLoading = false;
    		}
    	}
    </script>
    

    这种处理方式是可以实现根据页面内容的变化而实现不同的骨架屏样式。
    在这里插入图片描述
    但是这种处理方式还是有缺陷的:

    1. 需要给每一个元素都加上同样的类,增加了代码量
    2. 将骨架屏与业务代码耦合在一起,增加了耦合性

    三、利用webpack嵌入骨架屏页面

    展开全文
  • 作者:花满楼https://zhuanlan.zhihu.com/p/74403911什么是骨架屏?什么是骨架屏呢?骨架屏(Skeleton Screen)是指在页面数据加载完成前,先给用...

    作者:花满楼

    https://zhuanlan.zhihu.com/p/74403911

    什么是骨架屏?

    什么是骨架屏呢?骨架屏(Skeleton Screen)是指在页面数据加载完成前,先给用户展示出页面的大致结构(灰色占位图),在拿到接口数据后渲染出实际页面内容然后替换掉。Skeleton Screen 是近两年开始流行的加载控件,本质上是界面加载过程中的过渡效果。

    假如能在加载前把网页的大概轮廓预先显示,接着再逐渐加载真正内容,这样既降低了用户的焦灼情绪,又能使界面加载过程变得自然通畅,不会造成网页长时间白屏或者闪烁。这就是 Skeleton Screen !

    Skeleton Screen 能给人一种页面内容“已经渲染出一部分”的感觉,相较于传统的 loading 效果,在一定程度上可提升用户体验。

    骨架屏的实现方案

    目前生成骨架屏的技术方案大概有三种:

    1. 使用图片、svg 或者手动编写骨架屏代码:使用 HTML + CSS 的方式,我们可以很快的完成骨架屏效果,但是面对视觉设计的改版以及需求的更迭,我们对骨架屏的跟进修改会非常被动,这种机械化重复劳作的方式此时未免显得有些机动性不足;

    2. 通过预渲染手动书写的代码生成相应的骨架屏:该方案做的比较成熟的是 vue-skeleton-webpack-plugin,通过 vueSSR 结合 webpack 在构建时渲染写好的 vue 骨架屏组件,将预渲染生成的 DOM 节点和相关样式插入到最终输出的 html 中。

     // webpack.conf.js
     const SkeletonWebpackPlugin = require( vue-skeleton-webpack-plugin );
     plugins: [
      //...
      new SkeletonWebpackPlugin({
        webpackConfig: {
          entry: {
            app: resolve( ./src/entry-skeleton.js )
          }
        }
      })
     ]
    

    该方案的前提同样是编写相应页面的骨架屏组件,然后预渲染生成骨架屏所需的 DOM 节点,但由于该方案与 vue 相关技术直接关联,在当今前端框架三分天下的大环境下,我们可能需要一个更加灵活、可控的方案;

    3 . 饿了么内部的生成骨架页面的工具:该方案通过一个 webpack 插件 page-skeleton-webpack-plugin 的方式与项目开发无缝集成,属于在自动生成骨架屏方面做的非常强大的了,并且可以启动 UI 界面专门调整骨架屏,但是在面对复杂的页面也会有不尽如人意的地方,而且生成的骨架屏节点是基于页面本身的结构和 CSS,存在嵌套比较深的情况,体积不会太小,并且只支持 history 模式。

     // webpack.conf.js
     const HtmlWebpackPlugin = require( html-webpack-plugin )
     const { SkeletonPlugin } = require( page-skeleton-webpack-plugin )
     const path = require( path )
    
     plugins: [
      //...
      new HtmlWebpackPlugin({
        // Your HtmlWebpackPlugin config
      }),
      new SkeletonPlugin({
        pathname: path.resolve(__dirname, `${customPath}`), // 用来存储 shell 文件的地址
        staticDir: path.resolve(__dirname,  ./dist ), // 最好和 `output.path` 相同
        routes: [ / ,  /search ], // 将需要生成骨架屏的路由添加到数组中
      })
     ]
    

    我们的实现方案

    后来仔细想想,骨架屏这幅样子不是和一堆颜色块拼起来的页面一样吗?对比现有的骨架屏方案,这个想法有点“走捷径”的感觉。再进一步思考,这些色块基于当前页面去分析节点来生成,不如来段 JS 分析页面节点,一顿 DOM 操作生成颜色块拼成骨架屏。那么问题来了,该怎么样精确的分析页面节点,不同节点又该生成什么样的色块呢?

    既然骨架屏代表了页面的大致结构,那么需要先用 js 对页面的结构进行分析。分析之前,我们需要制定一种规则,以确定需要排除哪些节点?哪些种类的节点需要生成颜色块?生成的颜色块如何定位等等。我们初步定下的规则如下:

    1. 只遍历可见区域可见的 DOM 节点,包括:

    非隐藏元素、宽高大于 0 的元素、非透明元素、内容不是空格的元素、位于浏览窗口可见区域内的元素等;

    2. 针对(背景)图片、文字、表单项、音频视频、Canvas、自定义特征的块等区域来生成颜色块;

    3. 页面节点使用的样式不可控,所以不可取 style 的尺寸相关的值,可通过 getBoundingClientRect 获取节点宽、高、距离视口距离的绝对值,计算出与当前设备的宽高对应的百分比作为颜色块的单位,来适配不同设备;

    基于这套规则,我们开始生成骨架屏:

    首先,确定一个 rootNode 作为入口节点,比如 document.body,同时方便以后扩展到生成页面内局部的骨架屏,由此入口进行递归遍历和筛选,初步排除不可见节点。

    function isHideStyle(node) {
        return getStyle(node,  display ) ===  none  || 
            getStyle(node,  visibility ) ===  hidden  || 
            getStyle(node,  opacity ) == 0 ||
            node.hidden;
    }
    

    接下来判断元素特征,确定是否符合生成条件,对于符合条件的区域,”一视同仁”生成相应区域的颜色块。”一视同仁”即对于符合条件的区域不区分具体元素、不考虑结构层级、不考虑样式,统一根据该区域与视口的绝对距离值生成 div 的颜色块。之所以这样是因为生成的节点是扁平的,体积比较小,同时避免额外的读取样式表、通过抽离样式维持骨架屏的外观,这种统一生成的方式使得骨架屏的节点更可控。基于那上述“走捷径”的想法,该方法生成的骨架屏是由纯 DOM 颜色块拼成的。

    生成颜色块的方法:

    const blocks = [];
    // width,height,top,left 都是算好的百分比
    function drawBlock({width, height, top, left, zIndex = 9999999, background, radius} = {}) {
      const styles = [
         position: fixed ,
         z-index:  + zIndex,
         top:  + top + % ,
         left:  + left + % ,
         width:  + width + % ,
         height:  + height + % ,
         background:  + background
      ];
      radius && radius !=  0px  && styles.push( border-radius:   + radius);
      // animation && styles.push( animation:   + animation);
      blocks.push(`<div style="${ styles.join( ; ) }"></div>`);
    }
    

    绘制颜色块并不难,绘制之前的分析确认才是这个方案真正的核心和难点。比如,对于页面结构比较复杂或者大图片比较多的页面,由图片拼接的区域没有边界,生成的颜色块就会紧挨着,出现不尽如人意的地方。再比如,一个包含很多符合生成条件的小块的 card 块区域,是以 card 块为准还是以里面的小块为准来生成颜色块呢?如果以小块为准,绘制结果可能给人的感觉压根就不是一个 card 块,再加上布局方式和样式的可能性太多,大大增加了不确定因素。而如果以 card 块为准生成颜色块的话还要对 card 块做专门的规则。

    目前来说,对于页面结构不是特别复杂,不是满屏图片的,不是布局方式特别“飘逸“的场景,该方式已经可以生成比较理想的骨架屏了。而对于那些与预期相差较远的情况,我们提供了两个钩子函数可供微调:

    1. init 函数,在开始遍历节点之前执行,适合删除干扰节点等操作。

    2. includeElement(node, draw) 函数,可在遍历到指定节点时,调 用 draw 方法进行自定义绘制。

    通过以上步骤就能够直接在浏览器中生成骨架屏代码了。

    在浏览器里运行

    由于我们的方案出发点是通过单纯的 DOM 操作,遍历页面上的节点,根据制定的规则生成相应区域的颜色块,最终形成页面的骨架屏,所以核心代码完全可以直接跑在浏览器端;

    const createSkeletonHTML = require( draw-page-structure/evalDOM )
        createSkeletonHTML({
            // ...
            background:  red ,
            animation:  opacity 1s linear infinite; 
        }).then(skeletonHTML => {
            console.log(skeletonHTML)
        }).catch(e => {
            console.error(e)
        })
    

    结合 Puppeteer 自动生成骨架屏

    虽然该方式已经可以生成骨架屏代码了,但是还是不够自动化,为了让生成的骨架屏代码自动加载进指定页面。于是,我们开发了一个配套的 CLI 工具。这个工具通过 Puppeteer 运行页面,并把 evalDOM.js 脚本注入页面自动执行,执行的结果是生成的骨架屏代码被插入到应用页面。

    我们的方案大概思路如下:

    接下来看看如何使用 CLI 工具生成骨架屏,最多只需如下四步:

    1. 全局安装,npm i draw-page-structure – g

    2. dps init 生成配置文件 dps.config.js

    3. 修改 dps.config.js 进行相关配置

    4. dps start 开始生成骨架屏

    只需简单几步,然而并没有繁琐的配置:

    一般来说,你需要按自己的项目情况来配置 dps.config.js ,常见的配置项有:

    • url: 待生成骨架屏的页面地址

    • output.filepath: 生成的骨架屏节点写入的文件

    • output.injectSelector: 骨架屏节点插入的位置,默认 #app

    • background: 骨架屏主题色

    • animation: css3 动画属性

    • rootNode: 真对某个模块生成骨架屏

    • device: 设备类型,默认 mobile

    • extraHTTPHeaders: 添加请求头

    • init: 开始生成之前的操作

    • includeElement(node, draw): 定制某个节点如何生成

    • writePageStructure(html, filepath): 回调的骨架屏节点

    详细代码及工具的使用请移步 [Github]( famanoder/dps);

    初步实现的效果:

    *  京东 PLUS 会员正式中首页,通过该方案生成的骨架屏效果:


    总结

    以上就是基于 DOM 的骨架屏自动生成方案,其核心是 evalDOM 函数。这个方案在很多场景下的表现还是令人满意的。不过,网页布局和样式组合的可能性太多,想要在各种场景下都获得理想的效果,还有很长的路要走,但既然已经在路上,就勇敢的向前吧!

    欢迎 star,欢迎提 PR !https://github.com/famanoder/dps

    展开全文
  • 前端骨架屏方案小结

    2020-12-24 13:23:49
    骨架屏最近在项目不时有用到骨架屏的需求,所以抽时间对骨架屏的方案作了一下调研,骨架屏的实践已经有很多了,也有很多人对自己的方案作了介绍.在这里按照个人的理解做了一个汇总和分类,分享给大家.关于骨架屏(简介)...

    骨架屏

    最近在项目不时有用到骨架屏的需求,所以抽时间对骨架屏的方案作了一下调研,骨架屏的实践已经有很多了,也有很多人对自己的方案作了介绍.在这里按照个人的理解做了一个汇总和分类,分享给大家.

    关于骨架屏(简介)

    骨架屏就是在页面数据尚未加载前先给用户展示出页面的大致结构,直到请求数据返回后再渲染页面,补充进需要显示的数据内容。常用于文章列表、动态列表页等相对比较规则的列表页面。

    很多项目中都有应用:ex:饿了么h5版本,知乎,facebook等网站中都有应用。

    借个图举例如下:

    两类用途

    简介中作了关于用途的说明,但是仍然可以继续细分:

    作为spa中路由切换的loading,结合组件的生命周期和ajax请求返回的时机来使用.

    作为首屏渲染的优化.

    第一类用途

    第一类用途需要自己编写骨架屏,推荐两个成熟方便定制的svg组件定制为骨架屏的方案

    作为首屏渲染(自动化方案)

    该方案是饿了么在骨架屏的实践中总结出的一套方案:

    骨架屏的dom结构和css通过离线生成后构建的时候注入模板中的节点下面.

    使用时候的注意点:

    cssUnit的配置: 需要使用自适应的单位,按照文档给出的选择范围选,直接用 px 生成的比例会不合适

    puppeteer有大概80M, 安装的时候有可能不能一次下载成功.

    原理:

    通过 puppeteer 在服务端操控 headless Chrome 打开开发中的需要生成骨架屏的页面,在等待页面加载

    渲染完成之后,在保留页面布局样式的前提下,通过对页面中元素进行删减或增添,对已有元素通过层叠样

    式进行覆盖,这样达到在不改变页面布局下,隐藏图片和文字,通过样式覆盖,使得其展示为灰色块。然后

    将修改后的 HTML 和 CSS 样式提取出来,这样就是骨架屏了.

    其他方案

    结合ssr render/prerender来使用:

    事先编写好骨架屏组件通过ssr render 解析注入html文件中(除了需要自己编写外其实过程类似于上面的自动化方案)参考文章

    1中事先编写好的骨架屏组件可以用图片代替 (svg) ;或者设计师设计好.

    小程序的骨架屏

    不存在预渲染的概念,但是还是可以通过自己预先编写骨架屏组件放在页面中,等到异步请求的数据回来后更新页面.

    广而告之

    本文发布于薄荷前端周刊,欢迎Watch & Star ★,转载请注明出处。

    欢迎讨论,点个赞再走吧 。◕‿◕。 ~

    展开全文
  • 前端骨架屏终极方案——骨架图

    万次阅读 2019-08-15 15:08:37
    骨架图代替骨架屏。用图片代替骨架屏!!! 主要还没尝试过自动生成方案,手工写感觉太麻烦(美工已经操起了板砖。。。) 最简单的实现方式,拿页面的UI效果图(或者直接手机截屏),然后把动态元素内容抹掉,一般...

    骨架图代替骨架屏。用图片代替骨架屏!!!

    主要还没尝试过自动生成方案,手工写感觉太麻烦(美工已经操起了板砖。。。)

    最简单的实现方式,拿页面的UI效果图(或者直接手机截屏),然后把动态元素内容抹掉,一般是用浅灰色替代!想要加点动画效果可能比较麻烦。。。

    注意保证骨架屏图片体积尽可能小,因为要保证以最快的时间加载出来。

    还有保证图片高度尽量高一点(控制好比例,缩放也可以),保证长手机,能被填满。

    个人理解,骨架屏就是特殊的loading,但是体验比普通loading好很多。

    对于网站来说可能并不太适用,因为要从网络加载图片,极有可能得不偿失,不过控制好图片大小,应该影响不大。

    我们是用IONIC开发混合APP,图片资源可以打入APP本地,加载本地图片很快,但图片大会影响APP体积。

    最后来一张骨架图(其实就是一个截图,哈哈):

    展开全文
  • 来源:花满楼https://zhuanlan.zhihu.com/p/74403911什么是骨架屏?什么是骨架屏呢?骨架屏(Skeleton Screen)是指在页面数据加载完成前,先给...
  • 前端骨架屏

    2019-10-06 10:46:11
    骨架屏 最近在项目不时有用到骨架屏的需求,所以抽时间对骨架屏的方案作了一下调研,骨架屏的实践已经有很多了,也有很多人对自己的方案作了介绍.在这里按照个人的理解做了一个汇总和分类,分享给大家. 关于骨架屏...
  • 相比于早些年前后端代码紧密耦合、后端工程师还得写前端代码的时代,如今已发展到前后端分离,这种开发方式大大提升了前后端项目的可维护性与开发效率,让前后端工程师关注于自己的主...
  • 在加载网络数据时,为了提升用户体验,通常会使用一个转圈圈的loading动画,或者使用Skeleton Screen占位。...骨架结构很简单,只是随意的放几个你喜欢的块级元素就ok了。 你看,就是
  • 先说优缺点,毕竟骨架屏实现的方案有很多种 优点 简单,不需要工程,不用puppeteer生成骨架dom,也不需要二次开发维护 定制程度高,想怎么搞就怎么搞 不臃肿,只给你想要的 缺点 自动化程度低,需要在骨架dom上...
  • 1.骨架屏- skeleton 在页面加载完成之前,页面出现的骨架,有利于性能优化 作用:当网页加载过慢如果是白屏,影响用户体验, 也可以加loding 来防止白屏。但是更好的解决方案就是骨架屏 实现:ui设计图片,当网页...
  • 前端骨架屏注入实践

    2019-07-26 16:00:26
    前端骨架屏注入实践 相比于早些年前后端代码紧密耦合、后端工程师还得写前端代码的时代,如今已发展到前后端分离,这种开发方式大大提升了前后端项目的可维护性与开发效率,让前后端工程师关注于自己的主业。然而在...
  • (马蜂窝技术原创内容,公众号 ID:mfwtech) 一份来自 Akamai 的研究报告显示,在对 1048 名网购户进行...一直以来,为了提升用户在页面加载时的体验,无论是 Web 还是 iOS、Android 的应用中,前端开发工程师都...
  • <!... } /* 加载中阻止事件 */ .skt-loading .skeleton { position: relative; overflow: hidden; border: none !important; border-radius: 5px;... }, 3000) </script> </html> 使用骨架屏
  • 前端骨架屏方案调研

    2021-03-22 21:21:31
    在模版中来实现骨架屏 使用一个Base64的图片来作为骨架屏 使用图片作为骨架屏; 简单暴力,让UI同学花点功夫吧;小米商城的移动端页面采用的就是这个方法,它是使用了一个Base64的图片来作为骨架屏。 使用专门的.vue...
  • 骨架屏在之前是个很热门的概念,现在大部分APP都有骨架屏的应用,即使我们不知道骨架屏是什么,但是一定见识过它的效果。 如上图,骨架屏就是在页面内容加载完成前,以简单的纯色块表现出页面的大致结构。其本意...
  • 二、常见的前端骨架屏方案 在选择骨架屏之前,我们也考虑了一些其他的方法,比如能否通过服务端渲染(SSR)的方式来避开前端白屏时间的问题。但发现需要涉及项目过多,还会涉及服务的构建与部署;或是通过 ...
  • 骨架屏技术讲解以及使用方法写在前面骨架屏实现方式(原理分析)实现方式(具体实现) 写在前面 现在的前端开发领域,都是前后端分离,前端框架主流的都是 SPA,MPA;这就意味着,页面渲染以及等待的白屏时间,成为...
  • 简单,不需要工程,不用puppeteer生成骨架dom,也不需要二次开发维护 定制程度高,想怎么搞就怎么搞 不臃肿,只给你想要的 缺点 自动化程度低,需要在骨架dom上手动添加类 协同要求高,不像工程化能通过工程去约束...
  • 前端普通网站手写实现骨架屏

    千次阅读 2019-01-17 13:33:10
    骨架屏原理: 在等待页面加载 渲染完成之后,在保留页面布局样式的前提下,通过对页面中元素进行删减或增添,对已有元素通过层叠样 式进行覆盖,这样达到在不改变页面布局下,隐藏图片和文字,通过样式覆盖,使得其...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,807
精华内容 1,122
关键字:

前端骨架屏