浅谈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 相关文章推荐
js 纯数字不重复排列的另类方法
Jul 17 Javascript
图片无缝滚动代码(向左/向下/向上)
Apr 10 Javascript
JS获取节点的兄弟,父级,子级元素的方法
Jan 09 Javascript
DOM事件阶段以及事件捕获与事件冒泡先后执行顺序(图文详解)
Aug 18 Javascript
jquery专业的导航菜单特效代码分享
Aug 29 Javascript
javascript同步服务器时间和同步倒计时小技巧
Sep 24 Javascript
JS实现放大、缩小及拖拽图片的方法【可兼容IE、火狐】
Aug 23 Javascript
JavaScript事件用法浅析
Oct 31 Javascript
Bootstrap3 多个模态对话框无法显示的解决方案
Feb 23 Javascript
从vue基础开始创建一个简单的增删改查的实例代码(推荐)
Feb 11 Javascript
vue项目强制清除页面缓存的例子
Nov 06 Javascript
uniapp实现可滑动选项卡
Oct 21 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
PHP设计模式之装饰者模式
2012/02/29 PHP
深入解析php之sphinx
2013/05/15 PHP
PHP APC缓存配置、使用详解
2014/03/06 PHP
php微信开发接入
2016/08/27 PHP
Laravel框架自定义公共函数的引入操作示例
2019/04/16 PHP
浅析JS刷新框架中的其他页面 &amp;&amp; JS刷新窗口方法汇总
2013/07/08 Javascript
jquery.qrcode在线生成二维码使用示例
2013/08/21 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
2013/10/23 Javascript
JS实现表格数据各种搜索功能的方法
2015/03/03 Javascript
Javascript优化技巧之短路表达式详细介绍
2015/03/27 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
Bootstrap基本组件学习笔记之分页(12)
2016/12/08 Javascript
AngularJS使用ng-app自动加载bootstrap框架问题分析
2017/01/04 Javascript
AngularJS 教程及实例代码
2017/10/23 Javascript
JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解
2017/10/25 Javascript
webpack源码之loader机制详解
2018/04/06 Javascript
JavaScript使用prototype原型实现的封装继承多态示例
2018/08/31 Javascript
JavaScript函数的4种调用方法实例分析
2019/03/05 Javascript
layui 弹出删除确认界面的实例
2019/09/06 Javascript
vue的三种图片引入方式代码实例
2019/11/19 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
[50:17]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python中的Classes和Metaclasses详解
2015/04/02 Python
Python读取视频的两种方法(imageio和cv2)
2018/04/15 Python
Pandas 解决dataframe的一列进行向下顺移问题
2019/12/27 Python
CSS3中background-clip和background-origin的区别示例介绍
2014/03/10 HTML / CSS
基于HTML5的WebGL经典3D虚拟机房漫游动画
2017/11/15 HTML / CSS
Woolworth官网:澳洲第一大超市
2017/06/25 全球购物
新加坡网上美容店:Hermo新加坡
2019/06/19 全球购物
Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
2015/01/27 面试题
自动化专业个人求职信范文
2013/12/30 职场文书
销售经理岗位职责
2015/01/31 职场文书
任命书标准格式
2015/03/02 职场文书
2015大学生求职信范文
2015/03/20 职场文书
JavaScript高级程序设计之变量与作用域
2021/11/17 Javascript
【海涛DOTA】D-cup邀请赛NV.cn vs DT.Love
2022/04/01 DOTA