浅谈Vue项目骨架屏注入实践


Posted in Javascript onAugust 05, 2019

相比于早些年前后端代码紧密耦合、后端工程师还得写前端代码的时代,如今已发展到前后端分离,这种开发方式大大提升了前后端项目的可维护性与开发效率,让前后端工程师关注于自己的主业。然而在带来便利的同时,也带来了一些弊端,比如首屏渲染时间(FCP)因为首屏需要请求更多内容,比原来多了更多HTTP的往返时间(RTT),这造成了白屏,如果白屏时间过长,用户体验会大打折扣,如果用户网速差,则FCP会更长。

由此引申出一系列的优化方法,骨架屏也因此被提出。

1. FCP优化

在 Google 提出的以用户为中心的四个页面性能衡量指标中,FP/FCP可能是开发者们最熟悉的了:

浅谈Vue项目骨架屏注入实践

为了优化首屏渲染时间这个指标,减少白屏时间,前端仔们想了很多办法:

加速或减少HTTP请求损耗 :使用CDN加载公用库,使用强缓存和协商缓存,使用域名收敛,小图片使用Base64代替,使用Get请求代替Post请求,设置 Access-Control-Max-Age 减少预检请求,页面内跳转其他域名或请求其他域名的资源时使用浏览器prefetch预解析等;

延迟加载 :非重要的库、非首屏图片延迟加载,SPA的组件懒加载等;

减少请求内容的体积 :开启服务器Gzip压缩,JS、CSS文件压缩合并,减少cookies大小,SSR直接输出渲染后的HTML等;

浏览器渲染原理 :优化关键渲染路径,尽可能减少阻塞渲染的JS、CSS;

 优化用户等待体验 :白屏使用加载进度条、菊花图、骨架屏代替等;

这里要介绍的就是优化用户等待体验的骨架屏,它可以被视为是原来加载菊花图的一种升级版,结合传统的首屏优化方法对应用进行优化可以达到不错的效果。

2. 骨架屏

骨架屏可以理解为是 当数据还未加载进来前,页面的一个空白版本 ,一个简单的关键渲染路径。可以看一下下面Facebook的骨架屏实现,可以看到在页面完全渲染完成之前,用户会看到一个样式简单,描绘了当前页面的大致框架的骨架屏页面,然后骨架屏中各个占位部分被实际资源完全替换,这个过程中用户会觉得内容正在逐渐加载即将呈现,降低了用户的焦躁情绪,使得加载过程主观上变得流畅。

浅谈Vue项目骨架屏注入实践

可以看一下下面的示例图,第一个为骨架屏,第二个为菊花图,第三个为无优化,可以看到相比于传统的菊花图会在感官上觉得内容出现的流畅而不突兀,体验更加优良。

浅谈Vue项目骨架屏注入实践

如今这项技术已经在Facebook、Google、支付宝、饿了么、简书、新浪微博、知乎、美团、领英等公司的产品中被广泛的使用。在论坛和社区也都有不少文章讨论骨架屏的实现和使用场景等。

3. 生成骨架屏的方法

生成骨架屏的方式主要有:

手写HTML、CSS的方式为目标页定制骨架屏 做法可以参考 <Vue页面骨架屏注入实践> ,主要思路就是使用vue-server-renderer 这个本来用于服务端渲染的插件,用来把我们写的 .vue 文件处理为 HTML ,插入到页面模板的挂载点中,完成骨架屏的注入。这种方式不甚文明,如果页面样式改变了,还得改一遍骨架屏,增加了维护成本。 骨架屏的样式实现参考CodePen

使用图片作为骨架屏; 简单暴力,让UI同学花点功夫吧哈哈;小米商城的移动端页面采用的就是这个方法,它是使用了一个Base64的图片来作为骨架屏。

自动生成并自动插入静态骨架屏 这种方法跟第一种方法类似,不过是自动生成骨架屏,可以关注下饿了么开源的插件page-skeleton-webpack-plugin ,它根据项目中不同的路由页面生成相应的骨架屏页面,并将骨架屏页面通过 webpack 打包到对应的静态路由页面中,不过要注意的是这个插件目前只支持history方式的路由,不支持hash方式,且目前只支持首页的骨架屏,并没有组件级的局部骨架屏实现,作者说以后会有计划实现 (issue9) 。

