JavaScript 微观性能测试、历史和局限性
많은 개발자가 작업을 수행하는 다양한 방법을 더 많이 배울 때 성능 최적화에 관심이 있다고 생각합니다. 내부에서는 "어떤 길이 가장 좋은지 묻는 목소리도 있다. Douglas Crockford의 2008년 JavaScript: The Good Parts처럼 "최고"에 대한 지표는 다양하지만 성능은 직접 테스트할 수 있기 때문에 접근 가능합니다.
그러나 성능을 테스트하고 입증하는 일이 항상 쉬운 것은 아닙니다.
약간의 역사
브라우저 전쟁
2000년대 초반에는 Internet Explorer가 최초의 브라우저 전쟁에서 승리했습니다. IE는 한동안 Mac의 기본 브라우저이기도 했습니다. 한때 지배적이었던 Netscape는 AOL에 매각되었고 결국 폐쇄되었습니다. Mozilla는 새로운 독립형 브라우저 Phoenix Firebird Firefox를 위해 수년간 베타 버전을 선보였습니다.
2003년 Opera 7은 새롭고 더 빠른 렌더링 엔진인 Presto와 함께 출시되었습니다. 또한 Apple은 잘 알려지지 않은 Konqueror KHTML 엔진을 기반으로 구축된 Mac용 성능 중심 브라우저인 Safari를 출시했습니다. Firefox는 2004년에 공식적으로 출시되었습니다. Microsoft는 2006년에 IE 7을 출시했고 Opera 9는 더 빠른 JavaScript 엔진을 출시했습니다. 2007년에는 Windows와 새로운 iPhone 모두에 Safari가 도입되었습니다. 2008년에는 Google Chrome과 Android 브라우저가 등장했습니다.
더 많은 브라우저와 더 많은 플랫폼이 등장하면서 이 기간의 핵심은 성능이었습니다. 새로운 브라우저 버전은 정기적으로 가장 빠른 새 브라우저라고 발표되었습니다. Apple의 SunSpider 및 Mozilla의 Kraken과 같은 벤치마크는 릴리스에서 자주 인용되었으며 Google은 자체 Octane 테스트 제품군을 유지했습니다. 2010년에 Chrome 팀은 브라우저의 성능을 입증하기 위해 일련의 '속도 테스트' 실험도 수행했습니다.
고성능 자바스크립트
미시 성능 테스트는 2010년대에 많은 주목을 받았습니다. 웹은 제한된 페이지 상호 작용에서 완전한 클라이언트 측 단일 페이지 응용 프로그램으로 전환되고 있었습니다. Nicholas Zakas의 2010 High Performance 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% 的机会。
更完整的引用添加了关键上下文。如果我们允许自己这样做,我们可以在小效率上花费大量时间。这通常会花费时间来实现项目目标,但无法提供太多价值。
收益递减
我个人在这些优化上花了很多时间,目前看来并不算浪费。但回想起来,并不清楚这些工作有多少是值得的。我确信我当时写的一些代码将执行时间缩短了几毫秒,但我真的不能说节省的时间是否重要。
Google 甚至谈到了 2017 年 Octane 测试套件退役的收益递减。我强烈建议您阅读这篇文章,深入了解致力于这项工作的团队在性能优化方面遇到的限制和问题。
那么我们如何聚焦那“关键的3%”呢?
应用而非操作
了解代码的使用方式和时间有助于我们更好地决定关注点。
工具而非规则
不久之后,新浏览器的性能提升和变化就开始将我们从这些类型的微观测试推向更广泛的工具,例如火焰图。
如果您有 30 分钟的时间,我推荐这个关于 V8 引擎的 2015 Chrome DevSummit 演示。它讨论的正是这些问题......浏览器不断变化,跟上这些细节可能很困难。
对正在运行的应用程序进行性能监控和分析可以帮助您快速识别代码的哪些部分运行缓慢或运行频繁。这使您能够处于有利的位置来考虑优化。
重点
使用性能监控工具和库可以让您了解代码如何运行以及哪些部分需要工作。它们还让我们有机会了解不同的领域是否需要在不同的平台或浏览器上工作。也许 localStorage 在内存和 eMMC 存储有限的 Chromebook 上要慢得多。也许您需要缓存更多信息来应对缓慢或不稳定的蜂窝服务。我们可以猜测哪里出了问题,但测量是更好的解决方案。
如果您的客户群足够大,您可能会发现真实用户监控 (RUM) 工具的好处,它可以让您了解实际的客户体验。这些超出了本文的范围,但我已经在几家公司使用它们来了解客户体验的范围,并将重点放在实际性能和错误处理上。
替代方案
深入思考“我如何改进这件事”很容易,但这并不总是最好的答案。您可以退后一步并询问“这是解决此问题的正确解决方案吗?”来节省大量时间
在 DOM 上加载非常大的元素列表时出现问题?也许仅在页面上加载可见元素的虚拟化列表可以解决性能问题。
在客户端执行许多复杂的操作?在服务器上计算部分或全部这些会更快吗?部分工作可以缓存吗?
退一步:这是执行此任务的正确用户界面吗?如果您设计的下拉列表预计有 20 个条目,而现在有 3000 个条目,那么您可能需要不同的组件或体验来进行选择。
够好了吗?
对于任何表演作品,都存在一个次要问题:“什么才足够”? Stand-up Maths 的 Matt Parker 有一段精彩的视频,讲述了他编写的一些代码以及他的社区如何将其从运行时间周改进到毫秒。虽然令人难以置信的是,这样的优化是可能的,但几乎所有项目都有一个达到“足够好”的点。
For a program that is run just once, weeks might be acceptable, hours would be better, but how much time you spend on it rapidly becomes an important consideration.
You might think of it like tolerances in engineering. We have a goal, and we have a range of acceptance. We can aim for perfect while understanding that success and perfection aren't the same.
Identifying Performance Goals
Goals are a critical part of optimization. If you only know that the current state is bad, "make it better" is an open-ended goal. Without a goal for your optimization journey you can waste time trying to find more performance or more optimization when you could work on something more important.
I don't have a good metric for this because performance optimization can vary wildly, but try not to get lost in the weeds. This is really about project management and planning more than coding solutions, but developer input is important when defining optimization goals. As suggested in the Alternatives section, the fix may not be "make this faster".
Setting Limits
In Matt Parker's case, he needed the answer eventually, and didn't need to use the device for anything else. In our world, we're often measuring visitor performance and its probable financial impact vs developer/team time and your opportunity cost, so the measure isn't as simple.
Let's imagine we know reducing our add-to-cart time by 50% would increase our income by 10%, but it will take two months to complete that work. Is there something that could have a bigger financial impact than two months of optimization work? Can you accomplish some benefit in a shorter period of time? Again, this is about project management than code.
Isolate Complexity
When you do find yourself needing to optimize code, it's also a good time to see if you can separate that code from other parts of your project. If you know you have to write complex optimizations that will make the code difficult to follow, extracting it to a utility or library can make it easier to reuse and allows you to update that optimization in one place if it needs to change over time.
Conclusion
Performance is a complicated subject with lots of twists and turns. If you aren't careful you can put in a lot of energy for very little practical gain. Curiosity can be a good teacher, but it doesn't always achieve results. There is a benefit to playing with code performance, but also a time to analyze actual sources of slowness in your project and use the available tools to help resolve them.
Resources
- Addy Osmani - Visualising JS processing over time with DevTools Flame Charts
- Stand-Up Maths - Someone improved my code by 40,832,277,770%
- Title image made with Microsoft Copilot
以上是JavaScript 微观性能测试、历史和局限性的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务
