当前位置: 首页 > article >正文

详细说明脚本评估和耗时较长的任务

在网页性能优化中,脚本评估耗时较长的任务是两大关键性能瓶颈。它们直接影响页面的加载速度、交互响应以及用户体验。以下是对这两个概念的详细说明及优化策略:


一、脚本评估(Script Evaluation)

1. 定义

脚本评估指浏览器解析(Parsing)、编译(Compiling)和执行(Executing)JavaScript代码的全过程。这一过程通常包括:

  • 解析:将文本形式的JavaScript代码转换为抽象语法树(AST)。
  • 编译:将AST转换为机器可执行的字节码或机器码(现代浏览器使用JIT即时编译优化)。
  • 执行:运行编译后的代码,触发变量初始化、函数调用等操作。
2. 性能影响
  • 主线程阻塞:脚本评估发生在浏览器主线程,会阻塞其他任务(如渲染、用户输入响应)。
  • 延迟页面交互就绪时间:过长的脚本评估时间会推迟DOMContentLoadedload事件,影响用户感知。
3. 常见问题场景
  • 大型脚本文件:未压缩或未分割的JavaScript文件(如单文件超过500KB)。
  • 同步加载脚本:未使用asyncdefer<script>标签,阻塞HTML解析。
  • 复杂初始化逻辑:页面加载时执行大量计算或DOM操作。
4. 优化策略
  • 代码分割(Code Splitting)
    使用工具(如Webpack、Rollup)将代码拆分为按需加载的块。
    // 动态导入模块,按需加载
    import('./module.js').then(module => {module.init();
    });
    
  • 延迟非关键脚本
    使用asyncdefer属性异步加载脚本,避免阻塞渲染。
    <!-- 异步加载,不阻塞HTML解析 -->
    <script src="app.js" async></script>
    <!-- 延迟执行,在DOM解析完成后按顺序执行 -->
    <script src="vendor.js" defer></script>
    
  • 减少解析/编译时间
    • 压缩代码(Terser)并移除未使用的代码(Tree Shaking)。
    • 避免使用eval()with等动态语法,增加解析复杂度。
  • 预加载关键资源
    使用<link rel="preload">提前加载核心脚本。
    <link rel="preload" href="critical.js" as="script">
    

二、耗时较长的任务(Long Tasks)

1. 定义

耗时较长的任务指在浏览器主线程上连续运行超过 50毫秒 的任务。这类任务会导致:

  • 帧率下降:浏览器以60 FPS渲染时,每帧需在16.6ms内完成。任务超过50ms会导致至少3帧丢失。
  • 交互延迟:用户点击、滚动等操作无法及时响应。
2. 常见来源
  • 复杂计算:大数据量循环、图像处理算法。
  • 同步DOM操作:批量修改DOM触发多次重排/重绘。
  • 未优化的第三方脚本:如广告跟踪、分析工具。
3. 检测工具
  • Chrome DevTools Performance面板
    录制页面运行时性能,标记超过50ms的任务(红色三角标识)。
  • Long Tasks API
    通过JavaScript监听长任务。
    const observer = new PerformanceObserver((list) => {list.getEntries().forEach(entry => {console.log('长任务耗时:', entry.duration);});
    });
    observer.observe({ entryTypes: ['longtask'] });
    
