在运行时确定浏览器是不是太慢而无法优雅地处理复杂的 JavaScript/CSS 的最佳方法是啥?
Posted
技术标签:
【中文标题】在运行时确定浏览器是不是太慢而无法优雅地处理复杂的 JavaScript/CSS 的最佳方法是啥?【英文标题】:What's the best way to determine at runtime if a browser is too slow to gracefully handle complex JavaScript/CSS?在运行时确定浏览器是否太慢而无法优雅地处理复杂的 JavaScript/CSS 的最佳方法是什么? 【发布时间】:2011-06-11 16:40:50 【问题描述】:我正在考虑逐步启用/禁用页面上的 javascript(和 CSS)效果 - 取决于浏览器的速度/速度。
我特别考虑的是低功耗移动设备和旧台式电脑——不仅仅是 IE6 :-)
有没有这样的例子?
衡量这一点的最佳方法是什么 - 考虑一些事情,例如繁忙的 CPU 上的临时减速?
注意事项:
我对浏览器/操作系统检测不感兴趣。 目前,我对带宽测量不感兴趣,只对浏览器/cpu 性能感兴趣。 可能对测量感兴趣的事物: 基础 JavaScript DOM 操作 DOM/CSS 渲染 我希望以一种尽可能少地影响页面呈现速度的方式来执行此操作。顺便说一句:为了不让行为不一致的用户混淆/激怒用户 - 当然,这需要屏幕上的通知以允许用户选择加入/退出整个性能调整过程。
[更新:我错过了一个相关问题:Disable JavaScript function based on user's computer's performance。谢谢Andrioid!]
【问题讨论】:
+1 我同意——我很想看看 SO 给出的答案。 相关:***.com/questions/3276321/… 【参考方案1】:您可以尝试对一些基本操作进行计时 - 查看 Steve Souder 的 Episodes 和 Yahoo 的回旋镖,了解在浏览器端计时的好方法。然而,要确定指标与可接受的性能水平/有益的用户体验之间的关系将相当复杂。
如果您要提供一个 UI 让用户选择加入/退出,为什么不让用户选择应用中的视觉效果与渲染速度?
【讨论】:
【参考方案2】:在这里不是很高兴,但在我看来,这不是目前以任何有意义的方式可能实现的壮举。
这有几个原因,主要是:
无论你做什么测量,如果它有任何意义,都必须测试浏览器/cpu的最大潜力,这是你无法做到的,并保持任何合理的用户体验
即使可以,这也将是一个毫无意义的快照,因为您不知道在您的测试运行时除了浏览器之外的其他应用程序的 CPU 承受了什么样的负载,并且在用户运行时,无论天气与否,这种情况都会继续正在访问您的网站。
即使你能做到,每个浏览器都有自己的优点和缺点,这意味着你必须测试每个 dom 操作函数才能知道浏览器完成它的速度,没有“一般”或“平均”这在我的经验中是有意义的,即使有,dom 操作命令的执行速度也是基于 dom 中当前内容的上下文,当你操作它时会发生变化。
你能做的最好的就是要么
让您的用户决定他们想要什么,并让他们在后悔时轻松更改该决定
或者更好
选择给他们一些你可以合理确定大部分目标受众能够享受的东西。
稍微偏离主题,但遵循以下思路:如果您的用户不是他们社交圈中的技术领导者(就像这里的大多数用户一样,但世界上大多数人都不是)不要给他们太多选择, IE。任何不是绝对必要的选择 - 他们不想要它,而且他们不了解他们的决定的技术后果,以免为时已晚。
【讨论】:
你根本不是一个杀人狂。但是,让我们换个角度看一下:我们如何/何时检测边缘情况(非常慢/快的浏览器)以“安全地”为用户做出选择 - 即当询问他们时会很麻烦或让我们看起来很愚蠢? 到目前为止,我自己还没有想出一个很好的解决方案来解决这个问题,而且在过去的 5 年里我一直试图找到一个。我们在这里做的方式很糟糕,但是我得到的最好的结果是在运行 ie7(这是我们支持的最慢浏览器)的慢速机器上测试我们所做的一切,如果它运行不顺畅,它会得到优化。然后我们使用特征检测进行渐进增强 - 如果浏览器支持我们使用它的功能,但同样,我们会在我们支持的所有浏览器中测试我们在慢速机器上所做的一切,并进行广泛的优化。 我也在考虑低功耗的移动设备。玩极端渐进增强等。 听起来是个很酷的项目,我希望能帮助你更多:) 我不确定它会飞。这主要是一个思想实验。【参考方案3】:查看 Google 的一些(受版权保护的!)V8 基准:
http://v8.googlecode.com/svn/data/benchmarks/v4/regexp.js
http://v8.googlecode.com/svn/data/benchmarks/v4/splay.js
我选择了几个更简单的基准来介绍您可以自己创建的类似基准来测试功能集。只要您在最慢的系统(这些 Google 测试远远大于这些系统)上将测试的运行时间从开始记录到完成记录的时间保持在不到 100 毫秒,您就应该获得所需的信息,而无需不利于用户体验。虽然 Google 基准测试关注速度更快的系统之间的粒度,但您并不关心。您只需要知道哪些系统需要超过 XX 毫秒才能完成。
你可以测试的东西是正则表达式操作(类似于上面的)、字符串连接、页面滚动、任何导致浏览器重绘或重排的东西等等。
【讨论】:
【参考方案4】:另一种不需要明确基准的方法是逐步启用功能。
您可以按优先顺序应用功能,然后在每个功能之后,如果经过一定时间,则放弃其余功能。
确保最昂贵的功能排在最后,您会根据浏览器的速度向用户提供一些适当的功能选择。
【讨论】:
它仍然存在用户获得(看似随意的)不一致 UI 的危险。 实际上它几乎可以确保不一致的零碎效果 - 对于那些浏览器速度较慢的人来说。【参考方案5】:一些想法:
对测试设置时间限制似乎是一个显而易见的选择。 在 cookie 中存储测试结果似乎也很明显。 测试性能不佳可能会暂停更多脚本 并触发显示非阻塞提示 UI(如现代 Web 浏览器中常见的保存密码提示) 询问用户是否要选择进一步的脚本效果 - 并将答案存储在 cookie 中。 当用户没有回答提示时,如果连续的测试比第一个更快地完成,则定期重复测试并自动接受脚本提示。 . 附带说明 - 也可能测试慢速网络速度 通过定时下载外部资源(例如页面自己的 CSS 或 JavaScript 文件) 并将该结果与 JavaScript 基准测试结果进行比较。 这对于依赖大量 XHR 效果和/或大量使用<img/>
s 的网站可能很有用。
.
似乎在页面开始渲染之前很难执行 DOM 渲染/操作基准测试 - 因此可能会导致所有用户都出现相当明显的延迟。
【讨论】:
【参考方案6】:您可以使用 Web Workers 运行您想要的所有基准测试,然后根据结果,将您对机器性能的检测存储在 cookie 中。 这仅适用于支持 html5 的浏览器,当然
【讨论】:
【参考方案7】:我提出了一个类似的问题,并以这种方式解决了它,实际上它帮助我做出了一些决定。
渲染页面后我做的:
let now, finishTime, i = 0;
now = Date.now();//Returns the number of miliseconds after Jan 01 1970
finishTime = now + 200; //We add 200ms (1/5 of a second)
while(now < finishTime)
i++;
now = Date.now();
console.log("I looped " + i + " times!!!");
之后,我在几个具有不同操作系统的浏览器上对其进行了测试,i
值给了我以下结果:
Windows 10 - 8GB 内存:
1,500,000 aprox on Chrome 在 Internet Explorer 上大约为 301,327 141,280(在 Firefox 上运行 Lubuntu 2GB 的 VirtualMachine)MacOS 8GB 内存:
Safari 上大约 3,000,000 个 在 Firefox 上大约为 1,500,000 70,000(在 Firefox 41 上运行 Windows XP 2GB 的虚拟机上)Windows 10 - 4GB RAM(这是我的旧电脑)
Google Chrome 上大约 500,000 个我以列表的形式加载了很多 div,根据用户的输入动态加载,这有助于我根据给定的性能限制我创建的元素数量,但是 但是 JS 并不是全部!,因为即使在虚拟机上运行的 Lubuntu 操作系统也很糟糕,它在不到 2 秒的时间内加载了 20,000 个 div 元素,你可以毫无问题地滚动列表,而我花了超过 12 秒对于 IE,性能很差!
所以一个好方法可能是这样,但是当涉及到渲染时,那就是另一回事了,但这肯定有助于做出一些决定。
祝大家好运!
【讨论】:
您基本上是在对Date.now()
进行基准测试,并希望它代表其他类型的性能。但正如你自己的结果所示,事实并非如此。这就说得通了;它可能在很大程度上取决于浏览器/操作系统的实现,而硬件只反映时钟速度和指令吞吐量。它不测量分支预测、数据缓存、内存大小/延迟/带宽或与处理更大数据结构相关的任何内容。
@PeterCordes 实际上确实如此,可能您没有注意到问题的注释,他基本上说他对您所说的任何内容都不感兴趣。你真的希望他写一整段代码来检测缓存、内存大小等吗?在 200 毫秒内我们可以说很多,因为问题说“浏览器的速度有多快!!!”,取给定的结果,如果你得到超过 1,000,000,你可以毫无问题地执行所有任务(只是说),是一种快速的方法,不要期望绝对的结果,甚至还有像navigator.deviceMemory
这样的功能
但是你甚至不知道什么浏览器可以处理这个问题,想象一下创建一个完整的代码来分析你所说的一切,当你只想知道什么时候启用一些 JS 和 CSS 功能时,我没有说我的 7 行代码可以解决所有这些问题,但是根据它对我有用的情况,正如我告诉过你的那样,我为那些付出超过 1,000,000 的人启用了更多功能,而用户会非常感激(我不认为一台 4K 电脑使用这 7 行代码会导致性能不佳)但不要杀死其他设备非常重要!
我的意思是,您可以在 JS 中做的其他事情将取决于性能的其他方面,例如用于处理在本地搜索/过滤的大表。对于将 div
元素添加到页面的示例,实际执行前 2k 可能会很好,并检查花费了多长时间,以决定是否应该继续做更多。 (尽管正如您所指出的,滚动/渲染性能可以分开)。不过,如果您可以管理它,那可能比在单独的基准测试中消耗 CPU 时间要好。
@PeterCordes 是的,在这些情况下,我们可以找到更好的解决方案,我喜欢你所说的嵌套循环,这些都是非常好的想法。我认为每个问题最终都可能有不同的解决方案,我们必须充分利用我们看到的所有想法来根据我们的个人情况开发我们的网站:)以上是关于在运行时确定浏览器是不是太慢而无法优雅地处理复杂的 JavaScript/CSS 的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章