Web/前端性能优化

Web/前端性能优化????人不光是靠他生来就拥有一切,而是靠他从学习中所得到的一切来造就自己。——歌德什么是Web性能  一个大型网站架构模型如下图所示,对一个网站的性能进行优化,可以分为Web前端性能优化、应用服务器端性能优化、存储服务器端性能优化三层。网站的整体性能,需要所有开发者一同来维护。  当然,我们重点关注Web性能优化。Web性能其实关注的是页面性能,我们说一个页面的性能如何,是在说页面是否可以快速加载,是否允许用户快速开始与之交互,滚动和动画是否流畅,这些都是我们关心的性能问题。  

🖊 人不光是靠他生来就拥有一切,而是靠他从学习中所得到的一切来造就自己。 —— 歌德

什么是Web性能

  一个大型网站架构模型如下图所示,对一个网站的性能进行优化,可以分为 Web 前端性能优化、应用服务器端性能优化、存储服务器端性能优化三层。网站的整体性能,需要所有开发者一同来维护。
在这里插入图片描述
  当然,我们重点关注Web 性能优化。Web 性能其实关注的是页面性能,我们说一个页面的性能如何,是在说页面是否可以快速加载,是否允许用户快速开始与之交互,滚动和动画是否流畅,这些都是我们关心的性能问题。

  Web 性能包括站在开发者视角可客观度量的性能和站在用户视角主观的可感知的性能。

客观性能

  客观性能是从发出请求开始,到下载、解析和执行所有资源以及最终绘制的整个过程的时间度量。

  • 减少加载时间:页面正常加载过程中所需的文件下载到用户的计算机上需要多长时间,影响因素一般为网络、文件大小、文件数量以及其他因素。一般策略是使文件尽可能小、减少HTTP请求的数量、预加载策略、延迟加载策略。
  • 使网站尽快可用:合理的顺序加载网站资源,让用户能够尽快的可以操作。例如:页面渲染了Input文本框,当初次显示后的短时间内,在用户操作时,应能够可以及时响应用户。
  • 平滑性和交互性:应用程序在流畅方面有很多最佳实践,例如使用 CSS 动画而不是 JavaScript 来制作动画,以及最小化由于 DOM 的更改而导致UI需要的重绘次数。

感知性能

  对于用户来说,用户的感知性能才是最重要的。感知性能是基于加载时间和页面响应性的一个主观指标,衡量一个网站在用户看来有多快,即当网站加载到足以让用户相信它已经加载完毕并且可交互的时候。通俗点说,页面可能不能做得更快,但你可以让用户感觉更快
即使一个页面加载或一个操作响应需要很长时间,也可以通过一些方式让用户觉得没有那么慢。如:

  • 在页面加载或数据请求过程中展示加载信息或加载动画;
  • 在上传文件、解析数据等交互场景时展示进度条;

Web性能的重要性

  用户的操作体验直接影响用户对产品的评价,比较明显的Web性能体验就是大家常常提到的首屏加载时间过长、页面操作卡顿、操作响应迟钝等等。一个Web性能很差的网站会让用户的印象差到极点,往往直接影响产品的销售及产品在市场的竞争力。

  在正常的开发过程中,可能都知道Web性能优化的重要性,以及大概知道Web性能的优化策略。但是很多开发者并不了解为什么要这样优化,这些优化策略对整体的Web性能起到多大的作用,到底优化到什么程度就可以放心了。所以在讨论性能的时候,精确的、可量化的指标很重要。

Web性能指标

