0

0

JavaScript 微观性能测试、历史和局限性

PHPz

PHPz

发布时间:2024-09-11 08:07:08

|

705人浏览过

|

来源于dev.to

转载

javascript 微观性能测试、历史和局限性

我认为性能优化对许多开发人员感兴趣,因为他们更多地了解完成任务的不同方法。一些内心的声音问道:“哪种方式最好?”虽然“最佳”指标有很多变化,例如 douglas crockford 的 2008 年 javascript:the good parts,但性能是容易获得的,因为我们可以自己测试它。

然而,测试和证明性能并不总是那么容易做到。

一点历史

浏览器大战

到 2000 年代初期,internet explorer 赢得了第一次浏览器战争。 ie 甚至一度成为 mac 上的默认浏览器。曾经占据主导地位的网景公司被出售给美国在线并最终关闭。他们的衍生产品 mozilla 对其新的独立浏览器 phoenix firebird firefox 进行了长达数年的测试。

2003 年,opera 7 推出了 presto,这是一种新的、更快的渲染引擎。 apple 还发布了 safari,这是一款基于鲜为人知的 konqueror khtml 引擎构建的 mac 性能浏览器。 firefox于2004年正式推出。微软于2006年发布了ie 7,opera 9发布了更快的javascript引擎。 2007 年,safari 出现在 windows 和新 iphone 上。 2008 年出现了 google chrome 和 android 浏览器。

立即学习Java免费学习笔记(深入)”;

随着更多的浏览器和更多的平台,性能成为这一时期的关键部分。新的浏览器版本定期宣布它们是新的最快的浏览器。 apple 的 sunspider 和 mozilla 的 kraken 等基准测试经常在版本中被引用,而 google 则维护着自己的 octane 测试套件。 2010年chrome团队甚至做了一系列“速度测试”实验来展示浏览器的性能。

高性能 javascript

微性能测试在 2010 年代受到了广泛关注。 web 正在从有限的页面交互性转向完整的客户端单页应用程序。 nicholas zakas 的 2010 年高性能 javascript 等书籍展示了看似微小的设计选择和编码实践如何能够产生有意义的性能影响。

不断变化

不久前,javascript 引擎竞赛就致力于解决高性能 javascript 中的一些关键性能问题,引擎的快速变化使得很难知道什么是最好的现在。随着新的浏览器版本和移动设备的出现,微性能测试成为一个热门话题。到 2015 年,现已关闭的性能测试网站 jsperf.com 非常受欢迎,它开始因垃圾邮件而出现性能问题。

测试正确的事情

随着 javascript 引擎的发展,编写测试很容易,但很难确保你的测试公平甚至有效。如果您的测试消耗了大量内存,则后续测试可能会看到垃圾收集造成的延迟。设置时间是否被计入或排除在所有测试之外?测试是否产生相同的输出?测试的背景重要吗?如果我们测试 !~arr.indexof(val) 与 arr.indexof(val) === -1 ,如果我们只是运行表达式或在 if 条件下使用它,会有什么不同吗?

编译器优化

随着脚本解释器被各种编译器取代,我们开始看到编译代码的一些好处和副作用:优化。例如,在没有副作用的循环中运行的代码可能会被完全优化。

// Testing the speed of different comparison operators
for (let i = 0; i < 10000; i += 1) {
  a === 10;
} 

因为这是执行 10000 次操作而没有输出或副作用,所以优化可能会完全丢弃它。但这并不能保证。

移动目标

此外,微优化在不同版本之间可能会发生显着变化。 jsperf.com 的不幸关闭意味着不同浏览器版本的数百万历史测试比较丢失,但这仍然是我们今天可以看到的。

重要的是要记住,微优化性能测试有很多注意事项。

随着性能改进开始趋于平稳,我们看到测试结果出现反弹。其中一部分是引擎的改进,但我们也看到引擎针对常见模式优化代码。即使存在更好的编码解决方案,优化通用代码模式对用户来说也有真正的好处,而不是期望每个站点都进行更改。

变化的景观

比不断变化的浏览器性能更糟糕的是,2018 年计时器的准确性和精度发生了变化,以减轻 spectre 和 meltdown 等推测执行攻击。如果您感兴趣的话,我写了一篇关于这些时间问题的单独文章。

分焦

让事情变得复杂的是,您是否针对最新的浏览器或项目支持的最低浏览器进行测试和优化?同样,随着智能手机的普及,处理能力明显较低的手持设备成为重要的考虑因素。知道在哪里分配时间以获得最佳结果或最有影响力结果变得更加困难。

过早优化?

过早的优化是万恶之源。 ——唐纳德·高德纳

这句话经常被引用。人们用它来暗示,每当我们考虑优化时,我们可能会为了虚幻的或微不足道的收益而浪费时间并使代码变得更糟。在很多情况下这可能是正确的。但这句话还有更多内容:

我们应该忘记小的效率,大约 97% 的情况下:过早的优化是万恶之源。但我们不应该放弃这关键的 3% 的机会。

更完整的引用添加了关键上下文。如果我们允许自己这样做,我们可以在小效率上花费大量时间。这通常会花费时间来实现项目目标,但无法提供太多价值。

收益递减

我个人在这些优化上花了很多时间,目前看来并不算浪费。但回想起来,并不清楚这些工作有多少是值得的。我确信我当时写的一些代码将执行时间缩短了几毫秒,但我真的不能说节省的时间是否重要

