如何着手网页性能优化

性能优化 2020年2月9日 ~

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

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.