Web 核心指标优化之 INP 篇

news2024/11/30 10:56:33

这篇文章是我在公司做 INP 优化经验分享的演讲稿。

大家好,今天我要做的分享是关于 INP 的一些优化经验。

概念

首先,什么叫 INP 呢。 INP 的全称叫 Interaction to Next Pain ,翻译过来就是从交互到下一次绘制的延迟。这是 Google 提出来的一个衡量 Web 用户体验的指标。衡量一个 Web 页面体验和质量的指标有很多,为了帮助开发者专注于重要的用户体验指标,同时也为了降低学习成本,Google 提出了一套关键指标,叫 Core Web Vitals:

在这里插入图片描述

分别从加载性能、交互体验和视觉稳定性三个维度来衡量用户体验,其中 INP 就是衡量交互体验的指标。

在浏览器中,渲染引擎在每一帧都有机会渲染页面。假设你的显示器是 60 Hz,那么浏览器每秒可以渲染 60 次,每次渲染间隔时间大约就是 16.7ms。但是如果浏览器其他任务执行时间过长,导致迟迟无法执行渲染,就会给用户造成网页响应速度不够快的印象。

INP 就是算从用户触发交互到浏览器下一次绘制被阻塞的时间,如果说阻塞时间小于200ms,那么算得分良好。

这里要强调一下, INP 算的是浏览器下一次绘制的延迟,并不是算当前交互结果绘制的延迟。比如有些异步操作(调接口等),虽然等待时间较长,但是如果没有影响到浏览器的下一次绘制,那么不会影响 INP 结果。

一次交互可分为以下 3 个阶段:

  1. 输入延时(Input Delay)= 交互事件回调开始运行时 - 用户发起与页面的交互时

  2. 事件处理(Processing Time)= 事件回调运行完成时 - 事件回调运行开始时

  3. 渲染延时(Presentation Delay)= 浏览器显示包含交互的可视结果的下一帧渲染时 - 事件回调运行完成时

在这里插入图片描述

根据 Google 官方文档的说明, INP 的计算方式是:对于大多数网站(互动次数不超过 50 次)来说,用户和网页所有的互动中,延迟时间最长的互动会被报告为本次浏览的 INP ,然后系统会取所有网页浏览量的第 75 百分位作为网页的 INP。而对于有大量互动的网站,Google 会忽略每 50 次互动中最高的一次互动。

目前会被观察用于记录 INP 的互动类型有:

  • 鼠标点击

  • 触摸屏点按

  • 实体键盘或屏幕键盘的按键

接下来我会从如何发现问题、如何定位问题以及如何解决问题三个阶段来阐述,我们在处理 INP 问题上的工作流程是怎样的。

如何发现问题

人为巡检

首先在前端团队内部,每周会有人对线上指标做定期巡检,大家每周都会收到一封关于核心指标状况报告的邮件,在邮件上汇总了各个业务线关键页面的核心指标状况,然后我们在邮件上就可以看到哪些页面的指标可能是不太健康的。

监控告警

其次在公司内部的监控系统看板上,我们也可以自行查阅具体页面的核心指标状态。然后 Sentry 也提供了监控 INP 的功能,而且还有针对 FID 的告警功能。 FID 叫 First Input Delay ,是一个记录第一次交互行为的指标,算作 INP 的前身,大家如果有需要的话可以自行配置。

如何定位问题

然后来讲一下就是当我们发现页面的 INP 指标偏高的时候,要怎么去定位到底是具体哪一个交互导致页面的 INP 值偏高。

Chrome 插件 Web Vitals

首先我们最常用到的是 Google 的一个插件叫 web vitals 。当我们在界面上进行一些交互操作的时候,比如我点了一个按钮,这个插件就会在控制台打印出该交互的 INP 值,还有交互分别在输入、事件处理和渲染阶段的耗时。

在这里插入图片描述

在这里插入图片描述

一般我们定位 INP 问题就是通过在界面上自行做一些交互操作,然后看看哪些交互操作的 INP 值是偏高的。

Chrome DevTools - Performance 面板

假设我们已经发现某个操作它的 INP 值偏高,那我们该怎么去分析原因呢?我们可以借助 Google 开发者工具的 Performance 面板来分析。

在这里插入图片描述

首先对一次交互进行录制,然后它会以堆栈的形式帮你列出来任务的执行形容,而且会根据耗时从高到低排列任务,在任务列表的右边还会标出任务所属文件,点开文件就可以看具体是哪一段代码执行耗时。