4. 优化策略
  • 任务分解(Chunking)
    将长任务拆分为多个小任务,通过setTimeoutrequestIdleCallback分时执行。
    function processChunk(data, start) {const chunkSize = 100;const end = Math.min(start + chunkSize, data.length);for (let i = start; i < end; i++) {// 处理数据块}if (end < data.length) {setTimeout(() => processChunk(data, end), 0);}
    }
    processChunk(largeData, 0);
    
  • 使用Web Workers
    将计算密集型任务移至后台线程。
    // 主线程
    const worker = new Worker('task.js');
    worker.postMessage(largeData);
    worker.onmessage = (e) => {console.log('结果:', e.data);
    };// task.js
    self.onmessage = (e) => {const result = heavyComputation(e.data);self.postMessage(result);
    };
    
  • 优化DOM操作
    • 使用DocumentFragment批量插入DOM节点。
    • 避免在循环中直接修改样式,优先使用CSS类名切换。
    const fragment = document.createDocumentFragment();
    data.forEach(item => {const div = document.createElement('div');div.textContent = item;fragment.appendChild(div);
    });
    document.body.appendChild(fragment);
    
  • 限制第三方脚本影响
    • 延迟加载非关键脚本(如广告、分析代码)。
    • 使用<iframe>隔离第三方代码的执行环境。

三、综合优化示例

场景:页面加载时初始化一个大型数据表格,导致脚本评估时间长且触发长任务。
优化步骤
  1. 代码分割
    将表格渲染逻辑拆分为独立模块,动态加载。
    // 点击按钮时加载渲染逻辑
    document.getElementById('loadTable').addEventListener('click', () => {import('./renderTable.js').then(module => {module.renderTable(largeData);});
    });
    
  2. Web Workers处理数据
    在后台线程排序和过滤数据。
  3. 分批渲染
    使用requestAnimationFrame逐帧渲染行,避免阻塞主线程。
    function renderRows(rows, index = 0) {if (index >= rows.length) return;const row = createRow(rows[index]);table.appendChild(row);requestAnimationFrame(() => renderRows(rows, index + 1));
    }
    
  4. 虚拟滚动(Virtual Scrolling)
    仅渲染可视区域内的行,减少DOM节点数量。

四、工具验证

  • Lighthouse报告:检查“Reduce JavaScript execution time”建议。
  • Chrome DevTools Performance面板:分析任务耗时和脚本评估时间。
  • Web Vitals监控:通过web-vitals库跟踪真实用户的FID(首次输入延迟)和INP(Interaction to Next Paint)。

总结

  • 脚本评估优化:关注代码体积、加载策略和解析效率。
  • 长任务优化:通过任务拆分、多线程和DOM操作优化减少主线程阻塞。
  • 核心目标:将主线程的连续任务控制在50ms以内,确保流畅的交互体验(RAIL模型)。

通过结合工具检测和代码级优化,可显著提升页面性能,尤其在低端设备和弱网环境下效果更为明显。

相关文章:

详细说明脚本评估和耗时较长的任务

在网页性能优化中&#xff0c;脚本评估和耗时较长的任务是两大关键性能瓶颈。它们直接影响页面的加载速度、交互响应以及用户体验。以下是对这两个概念的详细说明及优化策略&#xff1a; 一、脚本评估&#xff08;Script Evaluation&#xff09; 1. 定义 脚本评估指浏览器解析…...

Floyd 算法——97. 小明逛公园

卡码网:97. 小明逛公园https://kamacoder.com/problempage.php?pid=1155 题目描述 小明喜欢去公园散步,公园内布置了许多的景点,相互之间通过小路连接,小明希望在观看景点的同时,能够节省体力,走最短的路径。 给定一个公园景点图,图中有 N 个景点(编号为 1 到 N),…...

QT二 QT使用generate form 生成常用UI,各种UI控件

一 。没有使用general form 和 使用 general form 后&#xff0c;file层面和代码层面的不同比较 file层面的不同 代码层面的不同&#xff0c; 在 使用了general form之后&#xff0c;在主界面的构造方法中&#xff0c;使用ui->setupUi(this),就完成了所有UI的处理。 而之…...

蓝桥每日打卡--打家劫舍4

#蓝桥#JAVA#打家劫舍4 题目描述 沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。 由于相邻的房屋装有相互连通的防盗系统&#xff0c;所以小偷 不会窃取相邻的房屋 。 小偷的 窃取能力 定义为他在窃取过程中能从单间房屋中窃…...

Intel Alder Lake N200桌面级处理器 详细介绍

1.Intel Alder Lake N200桌面级处理器 详细介绍 Intel Processor N200 是一款属于 Alder Lake-N 系列的入门级处理器&#xff0c;以下是其详细介绍&#xff1a; 基本规格 架构&#xff1a;Alder Lake-N&#xff0c;采用 Gracemont 架构的高效能核心。 核心与线程&#xff1…...

AudioTrack

AudioTrack是Android Audio系统提供给应用开发者&#xff08;java/C&#xff09;的API&#xff0c;用于操作音频播放的数据通路。MeidaPlayer在播放音乐时用到的是它&#xff0c;我们可以也可以直接使用AudioTrack进行音频播放。它是最基本的音频数据输出类。 AudioTrack.java…...

多条件排序(C# and Lua)

C# 升序排序 OrderBy 按升序对序列的元素进行排序 ThenBy 按升序对序列中的元素执行后续排序 降序排序 OrderByDescending 按降序对序列的元素排序 ThenByDescending 按降序对序列中的元素执行后续排序 public class Fruit {public int id;public string name;publi…...

人工智能之数学基础:线性方程组求解的得力助手——增广矩阵

本文重点 增广矩阵是一个极具实用价值的工具,尤其在处理线性方程组时,它展现了卓越的功效。通过整合系数和常数项,增广矩阵简化了计算过程并提供了判断方程组解集的有效方法。 增广矩阵的起源与定义 增广矩阵的概念源于线性方程组求解的需求。在解决线性方程组时,我们常…...

Vue3 + ECharts 数据可视化实战指南

一、为什么选择ECharts&#xff1f; 百度开源的成熟可视化库 支持30种图表类型 完善的文档和社区支持 与Vue3完美兼容 二、环境搭建 1. 创建Vue3项目 npm create vuelatest # 选择TypeScript、Pinia等按需配置 2. 安装核心依赖 npm install echarts vue-echarts vueus…...

关于Flask框架30道面试题及解析

文章目录 基础概念1. 什么是Flask?其核心特性是什么?2. Flask和Django的主要区别?3. 解释Flask中的“路由”概念。如何定义动态路由?核心组件4. Flask的请求上下文(Request Context)和应用上下文(Application Context)有什么区别?5. 如何访问请求参数?POST和GET方法的…...

服务安全认证概述与基础认证方式

文章目录 1. 引言1.1 认证与授权的区别1.2 认证方式的演进 2. 基础认证方式2.1 HTTP Basic Authentication2.2 API Key 认证2.3 HMAC-SHA256 签名认证2.4 JWT&#xff08;JSON Web Token&#xff09; 3. 认证方式对比与总结3.1 认证方式对比3.2 如何选择合适的认证方式&#xf…...

【Android Studio开发】生命周期、Activity和组件通信(上)

零、前期配置 1.【Android】模式 2.点击【运行】&#xff0c;弹出模拟器 右侧是模拟机&#xff0c;显示Hello World 3. 打开【activity_main.xml】文件&#xff0c;点击【Design】&#xff0c;然后点击【Component Tree】 在弹出的Component Tree中右键【main】,选择【Conver…...

【ES】Elasticsearch学习

文章目录 简单的安装 简单的安装 参考&#xff1a;https://blog.csdn.net/smilehappiness/article/details/118466378 官网&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/targz.html 下载&#xff1a;https://www.elastic.co/cn/downloads/e…...

实验三 Python 数据可视化 Python 聚类-K-means(CQUPT)

一、实验目的 Python 数据可视化&#xff1a; 1、学习使用 jieba、wordcloud 等类库生成词云图。 2、学习使用 Matplotlib 库进行数据可视化。 Python 聚类-K-means&#xff1a; 1、理解聚类非监督学习方法的基本原理。 2、掌握 Python、numpy、pandas、sklearn 实现聚类…...

【STM32】SPI通信协议W25Q64Flash存储器芯片(学习笔记)

通信接口部分有介绍SPI&#xff1a;【STM32】USART串口协议&串口外设-学习笔记-CSDN博客 SPI通信协议 SPI通信 SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司开发的一种通用数据总线四根通信线&#xff1a;SCK&#xff08;Serial Clock&…...

JavaScript实现一个函数,将数组扁平化(flatten),即把多维数组转为一维数组。

大白话实现一个函数&#xff0c;将数组扁平化&#xff08;flatten&#xff09;&#xff0c;即把多维数组转为一维数组。 思路 实现数组扁平化的基本思路是遍历数组中的每个元素&#xff0c;如果元素是数组&#xff0c;就递归地将其扁平化并添加到结果数组中&#xff1b;如果元…...

SpringBoot最佳实践之 - 使用AOP记录操作日志

1. 前言 本篇博客是个人在工作中遇到的需求。针对此需求&#xff0c;开发了具体的实现代码。并不是普适的记录操作日志的方式。以阅读本篇博客的朋友&#xff0c;可以参考此篇博客中记录日志的方式&#xff0c;可能会对你有些许帮助和启发。 2. 需求描述 有一个后台管理系统…...

第六届机电一体化技术与智能制造国际学术会议(ICMTIM 2025)

重要信息 4月11-13日 南京江北新区工业大学亚朵酒店 www.icmtim.org&#xff08;点击了解参会投稿等&#xff09; 简介 由南京工业大学主办&#xff0c;南京工业大学电气工程与控制科学学院、中国矿业大学、黑龙江大学、江苏省自动化学会承办的第六届机电一体化技术…...

numpy学习笔记4:np.arange(0, 10, 2) 的详细解释

numpy学习笔记4&#xff1a;np.arange(0, 10, 2) 的详细解释 以下是 np.arange(0, 10, 2) 的详细解释&#xff1a; 1. 函数作用 np.arange() 是 NumPy 中用于生成均匀间隔数值序列的函数&#xff0c;类似于 Python 内置的 range()&#xff0c;但返回的是 NumPy 数组而非列表&…...

期刊分区表2025年名单下载(经济学、管理学)

2025年期刊分区表包括SCIE、SSCI、A&HCI、ESCI和OAJ&#xff0c;共设置了包括自然科学、社会科学和人文科学在内的21个大类 本次分享的是期刊分区表2025年名单经济学类、管理学类&#xff0c;一共7631025条 一、数据介绍 数据名称&#xff1a;期刊分区表2025年名单 数据…...

八股学习-JUC java并发编程

本文仅供个人学习使用&#xff0c;参考资料&#xff1a;JMM&#xff08;Java 内存模型&#xff09;详解 | JavaGuide 线程基础概念 用户线程&#xff1a;由用户空间程序管理和调度的线程&#xff0c;运行在用户空间。 内核线程&#xff1a;由操作系统内核管理和调度的线程&…...

嵌入式笔记 | 正点原子STM32F103ZET6 4 | 中断补充

1. 外设引脚重映射 1.1 定义 在STM32中&#xff0c;每个外设的引脚都有默认的GPIO端口&#xff0c;但有些引脚可以通过重映射寄存器将功能映射到其他端口。这种机制称为引脚重映射&#xff0c;主要用于解决引脚复用冲突或优化PCB布线。 1.2 重映射的类型 部分重映射&#x…...

PostgreSQL_数据下载并保存(psycopg2)

目录 前置&#xff1a; 1 数据下载 1.1 多个股票多个交易日 1.2 一个交易日所有股票 2 数据保存&#xff0c;使用python中的psycopg2包 2.1 在PyCharm中创建新项目&#xff0c;并安装包 2.2 代码-多个股票多个交易日 2.3 代码-一个交易日所有股票 2.4 在 pgAdmin4 中…...

启明星辰春招面试题

《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇网安资料库https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…...

边缘计算革命:重构软件架构的范式与未来

摘要 边缘计算通过将算力下沉至网络边缘&#xff0c;正在颠覆传统中心化软件架构的设计逻辑。本文系统分析了边缘计算对软件架构的范式革新&#xff0c;包括分布式分层架构、实时资源调度、安全防护体系等技术变革&#xff0c;并结合工业物联网、智慧医疗等场景案例&#xff0c…...

【读点论文】Chain Replication for Supporting High Throughput and Availability

在分布式系统中&#xff0c;强一致性往往和高可用、高吞吐是矛盾的。比如传统的关系型数据库&#xff0c;其保证了强一致性&#xff0c;但往往牺牲了可用性和吞吐量。而像 NoSQL 数据库&#xff0c;虽然其吞吐量、和扩展性很高&#xff0c;但往往只支持最终一致性&#xff0c;无…...

Servlet、Servlet的5个接口方法、生命周期、以及模拟实现 HttpServlet 来写接口的基本原理

DAY15.1 Java核心基础 Servlet Servlet是一个接口&#xff0c;是java的基础&#xff0c;java之所以编写web的程序&#xff0c;接收请求并响应&#xff0c;就是因为Sevlet接口 Java 类实现了Servlet接口的时候就可以接收并响应请求&#xff0c;成为web服务器 Web服务器就是接…...

深入了解 C# 中的 LINQ:功能、语法与应用解析

1. 什么是 LINQ&#xff1f; LINQ&#xff08;Language Integrated Query&#xff0c;语言集成查询&#xff09;是 C# 和其他 .NET 语言中的一种强大的查询功能&#xff0c;它允许开发者在语言中直接执行查询操作。LINQ 使得开发者可以使用 C# 语法&#xff08;或 VB.NET&…...

贝叶斯公式的一个直观解释

E E E&#xff1a;抓到娃娃 H H H&#xff1a;坐地铁 H ˉ \bar H Hˉ&#xff1a;坐公交 P ( E ) P ( H ) P ( E ∣ H ) P ( H ‾ ) P ( E ∣ H ‾ ) P({E}) P({H}) P({E} \mid {H}) {P}(\overline{{H}}) {P}({E} \mid \overline{{H}}) P(E)P(H)P(E∣H)P(H)P(E∣H) P (…...

Java 大视界 -- Java 大数据分布式计算中的通信优化与网络拓扑设计(145)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...