性能与用户紧紧相关,如何让用户觉得页面展示的快,页面渲染不卡顿,这是我们应该思考要做的事情。
资源加载优化
资源越快加载完成,用户就能越快的看到页面,随着社会的发展,手机越来越好,网络也越来越快,但是,不要轻易忽视用户真实的网络环境。我们所做的任何优化,都有它的价值。
1、依赖资源拆分
项目中引入多个依赖包,比如echarts、html2canvas、swiper等等,这些依赖在项目中如果合并到一个文件里面的时候,就会导致这个文件特别大,请求时间也会很长,所以要根据自己项目情况,进行自定义拆包处理。
2、异步加载资源
异步加载路由文件、部分组件往往都能起到让用户更快看到页面内容的效果。
3、图片资源压缩、大小、格式的合理使用
选择合适的图片大小,往往是容易忽略的事情,但是,图片大小又紧紧与性能相关,比如明明120 * 120像素的图片完全可以使用,却选择使用360 * 360的图片...
图片格式不仅仅只有png、jpg格式,同样内容的图片,选择webp格式的图片,往往能大大的减少图片的大小。
从设计师拿到的图片,也可以根据情况选择压缩(tinypng)
4、特殊字体的文件使用
项目中往往出现一些特殊字体展示的时候,很容易想着用一张切图进行展示,但是,如果能够拿到对应字体的文件,进行所需字体的提取(fontmin),也能减少资源大小的请求。
5、资源缓存(ServiceWorker)
适当的时候,可以考虑使用ServiceWorker选择性的进行文件缓存,不仅仅只考虑在离线场景中才去使用ServiceWorker。
渲染优化
1、骨架屏
骨架屏的使用,会在一定程度上减少了用户等待焦虑
2、渲染阻塞
js因为可以修改dom的原因,存在影响dom tree的构建。
- 内联
JS的执行会阻塞关键渲染路径,所以需要留意内联js的书写位置 - 使用
async defer属性可以帮助外链形式引入JS的加载、执行不去阻塞关键渲染路径
内联的 CSS 已经在 HTML 中一同返回,所有不会对 DOM 构建产生影响。
如果 CSS 通过外链引入,即使 CSS 不阻塞 DOM 构建,但在 CSS 加载完成之前都无法进行 CSSOM 构建也就无法进行渲染树的构建,从而导致阻塞关键渲染流程。
CSS 会阻塞渲染树的构建和他后面的 JS 执行,JS 的执行和 DOM 构建又是相互阻塞的。
那么CSS 为什么需要在页面头部?
CSS 不会阻塞 DOM 构建,但却会阻塞渲染树构建,从而阻塞布局影响关键渲染流程。
如果将 CSS 放在页面中间或者底部,CSS 不会阻塞 DOM 构建,已经解析完成的内容会被渲染出来。
这时一旦 CSS 加载完成页面则会重新渲染,可能造成页面变化。一方面不必要的重新渲染造成额外的性能负担,另一方面页面的变化体验也非常不好。
所以将重要的 CSS 资源放在页面头部,尽早开始加载,减少网络请求上阻塞的时间,避免页面阻塞提高渲染效率。
另外对于体积较大的 CSS 资源建议以外部链接的方式加载,这样则能充分利用缓存减少请求时间。
JS 为什么需要在页面底部?
script 标签在不设置 async、defer 属性的情况下,会阻塞 DOM 构建。
如果将这样的 script 标签放在页面头部,在没有加载完成的情况下不会解析 script 后面的 HTML 内容,直到 JS 加载执行完成页面都会一直显示空白,体验非常不好。
将 JS 放在页面底部则不会有这样的问题,即使浏览器解析 HTML 在底部被阻塞了 script 标签之前的内容依然可以显示,用户依然能在第一时间看到完整的页面。
如果有了 async、derfer 属性之后,script 标签的位置已经不是那么重要了。
硬件加速优化
1、合成层优化
渲染引擎在绘制页面的内容,会对页面内容进行分层处理,然后再进行绘制,如果页面里的一个区域,展示过程中如果会经常变化的情况下,可以考虑使用提升此处为一个图层的手段,会减少内存memory estimate的占用,包括对别的内容影响。
拥有层叠上下文属性的元素会被提升为单独的一层。
明确定位属性的元素、定义透明属性的元素、使用 CSS 滤镜的元素等,都拥有层叠上下文属性。
需要剪裁(clip)的地方也会被创建为图层。
2、动画性能
根据经验实现动画效果,留意动画效果的绘制次数paint count,也是一个很好的优化手段。
新特性使用
1、content-visibility
借助 content-visibility 属性可以跳过离屏内容的渲染,加快用户首屏渲染时间。
content-visibility: auto
contain-intrinsic-size: 500px // 可以解决只使用content-visibility,导致页面在滚动过程中滚动条一直抖动
2、intersection Observer
经典场景,监听页面滚动距离,然后实现对应效果。但是这个的确容易消耗内存,不如使用intersection Observer监听元素位置。
页面性能面板
在谷歌浏览器中,有很多面板可以帮我们分析页面性能。比如:Networt面板(查看资源加载情况)、
Performace面板(查看页面渲染情况)、Rendering(查看页面性能核心指标)、Layers(页面分层情况)...这一部分,后续详情整理一下。