这里我还要补充一点,因为大部分开发者电脑性能配置都很好,但其实我们的用户他们的设备性能是非常不统一的,尤其是移动端会面临户外各种复杂网络环境的情况。 Performance 面板有 CPU 和 Network 两个选项,我们可以通过设置这两个选项来模拟用户的使用场景。

在这里插入图片描述

一般我们可以先设置 CPU 慢速的场景,看看 INP 值是否正常,如果说这时候 INP 指标正常,那么大概率是网络问题,然后我们再设置 Network 慢速的场景。

如何解决问题

接下来讲一下关于优化 INP 的一些思路。在最开始我们介绍过一次交互分为输入、任务执行和渲染三个阶段,我们优化的时候就是分别针对这三个阶段去做优化。

减少输入延迟

第一个输入阶段,我们要如何减少输入的延迟呢?

减少影响输入的长任务

如果当用户输入的时候有一个很长的任务,它占领了主线程,那么这个任务就会导致主线程的一个阻塞,然后从用户输入到触发时间回调的这个过程就会变得很长。所以说我们要尽量减少这种影响用户输入的长任务,我们可以把任务做一下切分,把它拆成更小颗粒度的任务。如果说一些任务它的执行优先级不那么高,我们可以放到后面再执行。

在这里插入图片描述

避免交互重叠

然后还有一个我们要做的,就是避免交互重叠。交互重叠的意思是说当用户完成了一个交互以后,本来浏览器要渲染这个交互的结果,但是这时候又产生了一个新的交互,这就叫交互重叠。之所以交互重叠对输入有影响是因为渲染第一次交互结果的时候会导致第二次交互的输入产生延迟。

在这里插入图片描述

这种情况我们可以通过防抖或者节流来控制用户触发输入事件的频率。

优化任务执行效率

然后来看看怎么优化任务执行效率。

优化代码逻辑

其实我们要优化任务执行效率,就是要对我们的代码逻辑做一个梳理,尽可能地减少冗余代码,还有一些不重要的任务我们可以放到下一个事件循环去执行,还有就是一些非常大型的任务,我们要对它做更小颗粒度的拆分。这里以下图的点击筛选查看结果为例:

在这里插入图片描述

这个交互简单来说就是用户点击了筛选弹窗右下角的“查看结果”按钮,然后弹窗会收起并在页面上展示筛选结果。

这个交互在优化前的代码执行流程是👇🏻这样的:

在这里插入图片描述

就是说我点了筛选项,然后前端会根据筛选项去调接口获取搜索结果。当用户点了筛选弹窗右下角的“查看结果”按钮,首先前端会记录弹窗内用户选中的筛选项数据,这样做的目的是为了让用户下次打开弹窗的时候会展示上一次选择的选项。然后就是关闭弹窗,然后再去行一个叫 updatePageData 的方法,这个方法主要就是更新页面数据,然后就是结束。

那么这一整个执行逻辑,它的执行过程有什么问题呢?

首先我们可以看到一整个执行流程它都是同步执行的。但其实有一些任务它的执行优先级并不那么高,它其实可以放到下一个事件循环去做。就比如“弹窗内记录筛选项数据“这一步,因为记录数据是为了下一次打开弹窗服务的,不一定马上就要做这件事,所以这一步其实可以放到下一个时间循环。

还有我们可以看到有一个很大的方法叫 updatePageData ,这个方法里面做了很多的事情,那为什么这个方法这么大呢?主要是因为这个方法被应用到了多个场景,比如页面初始化的时候会执行 updatePageData 方法、点击筛选项的时候也会执行 updatePageData 方法。所以这个方法相当于是把多个交互要执行的任务取了一个并集。但是对于单个交互比如我们举例的“查看结果”来说,其实 updatePageData 里的很多任务是不需要执行的。

那么我们就是要对这个大型的方法做一个更小颗粒度的拆分,然后根据具体的场景再对这些小任务做一个组合。

然后还有一个就是冗余问题。比如更新界面的时候会滚动到界面顶部,但如果页面本身就在顶部那么就没必要去操作 DOM 。

这个交互在优化后的代码执行流程是👇🏻这样的:

在这里插入图片描述

可以看到整个任务执行流程短了很多。

善用任务拆解API

然后呢我要讲一下,其实浏览器提供了很多可用于任务拆解的 API 。比如最常见的是 setTimeout ,它可以把某个任务放到下一个事件循环去执行,这样就可以把当前主线程让出来,去做一些更重要的事。

不过 setTimeout 本身的用意是延迟执行某些逻辑,它并不是专门用来做任务拆解的。浏览器提供了一些专门用来做任务拆解的 API ,比如 requestIdleCallback 、requestAnimationFrame 这些,还有最近新出的 scheduler.yidld 。

