# 性能指标
三大核心指标:
- LCP:页面速度指标
- FID:交互体验指标
- CLS:页面稳定指标
# FP&FCP
FP (First Paint) 首次绘制,记录页面第一次绘制像素的时间
FCP(First Contentful Paint) 首次内容绘制,记录页面首次绘制文本、图片、非空白Canvas或SVG的时间
FP<=FCP
# LCP
Largest Contentful Paint,最大内容绘制,用于记录视窗内最大的元素绘制的时间,会随着页面渲染变化而变化,会在用户第一次交互后停止记录
# TTI
Time to Interactive首次可交互时间
- 从FCP后开始计算
- 持续秒内无长任务,且无两个以上进行中的GET请求
- 往前回溯至5秒前的最后一个长任务结束的时间
# FID
First Input Delay,首次输入延迟,用户首次与页面交互到浏览器实际响应该事件的时间
用户交互事件触发到页面响应中间耗时多少,推荐100ms以内
# TBT
Total Blocking Time,阻塞总时间。记录FCP到TTI之间所有长任务的阻塞时间总和
长任务(执行时间大于50ms)
每个长任务的阻塞时间=执行时间-50ms
# CLS
Cumulative Layout Shift ,累计位移偏移,记录了页面上非预期的位移波动
页面渲染过程中突然插入巨大的图片等等
计算方式:位移影响的面积*位移距离,用屏幕面积百分比表示
推荐值低于0.1
# 获取指标工具
- lighthouse
- web-vitals-extension Chrome插件
- Chrome Devtools的Performance选项卡
# 页面的渲染过程
输入网址、解析URL、检查浏览器缓存、DNS解析、TCP/IP解析、HTTP请求、服务器请求并返回http报文、浏览器渲染页面、断开连接
# 输入网址
用户输入查询关键词时,地址栏会判断输入的是关键字是搜索内容还是URL
- 如果是搜索内容,会合成带搜索关键字的URL
- 如果符合URL,会添加协议合称为完整的URL
# 解析URL
协议、主机、端口、路径、查询参数、锚点
# DNS解析
获取目标网页IP地址的过程
- 先递归查询DNS缓存
- 查询根域名服务器
- 查询com顶级域名服务器
- 查询google.com域名服务器
- 查询结果缓存
优化:
- DNS预解析:有多个不同的服务器资源时,可提前解析,避免卡顿
- DNS负载均衡:把访问引导到不同的服务器上
# TCP/IP连接
三次握手的过程
# 检查浏览器缓存(补充)
网络进程会查找本地缓存是否缓存了该资源,如果有,直接返回给浏览器进程。
浏览器缓存:
- 浏览器发送请求,会根据请求头expires和cache-control判断是否命中强缓存策略
- 未命中,会发送请求,根据If-Modified-Since和If-None-Match判断是否命中协商缓存
- 离线缓存,service worker
第三方库公共模块抽取:
- 设置较长的强缓存时间
# HTTP请求(重点看)
建立连接之后,浏览器会构建请求行、请求头等信息,并把cookie数据附加到请求头,然后发送请求。
开启HTTP2:
- HTTP1用文本,HTTP2用二进制分帧通信
- HTTP2可以多路复用,HTTP1会有并发限制
- HTTP2可以头部压缩,节省消息头占用的网络流量
- HTTP2可以服务端推送
# 服务器请求并返回http报文
# 浏览器渲染页面
# DOM树
字节->字符->令牌->节点->对象模型
构建流程:
- 转换:根据HTML原始字节,根据指定编码转换为字符 √
- 令牌化:将字符串转换为H5标准的各种令牌,从而识别每个元素 √
- 词法分析:发出的令牌转换为定义属性和规则的对象 √
- DOM构建:构建树结构 √
# CSS对象模型
构建过程:
- 解析CSS样式表:浏览器加载CSS样式后,会解析成一组样式规则
- 创建StyleSheet对象,表示整个样式表 √
- 创建CSSRule对象,表示样式规则,包括选择器和声明块 √
- 创建CSSStyleDeclaration声明块对象,表示声明块、样式属性和值
- 构建CSSOM树
CSSOM的每个节点代表一个CSS规则,包括选择器和声明块
# 布局树Layout Tree
- DOM树和CSSOM树合并形成渲染树 √
- 渲染树只包含网页所需的节点
- 布局计算每个对象精确位置和大小 √
- 使用最终渲染树将像素渲染在屏幕上 √
# 渲染
渲染流程:
- 获取DOM后分割为多个图层,通过浏览器Layer图层查看 √ 以下情况浏览器会将其分配到单个图层:
- 应用CSS 3D变换和透视属性
- 视频、canvas和webgl元素,动态更新
- 具有滚动、动画和滑动效果的元素,频繁重绘
- 对每个图层的节点计算样式结果 √
- 为每个节点生成图形和位置 √
- 将每个节点绘制填充到图层位图中
- 图层作为纹理上传至GPU
- 组合多个图层到页面上生成最终图像
# 回流和重绘
- 重绘
页面中元素样式改变不影响在文档流中的位置时,例如color,bgc,visibility等等,浏览器会将新的样式赋予该元素并重新绘制。
- 回流
当渲染树中部分或者全部元素的尺寸、结构、或者某些属性发生改变时,浏览器重新渲染部分或全部文档的过程成为回流。
引起回流的方式:(页面排版发生了变化)
- 页面首次渲染 √
- 浏览器窗口大小发生变化 √
- 元素尺寸或者位置发生变化 √
- 元素内容和字体变化 √
- 添加、删除DOM √
- 激活CSS伪类
- 查询某些属性或调用某些方法
引起回流的属性和方法:
- clientWidth、clientHeight、clientTop、clientLeft
- offsetWidth、offsetHeight、offsetTop、offsetLeft
- scrollWidth、scrollHeight、scrollTop、scrollLeft
- scrollIntoView()、scrollIntoViewIffNeeded()
- getComputedStyle()
- getBoundingClientRect()
- scrollTo()
# 性能优化(雅虎军规)
# 页面内容
# 减少HTTP请求数
- 合并JS/CSS文件 √
- 使用CSS Sprite将背景图片合并成一个文件√
- 行内图片,使用Data URI scheme将图片嵌入HTML和CSS,用于小图标、小图片等等
# 减少DNS查询
- 配置DNS缓存
- 减少不同主机名,避免DNS查找。但是会减少并行下载数量,会增加响应时间。将组件分散在2-4个主机名下。
# 避免重定向
重定向是指用户在访问一个网址时,服务器会将用户的请求重定向到另一个网址的过程。
重定向方式:
- 永久重定向 301
- 临时重定向 302
- JS重定向,window.location.href
- Meta Refresh
发生重定向的场景:
- URL末尾的/并未添加
- 网站域名变更
# 缓存Ajax请求
- 服务器端通过设置HTTP相应头来控制缓存cache-control,expires
no-cache:表示不使用缓存
no-store:不缓存响应内容,也不允许缓存设备缓存响应内容
max-age(单位为秒):缓存响应内容的最大时间
must-revalidate:缓存过期后,缓存设备需要向服务器发送请求
public:响应内容可以被任何缓存设备缓存
private:只能被客户端缓存
- 浏览器本地缓存
# 延迟加载
- 非首屏使用的数据、样式、脚本、图片
- 用户交互才会显示的内容
# 预加载
使用浏览器的空闲时间请求将来要使用的资源
- 无条件预先加载
- 有条件预加载:根据用户行为判断
# 减少DOM元素的数量
移除不必要的标记:
- 是否还在使用表格布局?
- 使用div仅仅为了解决布局问题,也需要更好、更语义化的标记
- 能通过伪元素实现的功能,就没必要添加额外元素
# 减少iframe的使用
ifame优点:
- 加载速度较慢的第三方资源,如广告、徽章
- 安全沙箱
- 可以并行下载脚本
iframe缺点:
- 加载代价昂贵
- 阻塞页面load事件触发
- 无法获取外层页面的DOM元素
# 服务器
# 使用CDN
用户与服务器的距离影响响应时间,使用CDN可以提升加载速度
# 添加Expires或Cache-Control响应头
- 静态内容:永不过期
- 动态内容,有条件发起请求
# 启用Gzip
Gzip压缩通常可以减少70%的响应大小,可以对HTML、CSS、JS、XML、JSON等文本类型。
# 配置Etag
# Cookie
- 减少cookie大小
- 去除不必要的cookie
- 设置合适的过期时间
- 注意设置cookie的domain级别
静态资源无需使用cookie
# CSS
- 把样式表放在中
- 不要使用css表达式
- 使用link代替@import
# Javascript
- 把脚本放在页面底部
- 使用外部的Js和Css
- 压缩JS和CSS
- 移除重复脚本
- 使用高效的事件处理,事件委托,尽早处理事件
# 图片
- 优化图片,GIF转PNG
- 优化CSS Sprite,水平排列Sprite的图片,Sprite图像中间不要有较大空隙
- 不要在HTML中缩放图片,使用相应大小的图片
- 使用体积小可缓存的favicon.ico
# 移动端
- 保证组件都小于25k
- 打包内容为分段文档
← ♥性能优化♥