Figma
Figma

Figma 是一款基于云端的 UI 设计工具,可以在线进行产品原型、设计、评审、交付等工作。

下载

google 甚至谈到了 2017 年 octane 测试套件退役的回报递减。我强烈建议您阅读这篇文章,深入了解致力于这项工作的团队在性能优化方面遇到的限制和问题。

那么我们如何聚焦那“关键的3%”呢?

应用而非操作

了解代码的使用方式和时间有助于我们更好地决定关注点。

工具而非规则

不久之后,新浏览器的性能提升和变化就开始将我们从这些类型的微观测试推向更广泛的工具,例如火焰图。
如果您有 30 分钟时间,我推荐这个关于 v8 引擎的 2015 chrome devsummit 演示。它讨论的正是这些问题......浏览器不断变化,跟上这些细节可能很困难。

对正在运行的应用程序进行性能监控和分析可以帮助您快速识别代码的哪些部分运行缓慢或运行频繁。这使您能够处于有利的位置来考虑优化。

重点

使用性能监控工具和库可以让您了解代码如何运行以及哪些部分需要工作。它们还让我们有机会了解不同的领域是否需要在不同的平台或浏览器上工作。也许 localstorage 在内存和 emmc 存储有限的 chromebook 上要慢得多。也许您需要缓存更多信息来应对缓慢或不稳定的蜂窝服务。我们可以猜测哪里出了问题,但测量是更好的解决方案。

如果您的客户群足够大,您可能会发现真实用户监控 (rum) 工具的好处,它可以让您了解实际的客户体验。这些超出了本文的范围,但我已经在几家公司使用它们来了解客户体验的范围,并将重点放在实际性能和错误处理上。

替代方案

深入思考“我如何改进这件事”很容易,但这并不总是最好的答案。您可以退后一步并询问“这是解决此问题的正确解决方案吗?”来节省大量时间

在 dom 上加载非常大的元素列表时出现问题?也许仅在页面上加载可见元素的虚拟化列表可以解决性能问题。

在客户端执行许多复杂的操作?在服务器上计算部分或全部这些会更快吗?部分工作可以缓存吗?

退一步:这是执行此任务的正确用户界面吗?如果您设计的下拉列表预计有 20 个条目,而现在有 3000 个条目,那么您可能需要不同的组件或体验来进行选择。

够好了吗?

对于任何表演作品,都存在一个次要问题:“什么才足够”?有一个来自 stand-up maths 的 matt parker 的精彩视频,讲述了他编写的一些代码以及他的社区如何将其从运行时间改进到毫秒。虽然令人难以置信的是,这样的优化是可能的,但几乎所有项目都有一个达到“足够好”的点。

对于只运行一次的程序,几周可能是可以接受的,几个小时会更好,但你快速花费多少时间就成为一个重要的考虑因素。

您可能会认为它就像工程中的公差。我们有一个目标,我们有一个接受范围。我们可以追求完美,同时明白成功和完美并不相同。

确定绩效目标

目标是优化的关键部分。如果你只知道当前状态不好,“让它变得更好”就是一个开放式目标。如果没有优化之旅的目标,当您可以处理更重要的事情时,您可能会浪费时间尝试寻找更高的性能或更多的优化。

我对此没有一个好的衡量标准,因为性能优化可能会有很大差异,但尽量不要迷失在杂草中。这实际上与项目管理和规划有关,而不仅仅是编码解决方案,但在定义优化目标时,开发人员的输入非常重要。正如“替代方案”部分中所建议的,解决方案可能不是“使其更快”。

设定限制

就马特·帕克的情况而言,他最终需要答案,并且不需要将该设备用于其他任何用途。在我们的世界中,我们经常衡量访问者表现及其可能的财务影响开发人员/团队时间以及您的机会成本,所以措施没那么简单。

假设我们知道将添加到购物车的时间减少 50% 将使我们的收入增加 10%,但完成这项工作需要两个月的时间。有什么比两个月的优化工作产生更大的财务影响吗?你能在更短的时间内实现一些效益吗?再说一次,这是关于项目管理而不是代码。

隔离复杂性

当您确实发现自己需要优化代码时,也是看看是否可以将该代码与项目的其他部分分开的好时机。如果您知道必须编写复杂的优化,这将使代码难以理解,那么将其提取到实用程序或库可以使其更容易重用,并允许您在需要随时间变化时在一个地方更新该优化。

结论

表演是一个复杂的话题,有很多曲折。如果你不小心的话,你可能会投入大量的精力却收效甚微。好奇心可以是一位好老师,但它并不总是能取得成果。玩弄代码性能是有好处的,但也有时间分析项目中缓慢的实际来源并使用可用的工具来帮助解决它们。

资源

  • addy osmani - 使用 devtools flame charts 可视化 js 处理随时间的变化
  • 站立数学 - 有人将我的代码改进了 40,832,277,770%
  • 使用 microsoft copilot 制作的标题图像

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

827

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

743

2023.11.06

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

775

2023.08.22

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

513

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

244

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

5306

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

481

2023.09.01

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

22

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Highcharts中文参考手册
Highcharts中文参考手册

共16课时 | 7.1万人学习

ios开发手册中文版
ios开发手册中文版

共25课时 | 16.5万人学习

Docker 教程
Docker 教程

共19课时 | 18万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号