在这里插入图片描述

减少渲染延时

接下来我们讲讲如何减少渲染延时。

资源缓存

首先我们可以对一些静态资源做缓存,比如图片、图标这些做一下 CDN 缓存,这样就是尽快地去加载页面的一些内容。

尽早让用户得到交互反馈

还有就是我们要尽早地让用户得到交互反馈。比如展示日历弹窗的时候,可能有很多跟日期相关的计算逻辑,需要等到逻辑处理完毕才能展示日历。那么这个时候我们可以在打开弹窗的时候先让用户看到一个 loading 的样式,等逻辑处理完毕再展示日历。

还有一种情况就是某个子组件,它要展示的数据依赖于外部 props 的传入。比如用户在子组件内执行了某些操作产生了新的值,一般我们写代码的逻辑都是先在子组件内部调用 $emit 方法把新值传给父组件,然后父组件更新 props 把值再传给子组件,然后子组件再根据新值去渲染内容。

那么这个执行流程是很长的。我们可以在子组件内定义一个内部变量,当用户在子组件内执行操作产生新值的时候,我们可以先用内部变量在子组件内渲染新的内容,然后再去通知父组件更新 props 。因为对当前操作来说,最重要的是让用户看到他的操作结果,通知父组件更新这件事情更不重要。

<klk-date-picker :date="innerDate" @change="handleChange" />

<script>
export default class DateModal extends Vue {
    @Prop({ type: Object, default: () => null }) date!: any
    
    @Watch('date')
    onDateChange(val) {
        this.innerDate = val
    }
    
    handleChange(val) {
        // 先更新交互结果,再通知父组件
        this.innerDate = val
        setTimeout(() => {
            this.$emit('change', val)
        })
    }
}
</script>

避免渲染大型DOM

减少渲染延时还有一种方法是避免渲染一些大型 DOM 。就是我们要优先渲染在可见区域内的 DOM ,这里我们可以用到虚拟列表或者 CSS 的一个属性叫做 content-visibility 来延迟渲染可视区域外的 DOM 。

结语

最后,用户体验一直是前端开发者需要重点关注的领域,但是用户体验其实是一个比较抽象的概念,Web 关键指标就是去量化了这个抽象的概念。这样不仅降低了开发者的理解成本,而且也量化了前端开发者的工作产出。通过关键指标,我们知道了优化用户体验的一个方向。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2225925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#与C++互操作时的数据类型对应

C#和C在互操作时&#xff0c;会涉及到数据类型对应的问题&#xff0c;如果数据类型用得不对&#xff0c;就会得不到想要的结果&#xff0c;严重的情况下&#xff0c;可能还会导致程序崩溃。这里做一下相关知识点的总结。 说明&#xff1a; 1. 表格第一列是Visual C中的数据类型…

【Docker大揭秘】

Docker 调试一天的血与泪的教训&#xff1a;设备条件&#xff1a;对应的build preparation相应的报错以及修改 作为记录 构建FASTLIO2启动docker获取镜像列出镜像运行containerdocker中实现宿主机与container中的文件互传 调试一天的血与泪的教训&#xff1a; 在DOCKER中跑通F…

numpy——数学运算

一、标量——矢量 import numpy as npa 3.14 b np.array([[9, 5], [2, 7]])print(a) print(b)# ---------- 四则运算 ---------- print(a b) # np.add print(a - b) # np.subtract print(a * b) # np.multiply print(a / b) # np.divide 二、矢量——矢量 import nump…

Claude Financial Data Analyst:基于Claude的金融数据分析工具!免费开源!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

MPC模型预测控制与RL强化学习的差异性

模型预测控制&#xff08;Model Predict Control&#xff0c;MPC&#xff09; 模型预测控制与强化学习的差异性调研 概述 MPC 是一种使用数学模型在有限时间内实时优化控制系统的技术&#xff0c;自二十世纪六七十年代问世以来&#xff0c;已广泛应用于化学工程、炼油、先进…

Java:String类(超详解!)

一.常用方法 &#x1f94f;1.字符串构造 字符串构造有三种方法&#xff1a; &#x1f4cc;注意&#xff1a; 1. String是引用类型&#xff0c;内部并不存储字符串本身 如果String是一个引用那么s1和s3应该指向同一个内容&#xff0c;s1和s2是相等的&#xff0c;应该输出两…

《深度学习》模型的部署、web框架 服务端及客户端案例

