首屏性能优化小案例
最近在帮一个同事看首屏加载慢的问题。以此文做个小记录
目录大纲:
- 看首屏性能问题简单步骤介绍
- 看资源的加载时间线
- 首先了解一下 HTML页面的生命周期
- 分析首屏的画面,在什么时候应该被渲染出来?
- 优化效果
- 看资源的加载时间线
看首屏性能问题简单步骤介绍
- 性能问题,首先会看开发者工具network
- 文件体积大小等优化好了后,就开始看资源的加载时间线
看资源的加载时间线
- 首先了解一下 HTML页面的生命周期
DOMContentLoaded
(上图蓝色的部分) —— 浏览器已完全加载 HTML,并构建了 DOM 树,但像<img>
和样式表之类的外部资源可能尚未加载完成。
DOM 已经就绪,因此处理程序可以开始获取 DOM 节点,并初始化接口。load
(上图红色的部分) —— 浏览器不仅加载完成了 HTML,还加载完成了所有外部资源:图片,样式,字体等。
外部资源已加载完成,样式、字体已被应用,图片大小也已知了。beforeunload/unload
—— 当用户正在离开页面时。beforeunload
事件 —— 用户正在离开:我们可以检查用户是否保存了更改,并询问他是否真的要离开。unload
事件 —— 用户几乎已经离开了,但是我们仍然可以启动一些操作,例如发送埋点统计数据。
分析首屏的画面,在什么时候应该被渲染出来?
对于vue+webpack工程来说,首屏内容的样式和js都在一个js文件,所以正常情况 DOMContentLoaded 时间,差不多就是页面应该被渲染出来的时间
看看 “问题”项目的首屏,确实有问题。first paint 比 DOMContentLoaded 时间慢了很多。
慢了接近1s
分析代码发现问题:(app.vue)<template>
<div id="app">
<router-view></router-view> // 页面都在等 get_menu接口的返回,返回之前都是白屏
</div>
</template>
- 问题原因:页面都在等 get_menu接口 的返回(因为要鉴权,根据权限来展示对应的menu菜单内容)
- 优化空间是:可以不用等get_menu接口,先把页面内能渲染的东西先渲染出来,比如先渲染布局:上面header部分(黑色) 和 左面空的menu部分(黑色) 先渲染出来。然后实际页面内容,就等接口返回(这样可以做到,首屏时间,提升到和 DOMContentLoaded 差不多的时间。如图)
首屏渲染的时间,是788ms和 DOMContentLoaded 时间差不多了。
实际代码操作也很简单(以下是改造app.vue)
- 先把页面内能渲染的东西先渲染出来,比如 头部和左侧
<template>
<div id="app">
<system-header></system-header> // 头部
<div class="content-wrap">
<system-left></system-left> // 左侧
<div class="right-content">
<router-view></router-view>
</div>
</div>
</div>
</template>
- 这样做后,还有一个好处是:以后的每次刷新,首屏时间都会更短。甚至刷新后,不会在出现白屏的情况
- 优化效果:
- 优化前后从1.62s提升到0.788s,提升了1倍多!
- 以后的每次刷新,首屏时间都会更短。甚至刷新后,不会在出现白屏的情况
码字不易,点赞鼓励