另外还有个插件 vue-skeleton-webpack-plugin ,它将插入骨架屏的方式由手动改为自动,原理在构建时使用 Vue 预渲染功能,将骨架屏组件的渲染结果 HTML 片段插入 HTML 页面模版的挂载点中,将样式内联到 head 标签中。这个插件可以给单页面的不同路由设置不同的骨架屏,也可以给多页面设置,同时为了开发时调试方便,会将骨架屏作为路由写入router中,可谓是相当体贴了。

vue-skeleton-webpack-plugin 的具体使用参考vue-style-codebase ,主要关注build目录的几个文件,线上Demo 在Chrome的DevTools中把network的网速调为 Gast 3G / Slow 3G 就能看到效果了~

网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 小型打飞机游戏实现原理说明
Oct 28 Javascript
基于jquery的图片幻灯展示源码
Jul 15 Javascript
jQuery检查元素存在性(推荐)
Sep 17 Javascript
Vue实例中生命周期created和mounted的区别详解
Aug 25 Javascript
Node.js 中使用 async 函数的方法
Nov 20 Javascript
vue2.0 路由模式mode=&quot;history&quot;的作用
Oct 18 Javascript
JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例
Dec 14 Javascript
使用layer.msg 时间设置不起作用的解决方法
Sep 12 Javascript
SSM+layUI 根据登录信息显示不同的页面方法
Sep 20 Javascript
vue循环数组改变点击文字的颜色
Oct 14 Javascript
详解vue页面首次加载缓慢原因及解决方案
Nov 06 Javascript
js实现炫酷光感效果
Sep 05 Javascript
基于 vue-skeleton-webpack-plugin 的骨架屏实战
Aug 05 #Javascript
JS 自执行函数原理及用法
Aug 05 #Javascript
jQuery提示框插件SweetAlert用法分析
Aug 05 #jQuery
Nuxt.js实战和配置详解
Aug 05 #Javascript
Vue组件间通信 Vuex的用法解析
Aug 05 #Javascript
前后端常见的几种鉴权方式(小结)
Aug 04 #Javascript
vue的注意规范之v-if 与 v-for 一起使用教程
Aug 04 #Javascript
You might like
使用PHPMailer实现邮件发送代码分享
2014/10/23 PHP
Yii清理缓存的方法
2016/01/06 PHP
PHP递归算法的简单实例
2019/02/28 PHP
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
javascript Window及document对象详细整理
2011/01/12 Javascript
Javascript/Jquery——简单定时器的多种实现方法
2013/07/03 Javascript
jquery中的常用事件bind、hover、toggle等示例介绍
2014/07/21 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
JavaScript显示表单内元素数量的方法
2015/04/02 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
2015/05/04 Javascript
TypeScript 学习笔记之基本类型
2015/06/19 Javascript
jQuery Validate验证表单时多个name相同的元素只验证第一个的解决方法
2016/12/24 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
Node层模拟实现multipart表单的文件上传示例
2018/01/02 Javascript
解决Vue 通过下表修改数组,页面不渲染的问题
2018/03/08 Javascript
详解React Native 屏幕适配(炒鸡简单的方法)
2018/06/11 Javascript
Python使用pymongo模块操作MongoDB的方法示例
2018/07/20 Python
python3结合openpyxl库实现excel操作的实例代码
2018/09/11 Python
python实现顺序表的简单代码
2018/09/28 Python
python遍历文件夹找出文件夹后缀为py的文件方法
2018/10/21 Python
使用python实现抓取腾讯视频所有电影的爬虫
2019/04/15 Python
python绘制动态曲线教程
2020/02/24 Python
python 两个一样的字符串用==结果为false问题的解决
2020/03/12 Python
从0到1使用python开发一个半自动答题小程序的实现
2020/05/12 Python
基于SQLAlchemy实现操作MySQL并执行原生sql语句
2020/06/10 Python
Saucony澳大利亚官网:美国跑鞋品牌,运动鞋中的劳斯莱斯
2018/05/05 全球购物
Java软件工程师综合面试题笔试题
2013/09/08 面试题
初中体育教学反思
2014/01/14 职场文书
材料专业毕业生求职信
2014/02/26 职场文书
学前班幼儿评语大全
2014/12/29 职场文书
停水通知
2015/04/16 职场文书
小学英语课教学反思
2016/02/15 职场文书
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python
Windows安装Anaconda3的方法及使用过程详解
2021/06/11 Python
Python机器学习之底层实现KNN
2021/06/20 Python
nginx从安装到配置详细说明(安装,安全配置,防盗链,动静分离,配置 HTTPS,性能优化)
2022/02/12 Servers