RAIL性能模型

  •   官方链接:https://web.dev/rail

      RAIL是Response,Animation,Idle,和Load的首字母缩写,是一种由Google Chrome团队于2015年提出的性能模型,用于提升浏览器的用户体验和性能。
    RAIL模型的理念是“以用户为中心,最终目标不是让您的网站在任何特定设备上都能运行很快,而是使用户满意”。
    在这里插入图片描述
    这个名字的由来使四个英文单词的首字母:

  • 响应(Response):应该尽可能快速的响应用户,应该在100ms以内响应用户输入。
  • 动画(Animation):在展示动画的时候,每一帧应该以16ms进行渲染,这样可以保持动画效果的一致性,并且避免卡顿。
  • 空闲(Idle):当使用Javascript主线程的时候,划分的任务执行时间应该小于50ms,这样可以释放线程以进行用户交互。
  • 加载(Load):应该小于1s的时间内加载完成你的网站,并可以进行用户交互。
      用户对性能延迟的感知不同,这取决于网络条件和硬件。例如,通过快速Wi-Fi连接在功能强大的台式机上加载站点通常需要不到1秒的时间,用户已经习惯了这一点。在3G连接速度较慢的移动设备上加载站点需要更多的时间,因此移动用户通常会更有耐心,在5秒内加载移动站点是一个更现实的目标。

      用户作为之后性能优化的中心,首先需要了解用户对于延迟的反应,用户感知延迟的时间窗口,如下表所示。

延迟时间用户感知
0-16ms用户非常擅长跟踪运动,他们不喜欢动画不流畅的时候。只要每秒渲染60个新帧,他们就会认为动画是平滑的。这是每帧16毫秒,包括浏览器在屏幕上绘制新帧所需的时间,让应用程序生成一帧大约需要10毫秒。
0-100ms对于用户来说还算流畅
100-1000ms用户感觉到明显的延迟
1000ms or more用户已经失去耐心了,用户的注意力会离开对执行任务的关注
10000ms or more用户可能会直接离开,放弃使用

Response: 事件处理最好在50ms内完成

目标

  用户的输入到响应的时间不超过100ms,给用户的感受是瞬间就完成了。

优化方案

  • 事件处理函数在50ms内完成,考虑到idle task的情况,事件会排队,等待时间大概在50ms。适用于click,toggle,starting animations等,不适用于drag和scroll。
  • 复杂的js计算尽可能放在后台,如web worker,避免对用户输入造成阻塞
  • 超过50ms的响应,一定要提供反馈,比如倒计时,进度百分比等
      Idle Task:除了要处理输入事件,浏览器还有其它任务要做,这些任务会占用部分时间,一般情况会花费50ms的时间,输入事件的响应则排在其后。

    下图是idle task对input response的影响:
    在这里插入图片描述

Animation: 在10ms内产生一帧

目标

  • 产生每一帧的时间不要超过10ms,为了保证浏览器60帧每秒,每一帧的时间在16ms左右,但浏览器需要用6ms来渲染每一帧。
  • 旨在视觉上的平滑。用户对帧率变化感知很敏感。

优化方案

  • 在一些高压点上,比如动画,不要去挑战cpu,尽可能地少做事,如:取offset,设置style等操作。尽可能地保证60帧的体验。
  • 在渲染性能上,针对不同的动画做一些特定优化

动画不只是UI的视觉效果,以下行为都属于

  • 视觉动画,如渐隐渐显,tweens,loading等
  • 滚动,包含弹性滚动,松开手指后,滚动会持续一段距离
  • 拖拽,缩放,经常伴随着用户行为

Idle: 最大化空闲时间

目标

  使空闲时间尽量最大化,以此增大50ms内响应用户输入的几率

优化方案

  • 用空闲时间来完成一些延后的工作,如先加载页面可见的部分,然后利用空闲时间加载剩余部分,此处可以使用 requestIdleCallback API(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback )
  • 在空闲时间内执行的任务尽量控制在50ms以内,如果更长的话,会影响input handle的pending时间
  • 如果用户在空闲时间任务进行时进行交互,必须以此为最高优先级,并暂停空闲时间的任务

Load: 传输内容到页面可交互的时间不超过5秒

  如果页面加载比较慢,用户的焦点可能会离开。加载很快的页面,用户平均停留时间会变长,产品的竞争力也会相应提高。

目标

  • 优化加载速度,可以根据设备、网络等条件。目前,比较好的一个方式是,让你的页面在一个中配的3G网络手机上打开时间不超过5秒
  • 对于第二次打开,尽量不超过2秒