目录 一、模型的部署 1、模型部署的定义与目的 1&#xff09;定义 2&#xff09;目的 2、模型部署的步骤 1&#xff09;导出模型 2&#xff09; 部署模型 3&#xff09;测试模型 4&#xff09;监控模型 3、模型部署的方式 1&#xff09;云端部署 2&#xff09;嵌入…

autMan奥特曼机器人-对接Docker版本NTQQ详细教程

准备 1、准备一台服务器&#xff0c;amd64/arm64都可以&#xff0c;配置最好还是2核保底吧。 2、准备一个VNC软件。1Remote&#xff1a;点此下载 3、准备手机登陆机器人QQ号&#xff0c;扫码 NTQQ相关 NTQQ一键脚本&#xff08;适用于小白支持autMan/无界&#xff09; 复制以…

linux标准 I/O

FILE 指针标准输入、标准输出和标准错误检查或复位状态I/O 缓冲控制文件 I/O 内核缓冲的标志直接 I/O&#xff1a;绕过内核缓冲stdio 缓冲 FILE 指针 FILE 是一个结构体数据类型&#xff0c;它包含了标准 I/O 库函数为管理文件所需要的所有信息&#xff0c;包括用于实际I/O 的…

基于Spring Boot的宿舍管理系统设计与实现(源码+定制+开发)宿舍信息管理平台、智能宿舍系统开发、学生宿舍管理平台设计、宿舍入住与信息管理

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

单节点kubernetes-1.20二进制部署

文章目录 一, 集群拓扑二&#xff0c;架构图三&#xff0c;前置准备1.环境准备1.1操作系统初始化配置&#xff08;1&#xff09;关闭防火墙&#xff08;2&#xff09;关闭selinux&#xff08;3&#xff09;关闭swap&#xff08;4&#xff09;根据规划设置主机名&#xff08;5&a…

[简易版] 自动化脚本

前言 uniapp cli项目中没办法自动化打开微信开发者工具&#xff0c;需要手动打开比较繁琐&#xff0c;故此自动化脚本就诞生啦~ 实现 const spawn require("cross-spawn"); const chalk require("picocolors"); const dayjs require("dayjs&quo…

实战教程:利用Docker容器化技术部署Szurubooru图像分享平台

实战教程&#xff1a;利用Docker容器化技术部署Szurubooru图像分享平台 一、Szurubooru介绍1.1 Szurubooru简介1.2 主要特点1.3 主要使用场景 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker comp…

numpy——索引切片

一、索引和切片 import numpy as npx np.arange(48).reshape(6, 8) print(x)# 选取第二行 print(x[1]) #从0开始&#xff0c;取得第2行# 选取第二行, 第二列 print(x[1][1])# 选取第三行到最后一行, 第一列到最后一列 print(x[2:,2:])# 花式索引 (1, 1) 和 (4, 4) print(&quo…

MPP音视频总结

基础篇 1.常用图像格式介绍 常用图像像素格式 RGB 和 YUV。 1.1RGB RGB分类通常指的是将图像或颜色按照RGB&#xff08;红、绿、蓝&#xff09;颜色空间进行分组或分类。RGB图像格式通常包括RGB24&#xff08;RGB888&#xff09;、RGB32、RGBA、RGB565等。 RGB24是一种常用…

【CSS】入门详解

你是否曾经浏览网页时&#xff0c;被一些网站精美的布局、炫酷的动画和赏心悦目的色彩所吸引&#xff1f;这背后神奇的力量就是 CSS&#xff08;层叠样式表&#xff09;。CSS 就像网页的化妆师&#xff0c;它负责网页的样式和布局&#xff0c;让原本枯燥的 HTML 结构变得生动有…

AttributeError: module ‘pandas‘ has no attribute ‘datetime‘

今天在进行时间序列问题处理时候&#xff0c;发生如下报错&#xff1a; AttributeError: module pandas has no attribute datetime 因为在新的pands版本中pandas已不再支持datetime模块。 from datetime import datetime 需要导入datetime库。 原代码&#xff1a; impor…

2025选题|基于Hadoop的物品租赁系统的设计与实现

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…

《虚拟现实的边界:探索虚拟世界的未来可能》

内容概要 在虚拟现实&#xff08;VR&#xff09;技术的浪潮中&#xff0c;我们见证了其从实验室的奇想逐渐走向日常生活的非凡旅程。技术发展的背后是不断突破的创新&#xff0c;早期的设备虽然笨重&#xff0c;但如今却趋向精致、轻巧&#xff0c;用户体验显著提升。想象一下…

【MySQL】视图特性 用户管理

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是视图&#xff0c;我们又该如何管理用户。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! >…