首屏性能优化小案例

最近在帮一个同事看首屏加载慢的问题。以此文做个小记录

目录大纲:

  1. 看首屏性能问题简单步骤介绍
    1. 看资源的加载时间线
      1. 首先了解一下 HTML页面的生命周期
      2. 分析首屏的画面,在什么时候应该被渲染出来?
      3. 优化效果

看首屏性能问题简单步骤介绍

  1. 性能问题,首先会看开发者工具network
  2. 文件体积大小等优化好了后,就开始看资源的加载时间线

看资源的加载时间线

line.png

  1. 首先了解一下 HTML页面的生命周期
    1. DOMContentLoaded(上图蓝色的部分) —— 浏览器已完全加载 HTML,并构建了 DOM 树,但像 <img> 和样式表之类的外部资源可能尚未加载完成。
      DOM 已经就绪,因此处理程序可以开始获取 DOM 节点,并初始化接口。
    2. load(上图红色的部分) —— 浏览器不仅加载完成了 HTML,还加载完成了所有外部资源:图片,样式,字体等。
      外部资源已加载完成,样式、字体已被应用,图片大小也已知了。
    3. beforeunload/unload —— 当用户正在离开页面时。
      beforeunload 事件 —— 用户正在离开:我们可以检查用户是否保存了更改,并询问他是否真的要离开。
      unload 事件 —— 用户几乎已经离开了,但是我们仍然可以启动一些操作,例如发送埋点统计数据。
  2. 分析首屏的画面,在什么时候应该被渲染出来?
    对于vue+webpack工程来说,首屏内容的样式和js都在一个js文件,所以正常情况 DOMContentLoaded 时间,差不多就是页面应该被渲染出来的时间
    看看 “问题”项目的首屏,确实有问题。first paint 比 DOMContentLoaded 时间慢了很多。
    慢了接近1s
    oldShouPing.png
    分析代码发现问题:(app.vue)

    1. <template>
    2. <div id="app">
    3. <router-view></router-view> // 页面都在等 get_menu接口的返回,返回之前都是白屏
    4. </div>
    5. </template>
    • 问题原因:页面都在等 get_menu接口 的返回(因为要鉴权,根据权限来展示对应的menu菜单内容)
    • 优化空间是:可以不用等get_menu接口,先把页面内能渲染的东西先渲染出来,比如先渲染布局:上面header部分(黑色) 和 左面空的menu部分(黑色) 先渲染出来。然后实际页面内容,就等接口返回(这样可以做到,首屏时间,提升到和 DOMContentLoaded 差不多的时间。如图)
      newShouPing.png
      首屏渲染的时间,是788ms和 DOMContentLoaded 时间差不多了。


实际代码操作也很简单(以下是改造app.vue)

  • 先把页面内能渲染的东西先渲染出来,比如 头部和左侧
    1. <template>
    2. <div id="app">
    3. <system-header></system-header> // 头部
    4. <div class="content-wrap">
    5. <system-left></system-left> // 左侧
    6. <div class="right-content">
    7. <router-view></router-view>
    8. </div>
    9. </div>
    10. </div>
    11. </template>
  • 这样做后,还有一个好处是:以后的每次刷新,首屏时间都会更短。甚至刷新后,不会在出现白屏的情况
  1. 优化效果:
    1. 优化前后从1.62s提升到0.788s,提升了1倍多!
    2. 以后的每次刷新,首屏时间都会更短。甚至刷新后,不会在出现白屏的情况

码字不易,点赞鼓励