优化方案

  • 在手机设备上测试加载性能,选用中配的3G网络(400kb/s,400ms RTT),可以使用 WebPageTest 来测试
  • 要注意的是,即使用户的网络是4G,但因为丢包或者网络波动,可能会比预期的更慢
  • 禁用渲染阻塞的资源,延后加载
  • 可以采用 lazy load,code-splitting 等 其他优化 手段,让第一次加载的资源更少

分析RAIL用的工具

  • Chrome DevTools
  • Lighthouse
  • WebPageTest

常用的性能指标

  Web性能指标有很多,我们这里主要讲我们比较常常用到的指标。

FP指标(First Paint)

  由 Web 性能工作组在 W3C 标准 Paint Timing 中提出。

  定义:从开始加载到浏览器首次绘制像素到屏幕上的时间,也就是页面在屏幕上首次发生视觉变化的时间。但此变化可能是简单的背景色更新或不引人注意的内容,它并不表示页面内容完整性,可能会报告没有任何可见的内容被绘制的时间。
在这里插入图片描述

重点 – FCP指标(First Contentful Paint)

  官方链接:https://web.dev/first-contentful-paint/

  FCP(First Contentful Paint)首次内容绘制,浏览器首次绘制来自DOM的内容的时间,内容必须是文本、图片(包含背景图)、非白色的 canvas 或 SVG,也包括带有正在加载中的 Web 字体的文本。
在这里插入图片描述
  这是用户第一次开始看到页面内容,但仅仅有内容,并不意味着它是有用的内容(例如 Header、导航栏等),也不意味着有用户要消费的内容。

速度指标

FCP时间 颜色编码 FCP分数(HTTP存档百分位数)
0-2s 绿色(快速) 75-100
2-4s 橙色(中等) 50-74
超过4s 红色(慢) 0-49

参考链接及优化办法

  https://web.dev/fcp/#how-to-improve-fcp

FMP(First Meaningful Paint)

  FMP(First Meaningful Paint)首次主要内容绘制,页面的主要内容绘制到屏幕上的时间,这是一个更好的衡量用户感知加载体验的指标,但仍然不理想。

  主要内容的定义因页面而异,例如对于博客文章,它的主要内容是标题和摘要,对于搜索页面,它的主要内容是搜索结果,对于电商的页面,图片则是主要内容。
在这里插入图片描述

速度指标

FMP时间 颜色编码 FMP分数(HTTP存档百分位数)
0-2s 绿色(快速) 75-100
2-4s 橙色(中等) 50-74
超过4s 红色(慢) 0-49

参考链接及优化办法

  https://web.dev/first-meaningful-paint/

重点 – LCP(Largest Contentful Paint)

  LCP(Largest Contentful Paint)最大内容绘制,可视区域中最大的内容元素呈现到屏幕上的时间,用以估算页面的主要内容对用户可见时间。

  由 Web 孵化器社区组(WICG)在 Largest Contentful Paint API 中提出,是一个非标准化的 Web 性能度量。

速度指标

在这里插入图片描述

参考链接及优化办法

  https://web.dev/optimize-lcp/

重点 – FID(First Input Delay)

  FID(First Input Delay)首次输入延迟,从用户第一次与页面交互(例如单击链接、点击按钮等)到浏览器实际能够响应该交互的时间

  FID通常发生在第一次内容绘制(FCP)和可持续交互时间(TTI)之间,因为页面已经呈现了一些内容,但还不能可靠地交互。
在这里插入图片描述

  如上图,浏览器接收到用户输入操作时,主线程正在执行一个耗时较长的任务,处于繁忙的阶段,只能等待此繁忙阶段结束后才能响应用户的输入操作,这个等待的时间就是FID值。

速度指标

在这里插入图片描述

参考链接及优化办法

  https://web.dev/fid/#how-to-improve-fid/

  https://web.dev/optimize-fid/

重点 – TTI(Time to Interactive)

  TTI(Time to Interactive),表示网页第一次完全达到可交互状态的时间点,也可称为可持续交互时间或可流畅交互时间。

  当主线程完成最后一个长任务(Long Task)的时间,并且随后的5秒内网络和主线程是空闲的,这个时间点称为TTI。
在这里插入图片描述

速度指标

TTI指标 颜色编码
0-3.8s 绿色(快速)
3.9-7.3s 橙色(中等)
超过7.3s 红色(慢)

