性能优化问题思考总结

INP 是什么?

Interaction to Next Paint (INP)

INP是一项指标,通过观察用户在访问网页期间发生的所有点击、点按和键盘互动的延迟时间,评估网页对用户互动的总体响应情况。

互动是指在同一逻辑用户手势期间触发的一组事件处理脚本。例如,触摸屏设备上的“点按”互动包括多个事件,例如 pointerup、pointerdown 和 click。交互可由 JavaScript、CSS、内置浏览器控件(例如表单元素)或这些控件的组合促成。

互动的延迟时间包括驱动互动的一组事件处理脚本中最长的时长,即从用户开始互动到下一帧显示视觉反馈的那一刻。

INP 的目标是确保尽可能缩短从用户发起互动到下一帧绘制完成之间的时间,以尽可能缩短用户进行的所有互动或大多数互动。

注意 :Interaction to Next Paint (INP) 是一项待处理的核心 Web 指标指标,将于 2024 年 3 月 12 日取代 First Input Delay (FID)。INP 使用 Event Timing API 中的数据评估响应能力。如果互动导致页面无响应,用户体验会很糟糕。INP 会观察用户与网页进行的所有互动的延迟时间,并报告所有(或几乎所有)互动所低于的单个值。INP 较低意味着网页始终能够快速响应所有或绝大多数用户互动。

INP 得分是多少?

很难在响应能力指标上固定“良好”或“差”等标签。一方面,您需要鼓励优先考虑良好响应能力的开发实践。另一方面,您必须考虑这样一个事实,即人们用来设定实现预期开发期望的设备的功能有很大的差异。

为确保提供良好的响应速度的用户体验,

  • INP 低于或等于 200 毫秒表示您的网页具有良好的响应速度
  • INP 高于 200 毫秒且低于或等于 500 毫秒表示网页的响应能力需要改进
  • INP 高于 500 毫秒表示您的网页响应速度很差

优化由JavaScript导致的INP不佳

线上情况(chrome性能分析):

可以看到单个任务由超过600ms的情况,单个任务执行时间过长导致INP 高于 500 毫秒表示您的网页响应速度很差,需要优化耗时较长的任务。

通过分析得知长任务在执行发送曝光sendExp和updateComponent、updateChild等重渲染任务,“任务”是指浏览器执行的任何独立工作。任务涉及的工作包括渲染、解析 HTML 和 CSS、运行编写的 JavaScript 代码以及无法直接控制的其他事情。其中,程序员编写并部署到网络的 JavaScript 是主要任务来源。

如何优化耗时较长的任务,我们一般有以下几个方法:

1. 避免长任务

在国际往返一屏项目中,由于去程和返程来回横滑切换时需要切换航班卡片展示形态,在一些热门航线如北京往返香港,去程列表航班卡片数百个,返程航班卡片数百个,一次切换形态,props发送变化会造成大量的父子组件重新渲染,组件的重新渲染又会引起大量曝光请求重新发送,使得页面性能消耗巨大,严重时能造成页面崩溃。

props只要任何改变就会导致父子组件重渲染,有一些props发送改变时是不必要都去重渲染浪费性能,所以这里通过memo来缓存组件,只有必要内容发送改变时才进行重渲染

export default memo(FlightCard, (props, nextProps) => {// 只对比需要涉及组件重渲染的props属性,不一味任何props的改变都无脑重渲染const { isActive, moduleIndex, cardIndex, item = {}, taxLabel, firstClick } = props;const {isActive: nextIsActive,moduleIndex: nextModuleIndex,cardIndex: nextCardIndex,item: nextItem = {},taxLabel: nextTaxLabel,firstClick: nextFirstClick,} = nextProps;const preProps = {isActive,moduleIndex,cardIndex,item,taxLabel,firstClick,};const compareProps = {isActive: nextIsActive,moduleIndex: nextModuleIndex,cardIndex: nextCardIndex,item: nextItem,taxLabel: nextTaxLabel,firstClick: nextFirstClick,};try {// 重要信息相同则不重新渲染,避免性能过量消耗if (isEqual(compareProps, preProps)) {return true;}} catch (e) {return false;}return false;
});
2. 拆分长任务,请勿阻塞主线程

