这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战
前言
本文将结合展厅大屏项目,详细介绍前端性能优化的一些手段。包括减少请求数量、懒加载、缓存、函数去抖(debounce)、初始化加载策略等。
该大屏的内容是比较丰富的,包含大量的图标、动画、地图数据、图表等。
what -- 什么是前端性能优化
从用户访问资源到资源完整的展现在用户面前的过程中,通过技术手段和优化策略,缩短每个步骤的处理时间从而提升整个资源的访问和呈现速度。
why -- 为什么要做前端性能优化
在构建web站点的过程中,任何一个细节都有可能影响网站的访问速度,如果不了解性能优化知识,很多不利网站访问速度的因素会形成累加,从而严重影响网站的性能,导致网站访问速度变慢,用户体验低下,最终导致用户流失。
rule -- 前端性能优化的原则
1、不出bug!
2、具体问题具体分析,根据实际情况因地制宜
3、从浏览器发起请求到页面能正常浏览都有哪些阶段(process)?
预处理——>DNS解析——>建立连接——>发起请求——>等待响应——>接受数据——>处理元素——>布局渲染
vue项目构建前
- 根据交互稿或视觉稿,合理划分pages,一般按照模块和子模块划分;
- 使用路由懒加载,实现模块化与按需加载的效果,优化首屏性能;
- 提取公共组件,尽量与业务隔离,如筛选条件等;
- 提取公共方法,放在util.js中,如表单校验封装;
- 提取在项目中出现较多的功能模块,如弹窗详情等;
- 与后台开发人员定义接口协议,模块中能合并的尽量合并。
vue项目构建中和完成后
- 开启eslint验证,看到错误和警告信息及时解决;
- 打开浏览器调试窗口,查看Network中从发起网页页面请求Request后分析HTTP请求后得到的各个请求资源信息(包括状态、资源类型、大小、所用时间等),可以根据这个进行网络性能优化。如查看哪些http请求返回资源非常大或耗用时间较长,可针对处理;
- 打开浏览器调试窗口,在Timeline中记录并分析在网站的生命周期内所发生的各类事件,以此可以提高网页的运行时间的性能;
- 代码编写过程中不断思考是否可优化模块或做共性组件提取;
- 及时代码审核,提高代码质量
way -- 优化方法(结合项目举例)
减少请求数量
【图片处理】
1、雪碧图
CSS雪碧图是把网站上的一些图片整合到一张单独的图片中,可以减少网站的HTTP请求数量,但是当整合图片比较大时,一次加载比较慢。
2、Base64
将图片的内容以Base64格式内嵌到HTML中,可以减少HTTP请求数量。但是,由于Base64编码用8位字符表示信息中的6个位,所以编码后大小大约比原始值扩大了 33%
3、使用字体图标来代替图片
多维布控大屏设计是比较个性的,没有现成可用的字体图标,因此左侧图标我们还是采取第1种雪碧图的方式来减少http的请求数量。一些控件图标使用字体图标代替图片。
【地图切片处理】
hmap地图是请求hvt图片数据,每个hvt图片大小在使用hmap server 桌面端工具切图时是可配置的,默认值为256,每增大一倍,请求数量可减少至原来的1/4。(原理:边长乘2,面积即原来的4倍)
缺点:切片较大时,地图边缘锯齿明显,影响视觉效果。
综合权衡,在切片时我们采取配置切片大小gridsize为512的方式将地图数据请求减少至默认数量的1/4。
减少重绘回流
【规则动画处理】
该应用中规则变化的动画效果能够使用CSS实现的效果,尽量使用CSS而不使用JS实现。如规律的闪烁,规律的变化如下图。
该动画中用opacity, transform等不触发重绘和回流的属性来降低重绘和回流频率。
【不规则动画处理】
大屏头部光效和中间边框光效轨迹有折线,因此需要使用js来实现。使用requestAnimateFrame让读操作和写操作分离,把所有的写操作放到下一次重新渲染,降低重绘回流的频率,优化渲染。
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
【列表滚动】
页面滚动事件(scroll)的监听函数,使用window.requestAnimationFrame() ,推迟到下一次重新渲染。
$(window).on('scroll', function() {
window.requestAnimationFrame(scrollHandler);
})
【防抖处理】
地图物联资源点位和场所点位资源巨大,因此每次只请求地图可视范围内的点位。当频繁进行缩放拖动会改变可视范围,不断请求数据渲染数据。需要做防抖来限制请求数据方法的频繁触发。
/** * * @param {执行的函数} func * @param {防抖等待时间} wait */
function debounce(func, wait) {
let timer = null
return () => {
if (timer) {
clearTimeout(timer)
timer = setTimeout(func, wait)
} else {
timer = setTimeout(func, wait)
}
}
}
资源加载优化
【懒加载】
由图一可见预警中心左侧预警列表模块有200条预警数据,每条数据都带有图片。但初始化仅展示7条数据,未展示的预警信息不去加载,良好的利用服务器资源。
【资源加载时机】
大屏首页初始化时加载内容较多,其中地图占了一大块面积。因此优先加载地图,等地图渲染结束再加载细节动画,减少等待时间。
this.bus.$on('25dmapLoaded', map => {
// 优先保证地图的加载 帧动画放后面
this.startCanvasAnim()
})
【使用缓存】
从预警中心切换到对象布控时,在构建布控任务阶段可随时取消并返回布控中心,此时使用缓存的地图,无需再次重新加载地图。
总结
性能优化不能按照准则照本宣科的做,需要根据实际情况因地制宜、具体分析、综合权衡。本文通过具体的大屏应用项目举例讲述具体优化分析过程,希望能给大家在项目开发、优化带来一些启发。