参考链接及优化办法

  https://web.dev/tti/#how-to-improve-tti/

重点 – TBT(Total Block Time)

  TBT(Total Block Time)总阻塞时间,度量FCP和TTI之间的总时间,在该范围内,主线程被阻塞足够长的时间以防止输入响应。

  只要存在长任务,该主线程就会被视为“阻塞”,当任务在主线程上运行超过50ms,我们认为主线程是被阻塞了,因为浏览器无法中断正在执行的任务。因此,用户的操作会被阻塞直到同时期的长任务在主线程中执行完成。

  长任务阻塞时间 = 长任务的执行时间(ms) – 50ms;

  TBT = 所有长任务的阻塞时间之和。

在这里插入图片描述

TBT 与 TTI 有什么关系?

  TBT 是 TTI 的一个出色的配套指标,因为 TBT 有助于量化在页面交互性变为可靠前,不可交互程度的严重性。

  TTI 会在主线程至少有五秒钟没有长任务时,认为页面具备”可靠交互性”。也就是说,分布在 10 秒钟里的三个 51 毫秒长的任务与单个 10 秒长的任务对 TTI 的影响是相同的,但对于试图与页面进行交互的用户来说,这两种情况给人的感觉是截然不同的。

  在第一种情况下,三个 51 毫秒的任务的 TBT 为3 毫秒。而单个 10 秒长的任务的 TBT 为9950 毫秒。第二种情况下较大的 TBT 值对较差的体验进行了量化。

速度指标

TTI指标 颜色编码
0-0.3s 绿色(快速)
0.3-0.6s 橙色(中等)
超过0.6s 红色(慢)

参考链接及优化办法

  https://web.dev/tbt/#how-to-improve-tbt/

重点 – CLS(Cumulative Layout Shift)

  CLS(Cumulative Layout Shift)累计布局偏移,CLS就是在页面整个生命周期中发生的所有单独布局移位的总和,为了保证页面的视觉稳定性从而提升用户体验的指标方案。

  例如,当页面刚加载完成,用户准备去点击页面上的某个位置,当鼠标刚触发事件之前,页面移动了,这个位置刚好出现了一个其他元素(如:图片链接),用户却误触发了其他事件,这个时候的用户是崩溃的。
在这里插入图片描述

速度指标

TTI指标 颜色编码
0-0.1s 绿色 快速)
0.1-0.25s 橙色(中等)
超过0.25s 红色(慢)

参考链接及优化办法

  https://web.dev/cls/#how-to-improve-cls/
  https://web.dev/optimize-cls/

重点 – Speed Index

  Speed Index(速度指数)表示页面可视区域中内容填充速度的指标,可以通过计算页面可视区域内容显示的平均时间来衡量。
在这里插入图片描述

在这里插入图片描述

  Lighthouse 首先捕获浏览器中页面加载的视频,每秒10帧,也就是说100ms截一次屏,并计算帧之间的视觉进展。

速度指标

TTI指标 颜色编码 速度指数得分
0-4.3s 绿色(快速) 75 – 100
4.4-5.8s 橙色(中等) 50 – 74
超过5.8s 红色(慢) 0 – 49

参考链接及优化办法

  https://web.dev/speed-index/#how-to-improve-speed-index/

前端页面的一生

  前端页面的生命周期说简单也简单,说复杂也牵扯到一系列的知识,如HTTP、TCP、网络是怎样连接的等等,前端页面请求过程基本如下:

  1. 对请求进行预处理(如:判断什么协议的请求、安全检查等)
  2. 根据请求URL进行域名解析(根据域名通过DNS查询IP地址)
  3. 通过TCP协议发送HTTP请求
  4. 服务端处理请求并响应
  5. 客户端接收响应并处理响应(HTML渲染、数据渲染、静态资源渲染等)
  6. 断开TCP连接
      这些知识是前端程序员的必修课之一,在这里就对这些知识展开了,如果有兴趣可以查看开发者社区中一些资料,搜索“从URL输入到页面展现到底发生了什么?”。也可以查阅我曾经写的文章《HTTP请求过程详解》。当然,写的文章比较粗糙,并不是很细节,毕竟HTTP、TCP的知识是可以编成一本书的。

