如何着手网页性能优化

性能优化 2月 09, 2020 ~

1. 简单了解

优化性能我们首先需要了解用户访问页面时发生了什么,这样方便我们定位当前页面的瓶颈在哪,更好的解决问题。

1.1 浏览器展现顺序

a.首次绘制(First Paint,FP)

FP是所有指标中发生的第一个,这个指标表示页面首次绘制的时间点,换句话说它表示当用户第一次看到白屏的时间点,但是他在图层进行绘制的时候触发,而不是文本、图片或 Canvas 出现的时候,所以它通常没有多少意义。标准定义

b.首次内容绘制(First Contentful Paint,FCP)

这是当用户看见一些“内容”元素被绘制在页面上的时间点。和白屏是不一样的,它可以是文本的首次出现,或者 SVG 的首次出现,或者 Canvas 的首次出现等等。如果FCP时间慢,通常有以下两个原因:

  1. 首次下载的资源过于大
  2. 用户网络状况差

c.首次有意义绘制(First Meaningful Paint,FMP)

指页面主要内容出现在屏幕上的时间点,他的计算通常是chromium通过收集所有布局变化,然后计算变化最大的一次所记录下来的时间,这个时间就是FMP如果FMP时间慢,通常有以下两个原因:

  1. 图片、样式、字体、js的资源具有较高的优先级,阻塞了FMP
  2. js的执行时间过长,导致页面关键元素的渲染被推后


d. 首次交互(Time to First Interactive, TTI)

指页面已经准备好并可以使用,chrome的计算通常是需要满足以下条件:

  1. FMP
  2. DOMContentLoaded触发 (domready)
  3. 页面85%以上已经被渲染


1.2 页面生命周期

在浏览器加载的顺序以及页面生命周期中都有可能发现性能问题:如在网络资源加载部分,优先级通常如下:高:CSS、font、同步请求中:JS、Ajax低:image、推迟加载的资源

最终我们在各个阶段中,可以考虑的方案大纲:

2. 优化的指标

每次的优化都需要有指标去量化衡量。优化的目标通常是为了加快对用户的 视觉反馈 & 操作反馈

2.1 视觉反馈

  • 白屏时间
  • 首屏(需要人为定义: 关键图片/文字加载出来的时间)


2.2 操作反馈

  • TTI
  • 资源load完毕


2.3 采集的指标 采集的数据均可从performance Timing API上获取

  • DNS: domainLookupEnd - domainLookupStart
  • TCP :connectEnd - connectStart
  • request:requestEnd - requestStart
  • response:responseEnd - responseStart
  • resource:performance.getEntriesByType('resource')
  • first paint(白屏):
  • performance.getEntriesByType('paint')[0].startTime
  • load.firstPaintTime - load.startLoadTime (chrome中)
  • TTI:domInteractive - navigationStart
  • domReady: domContentLoadedEventEnd - navigationStart
  • onload:loadEventEnd - navigationStart


3. 定位分析

3.1 数据分析

性能方案的制定通常需要与页面的数据分析相结合,所以在每个阶段的优化功能上线,都需要得出优化是正向还是负向,以及优化的预期,可视化监控平台,如:grafana

3.1.1 可视化平台 grafana

分位数: 亦称分位点,是指将一个随机变量的概率分布范围为几个等份的数值点 (百分比的人都在该数据以下)
通过上面两个平台可以看到按照分位数的看大盘的平均情况,但是对于需要得出各时段的分布区间或想查看不同类型下的表现,则需要跑hive数据得出:
3.1.2 数据分析平台

jupyterhub(支持python3在线分析数据)

引入 Pandas库 进行区间的分析(Pandas是Python第三方库,提供高性能易用数据类型和分析工具. )

3.2 性能分析

可以使用一些工具来帮助我们对单个页面进行分析:
3.2.1 Chrome performance

Performance通常可以定位以下问题:

  1. 资源加载顺序
  2. 执行时间
  3. cpu是否占用过高


3.2.2 Lighthouse & Chrome Audits & PageTest

这三类工具是集成性能分析工具,会对页面整体的性能进行分析,同时给出整体优化建议

3.2.3 webpack-bundle-analyzer

在具体项目构建中,可以使用插件对源码使用中的库及第三方插件大小进行分析:优化前:

优化后:

3.2.4 webspeedtest图片分析网站

webspeedtest会根据目前网站使用的图给出可能的优化点

优化前:

优化后:


4.优化方式

在根据对页面的分析以及结合落地页特性,我们给出了以下阶段的方案:

4.1 体积减小

体积减小通常包含三个方面:

  1. 代码体积
  • 组件/库的按需加载(动态import,requre.ensure)
  • split chunk 对js代码进行拆包
  • tree shaking 移除 JavaScript 上下文中的未引用代码(dead-code)
  • lazyload 对于不重要的资源惰性加载
  • 利用peerdependencies / webpack externals排除多个包的共用代码

2. 图片体积

  • 压缩/替换格式 在支持webp格式的手机上使用webp图片
  • 响应式图片 不同设备加载不同宽高的图片,有利于减小体积
  • lazyload 首屏以外的图片懒加载
  • jqeg 渐进式图片 模糊轮廓,渐进清晰

3. 字体体积

  • 预加载
  • 避免艺术字体包


4.2 图片lazyloadlazyload通常有两种方案:

  1. 监听scroll事件,真实地址放在data-src,通过getClientRect实时计算每个dom是否进入视窗,然后替换
  1. IntersectionObserver API

IntersectionObserver需要接收三个参数,root:视窗节点(蓝色部分) rootMargin:距离视窗的多少距离(虚线部分,相当于对视窗的扩充) threshold:交叉比例达到多少时触发回调

4.3 其他手段

  • 延迟 / async 非重要的js执行
  • 利用dns prefetch 并适当增加域名散列
  • http 2 多路复用
  • webworker 独立js线程计算,避免UI阻塞
  • serviceworker离线缓存资源

5. 最后

  • 所有的优化方向只是根据数据分析出来针对现阶段的优化手段
  • 分析页面的特性,页面形式是否一致, 如广告页场景,每个页面都没有共性,加大首屏优化难度
  • 持续对数据的分析,数据时长监控
  • 按资源类型 js, css ,image
  • 按请求类型 http 1.1 http2.0 DNS TTFB
  • 按页面的类型 文字占多数页 / 图片占多数页 / 其他

标签

Cuzz

handsome boy