指示处理器密集型 JS 函数正在运行(GIF 微调器不动画) [英] Indicate that processor-heavy JS function is running (GIF spinners don't animate)
问题描述
显示然后隐藏动画指示器/微调器 gif 是向用户展示他们的操作已生效以及在他们等待操作完成时正在发生的事情的好方法 - 例如,如果操作需要从服务器通过 AJAX.
我的问题是,如果速度下降的原因是处理器密集型功能,则 gif 会冻结.
在大多数浏览器中,GIF 会在需要处理器的函数执行时停止动画.对于用户来说,这看起来像是某个东西已经崩溃或出现故障,而实际上它正在工作.
- 预期:点击后,动画运行.当过程完成时,文本会发生变化(我们通常也会隐藏指示器,但如果我们让它旋转,示例会更清晰).
- 实际结果:动画开始运行,然后冻结,直到过程完成.这给人的印象是有些东西坏了(直到它突然意外完成).
如果 JS 使处理器保持忙碌,有什么方法可以表明进程正在运行并且不会冻结?隐藏说 Loading...
或类似内容的静态文本消息,但动画看起来更活跃.
如果有人想知道为什么我要使用处理器密集型的代码,而不是通过优化来避免这个问题:它有很多必然复杂的渲染.代码非常高效,但它所做的很复杂,所以它总是对处理器的要求很高.它只需要几秒钟,但这足以让用户感到沮丧,并且 有大量研究可以追溯到很长一段时间,表明指标对用户体验有益.
<小时>用于处理器密集型函数的 gif 微调器的第二个相关问题是微调器在一个同步集中的所有代码都运行之前实际上不会显示 - 这意味着它通常不会显示微调器直到需要隐藏旋转器.
- JSBIN 示例.
- 我在这里找到的一个简单解决方法(在上面的另一个示例中使用)是在
setTimeout( function(){ ... },50);
中显示指标后包装所有内容一个非常短的间隔,使其异步.这有效(参见上面的第一个示例),但不是很干净 - 我相信有更好的方法.
我确定必须有一些标准方法来处理我不知道的处理器密集型加载指标 - 或者可能只是将 Loading...
文本与 一起使用是正常的设置超时
?我的搜索一无所获.我已经阅读了 6 或 7 个关于类似问题的问题,但结果证明它们都是无关的.
编辑评论中有一些很好的建议,这里是我的确切问题的一些细节:
- 复杂的过程涉及处理大型 JSON 数据文件(例如,加载文件后在内存中的 JS 数据操作操作),以及渲染 SVG(通过 Raphael.js)可视化,包括一个复杂的、详细的可缩放的世界地图,基于来自 JSON 的数据处理结果.因此,其中一些需要 DOM 操作,有些则不需要.
- 不幸的是,我确实需要支持 IE8 但是 如有必要,我可以为 IE8/IE9 用户提供最小的后备,例如
Loading...
文本并为其他人提供现代感.li>
如果动画是使用变换实现的,而不是通过更改属性来实现,现代浏览器现在可以独立于 UI 线程运行 CSS 动画.关于这方面的文章可以在 http://www.phpied.com/css-animations 上找到-off-the-ui-thread/.
例如,http://projects.lukehaas.me/css-loaders/ 使用转换实现,并且在 UI 线程忙碌时不会冻结(例如,该页面上的最后一个微调器).
Showing then hiding animated indicator / spinner gifs are a good way to show a user that their action has worked and that something is happening while they wait for their action to complete - for example, if the action requires loading some data from a server(s) via AJAX.
My problem is, if the cause of the slowdown is a processor-intensive function, the gif freezes.
In most browsers, the GIF stops animating while the processor-hungry function executes. To a user, this looks like something has crashed or malfunctioned, when actually it's working.
JSBIN example
Note: the "This is slow" button will tie up the processor for a while - around 10 seconds for me, will vary depending on PC specs. You can change how much it does this with the "data-reps" attr in the HTML.
- Expectation: On click, the animation runs. When the process is finished, the text changes (we'd normally hide the indicator too but the example is clearer if we leave it spinning).
- Actual result: The animation starts running, then freezes until the process finishes. This gives the impression that something is broken (until it suddenly unexpectedly completes).
Is there any way to indicate that a process is running that doesn't freeze if JS is keeping the processor busy? If there's no way to have something animated, I'll resort to displaying then hiding a static text message saying Loading...
or something similar, but something animated looks much more active.
If anyone is wondering why I'm using code that is processor-intensive rather than just avoiding the problem by optimising: It's a lot of necessarily complex rendering. The code is pretty efficient, but what it does is complex, so it's always going to be demanding on the processor. It only takes a few seconds, but that's long enough to frustrate a user, and there's plenty of research going back a long time to show that indicators are good for UX.
A second related problem with gif spinners for processor-heavy functions is that the spinner doesn't actually show until all the code in one synchronous set has run - meaning that it normally won't show the spinner until it's time to hide the spinner.
- JSBIN example.
- One easy fix I've found here (used in the other example above) is to wrap everything after showing the indicator in
setTimeout( function(){ ... },50);
with a very short interval, to make it asynchronous. This works (see first example above), but it's not very clean - I'm sure there's a better approach.
I'm sure there must be some standard approach to indicators for processor-intensive loading that I'm unaware of - or maybe it's normal to just use Loading...
text with setTimeout
? My searches have turned up nothing. I've read 6 or 7 questions about similar-sounding problems but they all turn out to be unrelated.
Edit Some great suggestions in the comments, here are a few more specifics of my exact issue:
- The complex process involves processing big JSON data files (as in, JS data manipulation operations in memory after loading the files), and rendering SVG (through Raphael.js) visualisations including a complex, detailed zoomable world map, based on the results of the data processing from the JSON. So, some of it requires DOM manipulation, some doesn't.
- I unfortunately do need to support IE8 BUT if necessary I can give IE8 / IE9 users a minimal fallback like
Loading...
text and give everyone else something modern.
Modern browsers now run CSS animations independently of the UI thread if the animation is implemented using a transform, rather than by changing properties. An article on this can be found at http://www.phpied.com/css-animations-off-the-ui-thread/.
For example, some of the CSS spinners at http://projects.lukehaas.me/css-loaders/ are implemented with transforms and will not freeze when the UI thread is busy (e.g., the last spinner on that page).
这篇关于指示处理器密集型 JS 函数正在运行(GIF 微调器不动画)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!