优化策略

  具体的优化策略方案详解需要大家自行搜索,这里只提供常用的优化策略大纲

请求和响应优化

  • DNS解析
  • HTTP长连接
  • HTTP2
  • 避免重定向
  • 压缩传输的数据资源
  • 开启HTTP缓存
  • 开启Service Worker缓存
  • CDN缓存
  • Push缓存
  • 使用服务器渲染
  • 使用预渲染

渲染优化

  • 关键渲染路径优化
  • JavaScript执行优化
  • 计算样式优化
  • 页面布局与重绘优化
  • 合成处理

资源加载优化

  • 图片延迟加载
  • 视频加载
  • 路由懒加载
  • 资源优先级

图片优化

  针对图片优化,与其说是优化不如说是在“权衡”。我们平常图片优化都是压缩图片或是选择体积较小的图片格式,这个压缩过程是以牺牲图片质量为代价的,就会导致页面显示时图片失真。因此我们应该尽量寻找一个在质量和性能之间的平衡点。

  不同业务场景下的图片选择方案,使用较为广泛的web图片格式有:JPEG/JPG、PNG、WEBP、Base64、SVG。

  在计算中,像素是采用二进制数来表示,不同的图片格式像素与二进制数的对应关系不同。像素对应的二进制位数越多,则表示的颜色种类越多,成像的效果越细腻,但是文件体积也越大。一个二进制表示两种颜色(0|1对应黑白),一种图片格式对应的二进制位数有N个,那就可以呈现2的N次方种颜色。

JPEG/JPG

  特点:有损压缩,体积小,加载快,不支持透明。

  缺点:在处理一些矢量图形和logo等这些线条感很强、颜色对比强烈的图片时,认为压缩就导致图片模糊非常明显。另外,JPG图像不知此透明度处理,透明图片只能用PNG来呈现了。

  使用场景:JPG适合用于呈现热菜丰富的图片,在日常的开发中,JPG图片经常作为大的背景图、轮播图或是Banner图。比如两大电商网站对大图片的处理,就是对JPG图片应用场景的最佳写照。用JPG来呈现大图片,既可以保留图片的质量,又不会担心图片的体积,是一种比较广泛使用的方案。

PNG-8和PNG-24

  优点::无损压缩、质量高、体积大、支持透明。

  无损压缩的高保真图片格式。8和24都是二进制数的位数,8位的PNG支持256中颜色,24位的PNG可以支持1600万种颜色。在不考虑文件大小只在乎最佳的显示效果时,推荐使用PNG-24。但是在适合使用PNG时会优先选择### PNG-8

  应用场景:主要用PNG来呈现小的LOGO、颜色简单对比强烈的图片或是背景。

SVG

  SVG是一种基于XML语法的图像格式。SVG对图像的处理不是基于像素,而是基于对图像的形状描述。优点是文本文件,体积小,不失真,兼容性好。和JPG、PNG相比较,SVG文件体积更小,可压缩性更强。SVG作为矢量图最大的优点在于图片可以无限放大还不失真,一张SVG图片可以适配多种分辨率。另外SVG是文本文件,可以像写代码一样定义SVG,放在HTML中称为DOM的一部分。也可以把对图像的描述写入以.svg为后缀的文件中,在img标签中引入即可。

base64

  base64对于小图标来说是非常好的一种解决方案,当然前提是网页中图标不多,如果太多,建议使用雪碧图。

雪碧图(CSS Sprites)

  把小图标和背景图像合并到一张图片上,再使用css定位来显示其中的每一部分,就是把多个小图标合成一个图像文件,相对于一个图标一个图像文件来说,单独的一张图片需要的HTTP请求次数更少

WEBP

  2010年被提出,是Google专为WEB开发的一种旨在加快图片加载速度的图片格式,支持有损压缩和无损压缩。

  WEBP受到最大的限制就是浏览器的兼容性。

构建优化

  • 压缩与合并
  • 使用webpack进行资源构建
  • webpack优化性能

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/37114.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注