线上版本中,无论是上下滑动还是左右横滑,都会发送大量曝光请求,当频繁滑动的时候,网络请求列表中同时发送的请求数量过大,导致页面卡顿甚至崩溃,避免大量曝光请求同步发送,本着不阻塞主线程、拆分长任务的原则,采用防抖debounce + 分批处理曝光请求的思想:

  • 每次需要曝光的元素出现在视口,不是立马发送曝光请求而是将曝光信息添加到一个全局变量数组中,执行防抖函数进行发送曝光信息,只有到当用户停止新增曝光埋点一段时间之后,再统一发送收集到的曝光信息。
  • 分批处理曝光请求,设置每一批次发送固定数量的曝光信息,每发送一批数据延迟一段时间再继续发送后续批次,以免完全占用主线程导致用户操作回调排队过长
      // 确保全局exposures数组存在window.exposures = window.exposures || [];// 这个标志用于确保页面unload监听器只添加一次window.isBeforeUnloadEventListenerAdded = window.isBeforeUnloadEventListenerAdded || false;// 确保全局防抖window.sendExpTimeout = window.sendExpTimeout || null;// 发送全部曝光信息
    const sendExposures = debounce(() => {// 发送window.exposures中的曝光数据if (window && window.exposures && window.exposures.length > 0) {// 每发送100个曝光数据,等待1000 ms再发送,避免长期占用主线程sendRequestsInBatches([...window.exposures], 100, _sendExp);}// 防抖500 ms,用户500ms内无新增曝光操作才发送
    }, 500);// 批量发送曝光信息
    async function sendRequestsInBatches(dataArray, batchSize, onRequest) {for (let i = 0; i < dataArray.length; i += batchSize) {// 获取当前批次的数据const batch = dataArray.slice(i, i + batchSize);// 使用 Promise.all 并发发送请求Promise.all(batch.map(dataItem => {onRequest(dataItem);})).then(() => {// 发送完这一批数据,在window.exposures中清除window && window.exposures.splice(0, batchSize);}).catch(() => {console.error("exp信息发送失败");})// 可能需要延迟一小段时间(1000 ms)以避免完全占用网络和CPUawait new Promise(resolve => setTimeout(resolve, 1000));}
    }// 组件需要曝光
    const sendExp = () => {window && window.exposures.push({logkey: dataExpKey,exargs: expTrackInfo.trackArgs,spm: spm,scm: expTrackInfo.scm || ''}
    )
    sendExposures();
    }
    

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

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

相关文章

龙蜥OS 尝试

> 尝试一下龙蜥OS&#xff0c;和Centos8应该没什么区别。 阿里云版本龙蜥 https://alinux3.oss-cn-hangzhou.aliyuncs.com/aliyun_3_x64_20G_nocloud_alibase_20230727.vhd Index of /anolis/8.8/isos/GA/x86_64/ (openanolis.cn) 网卡 我在虚拟机上安装完后&#xff0c;…

[Python进阶] 混合编程

2.22 混合编程 2.22.1 什么是混合编程 所谓的混合编程就是指在一个大型项目中&#xff0c;因为要涉及到多个方面&#xff0c;单独使用某一种语言进行开发已经不能满足要求&#xff0c;可能在某一个模块中&#xff0c;需要用A语言编写一部分&#xff0c;而用B语言编写另外的部…

SpringBoot使用classfinal-maven-plugin插件加密Jar包

jar包加密 1、在启动类的pom.xml中加入classfinal-maven-plugin插件 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><…

算法沉淀——动态规划之子数组、子串系列(上)(leetcode真题剖析)

算法沉淀——动态规划之子数组、子串系列 01.最大子数组和02.环形子数组的最大和03.乘积最大子数组04.乘积为正数的最长子数组长度 01.最大子数组和 题目链接&#xff1a;https://leetcode.cn/problems/maximum-subarray/、 给你一个整数数组 nums &#xff0c;请你找出一个具…

计算机设计大赛 深度学习实现行人重识别 - python opencv yolo Reid

文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c…

vue3使用elementPlus进行table合并处理

elementPlus中table合并部分列 虚拟数据中公司下有多个客户&#xff0c;公司一样的客户&#xff0c;公司列需要合并&#xff0c;客户如果一样也需要合并进行展示&#xff0c;效果展示 const tableData ref([])自定定义自已想要的数据&#xff0c;一般都是通过接口拿到 //table…

springboot/ssm中医药店管理系统Java中药品出入库管理系统web

演示视频&#xff1a;https://www.bilibili.com/video/BV1rS421A7Ht/ 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&…

No module named ‘transformers.models.auto.tokenization_auto‘

transformers包安装 !pip install pytorch-transformers代码 from transformers import AutoTokenizer tokenizer AutoTokenizer.from_pretrained("gpt2")报错&#xff1a; No module named ‘transformers.models.auto.tokenization_auto’ 解决方案&#xff1a…

ubuntu+QT+ OpenGL环境搭建和绘图

一&#xff0c;安装OpenGL库 安装OpenGL依赖项&#xff1a;运行sudo apt install libgl1-mesa-glx命令安装OpenGL所需的一些依赖项。 安装OpenGL头文件&#xff1a;运行sudo apt install libgl1-mesa-dev命令来安装OpenGL的头文件。 安装GLUT库&#xff1a;GLUT&#xff08;Ope…

亚马逊巨头都在用的自养号大法,赶快get!

随着时间的推移&#xff0c;越来越多做亚马逊生意的朋友开始意识到自养号的重要性。拥有自养号意味着掌握了一手资源&#xff0c;这种自主性让人感到更安全。高权重的买家号可以享有更多的操作权限&#xff0c;也能获得更好的效果。然而&#xff0c;要想成功地养好自养号并不是…

mybatis---->tx中weekend类

&#x1f64c;首先weekend可不是mybatis中的类呦~~&#x1f64c; 它是来自于mybatis的一个扩展库&#xff01; 如果你要在springboot中使用&#xff0c;需要引入以下依赖~~ <dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot…

滥用生成式人工智能的安全威胁的应对

文章目录 前言一、生成式人工智能滋生了恶意大模型的新威胁(一)对维护国家安全提出新挑战(二)对行业应用创新造成新冲击(三)对生产生活方式带来新威胁二、生成式人工智能安全治理难点(一)包容审慎存在失衡,政策尺度有待细化(二)协同治理能力不足,联动合力有待提升(…

蓝桥杯刷题1

目录 1. 平方和 2. 门牌制作 3. 卡片 4. 分数 5. 星期一 6. 顺子日期 1. 平方和 题目描述&#xff1a;小明对数位中含有2、0、1、9 的数字很感兴趣&#xff0c;在1 到40 中这样的数包 括1、2、9、10 至32、39 和40&#xff0c;共28 个&#xff0c;他们的和是574&#x…

Netty权威指南——基础篇2(NIO编程)

1 概述 与Socket类和ServerSocket&#xff0c;NIO也提供了SocketChannel和ServerSocketChannel两种不同的套接字通道实现。这两种新增的通道都支持阻塞和非阻塞两种模式。阻塞模式使用简单&#xff0c;但性能和可靠性都不好&#xff0c;非阻塞模式则正好相反。一般来说&#xf…

python Matplotlib Tkinter-->导出pdf报表

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 reportlab 4.0.9 import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk import tkinter as tk import tkinter.messagebox as messagebox impor…

你知道哪里有Alzet购买吗?

Alzet Osmotic Pumps 是 ALZA 公司于二十世纪七十年代发明的一种用于体内药物缓释的工具。ALZA公司是一家著名的药物研发公司&#xff0c;由其研发的 Alzet 植入式胶囊渗透压泵一开始是用于公司内部和相关科研机构做药物测试用的&#xff0c;但是不久之后&#xff0c;由于渗透压…

46.仿简道云公式函数实战-文本函数-CHAR

1. CHAR函数 函数可将计算机其他类型的数字代码转换为字符。 2. 函数用法 CHAR(number) CHAR 函数可将计算机其他类型的数字代码转换为字符。 Number&#xff1a;用于指定字符的数字。 3. 函数示例 CHAR(10)&#xff0c;即返回值为换行字符"\n"。 目前仿简道…

电脑背景图片怎么设置?这个方法让你一目了然

电脑背景图片的设置是个性化电脑桌面的重要步骤之一。一张美观的背景图片不仅可以为电脑带来视觉愉悦&#xff0c;还能反映个人品味和风格。在本文中&#xff0c;我们将介绍电脑背景图片的设置方法&#xff0c;共包括三种方式&#xff0c;通过分步骤详细说明&#xff0c;帮助用…

【重温设计模式】适配器模式及其Java示例

【重温设计模式】适配器模式及其Java示例 适配器模式的介绍 在软件开发的世界里&#xff0c;设计模式如同是我们的罗盘&#xff0c;指引着我们在复杂的代码海洋中航行。而其中的适配器模式&#xff0c;就如同是我们手中的万能钥匙&#xff0c;让我们能够灵活应对各种各样的设…

解决Maven爆红以及解决 Idea 卡在 Resolving问题

关于 Idea 卡在 Resolving&#xff08;前提是Maven的setting.xml中配置好了阿里云和仓库&#xff09; 参考文章https://blog.csdn.net/jiangyu1013/article/details/95042611 解决Maven爆红参考文章https://devpress.csdn.net/beijing/656d993b76f0791b6eca7bb0.html?dp_toke…