h5bp / lazyweb-requests

Get projects and ideas built by the community
https://github.com/h5bp/lazyweb-requests/issues
1.69k stars 85 forks source link

Performance Evaluation of the Loading Spinner™ #103

Closed nimbupani closed 5 years ago

nimbupani commented 12 years ago

We all have used loading spinners all the time. It is almost mandatory to use them in any app. I have seen various ways they are being used, including SVG, PNG, DOM, Canvas. I think it would be great if someone evaluates the performance of each of these, so we know what would be the right context to use which and when.

Why

Recently I have seen increasing use of JavaScript & SVG/DOM based loading spinners because of the view that it helps solve the 'retina' case. Through this test, as a web developer I would like to know:

  1. If using JavaScript/SVG is more performant than other cases in non-retina case or retina case
  2. What mechanism would be most useful for the 80% use case? The one I can use blindly without thinking.
  3. If I have a zillion loading spinners being active at the same time, which mechanism should I use for maximum performance?

If this has already been done, please do publish the link in the comments so I can sleep in peace

Options to evaluate

Must ensure the end results look visually identical (as much as possible).

  1. GIF: Generate from http://ajaxload.info/
  2. PNG Sprite animated with CSS Animation: info
  3. PNG Sprite animated with JavaScript: Cant find any ready example but must be fairly trivial to rotate via JS instead of CSS Animations
  4. SVG/DOM animated with CSS Animation: spin.js for pixel perfection or this code for graceful degradation.
  5. Canvas loading spinner: Spinners uses jQuery so I think that would be a deal breaker. There is one in pure JS here from 2007.
  6. SVG with SMIL: Available here http://stuff.vandervossen.net/temporary/bigfuckingspinner/index.html (thanks @thijs)

Any other mechanism of a loading spinner I missed?

How to Evaluate

  1. Use a blank page and measure each of the performance criteria on it
  2. Use the blank page as a starter page for each mechanism of testing the performance. Measure the delta for each.
  3. If a method requires svg, js, css all should be inline.
  4. There must be no fallbacks or polyfills used for each mechanism.
  5. Each method must not depend on libraries existing, e.g. we must not use a solution that requires jQuery for the purposes of this test as it would skew the results and make the results useless for evaluation.

    Criteria

  6. Time taken to load resources required (network, render, all in one)
  7. CPU usage when loader is visible
  8. Runtime Memory usage (pretty sure dev tools have tracing mechanisms for this & above)
  9. How smooth are the animations
  10. Same measurements for usage in retina cases (2x size of what is required)
  11. How can the colors, size be altered? What are the files that need to be touched?

    Report

The report should table the results as per the criteria and also mention how many browsers support each method out of the box (no polyfill or special-casing).

If anyone has any inputs on any of this, please suggest! Thanks.

tbranyen commented 12 years ago

I think alongside performance, ease of customization and implementation should also be considered. I implemented a CSS3 spinner, but since I couldn't do it entirely within a single class I had to have scaffolded markup wherever I wanted the spinner to go. Which was a wrapper <div/> an inner wrapper <div/> and five <div/> bars.

nimbupani commented 12 years ago

Valid.

nirzar commented 12 years ago

I can evaluate. Personally i think retina is not good enough reason to use those things. Customizing the spinner with css could be a good plus along with retina. Also having to add a fallback for things like spinners and loaders sounds like a pain.

nimbupani commented 12 years ago

No, there is no need for fallback at all. But many people use it with fallbacks which surprises me.

nirzar commented 12 years ago

spin.js uses VML for old IE. cssload.net does not have a fallback by default "PNG Sprite animated with CSS Animation" needs a fallback - as written there. Canvas loading spinner needs excanvas.js for it to work in IE

nimbupani commented 12 years ago

The point of the exercise is to use code without these fallbacks. I merely suggested these as already existing. spin.js has code that can be removed (it does feature testing anyway). Testing canvas loading spinner requires it to be tested on a browser that supports canvas and IE9 and above do.

nirzar commented 12 years ago

True. I thought it could be part of the implementation factor that was discussed.

nimbupani commented 12 years ago

No. I think it is essential none of the solutions use fallbacks or anything of that sort. It will not reflect performance accurately then. I will amend text to state so.

On Wed, Nov 14, 2012 at 12:45 PM, Nirzar Pangarkar <notifications@github.com

wrote:

True. I thought it could be part of the implementation factor that was discussed.

— Reply to this email directly or view it on GitHubhttps://github.com/h5bp/lazyweb-requests/issues/103#issuecomment-10383705.

nirzar commented 12 years ago

Makes sense. I think pure css loader is missing from the list. cssload.net

nimbupani commented 12 years ago

Pure CSS Loader is the DOM based loader. It uses a bunch of markup divs.

On Wed, Nov 14, 2012 at 12:58 PM, Nirzar Pangarkar <notifications@github.com

wrote:

Makes sense. I think pure css loader is missing from the list. cssload.net

— Reply to this email directly or view it on GitHubhttps://github.com/h5bp/lazyweb-requests/issues/103#issuecomment-10384236.

sindresorhus commented 11 years ago

If I have a zillion loading spinners being active at the same time, which mechanism should I use for maximum performance?

The most convenient one. Micro-optimizations are no good.

tbranyen commented 11 years ago

It's not that simple. We have an application that had a significant amount of spinners and on the iPad I got a ton of lag. It was convenient to use images, but since that sucked, we went for the CSS3 spinners.

In my opinion finding the "best" approach is a useful endeavor. Hoping to find a better method than what I currently do.

sindresorhus commented 11 years ago

Sure, but if you have a significant amount of spinners you might have an bigger problem. Just saying.

tbranyen commented 11 years ago

Isn't that what people said about rounded corners?

sindresorhus commented 11 years ago

I think you mean box shadows, but anyways. If you have more than one or few spinners you're doing something wrong.

nimbupani commented 11 years ago

huh? Its not about more than 1 or few spinners, it is the very fact that many aspects of a page change and we need to know what works best in the worst case scenario. People have coped, but it is worth investigating what is the best case scenario and what can be done to improve it.

On Wed, Nov 14, 2012 at 4:35 PM, Sindre Sorhus notifications@github.comwrote:

I think you mean box shadows, but anyways. If you have more than one or few spinners you're doing something wrong.

— Reply to this email directly or view it on GitHubhttps://github.com/h5bp/lazyweb-requests/issues/103#issuecomment-10392746.

niyazpk commented 11 years ago

@sindresorhus it is micro-optimization and usually entirely pointless to do these kinds of research on an individual basis. At the same time, if we can figure it out here, a large number of people can benefit from this in their future projects (similar to other micro-optimizations in h5bp).

padolsey commented 11 years ago

I'm interested in reviving this effort.

One problem with testing this is that every spinner is different. Every use-case is different. Some spinners can be achieved with DOM/CSS alone, and others with SVG, while others require pixel control only provided with Canvas or pre-creating GIFs/Sprites in Photoshop.

I've been working on sonic-creator, which displays:

I've found that it's almost impossible to differentiate performance with a small amount of spinners. Over the weekend I am hoping to develop a heavy performance test which makes it possible to introspect and differentiate on:

Of course, a page full of a few dozen spinners is hyper unrealistic, so the usefulness of this analysis is limited.

Also, in addition to the technical details, there are other things to take into account, generally, such as:

Schepp commented 11 years ago

You might want to watch the part of the video "WebKit in Your Living Room" starting at 33:58: http://www.youtube.com/watch?v=xuMWhto62Eo&feature=player_detailpage#t=2038s

Concluding from there the best option seems to be to create an SVG spinner and have that CSS transforms animated (smooth or stepped, depending on its design).

tsvetomir commented 11 years ago

I don't see declarative SVG animations mentioned here. I wonder how they compare to the alternatives.

padolsey commented 11 years ago

@Schepp Cool presentation -- thanks for the link! I didn't hear mention of SVG though. Static GIF/PNG + CSS transforms seemed the best performing, no?

I wonder what the best method is for animations that cannot easily be expressed by a static image being rotated/transformed by CSS...

Schepp commented 11 years ago

The SVG thing is just something I added myself on top, as it will tackle Retina and is more future-proof than a bitmap. Drawback: You have one extra rasterization step involved, compared to a genuine bitmap.

nimbupani commented 11 years ago

Just to comment on the 'future-proof' thing. Nothing is future-proof. But we must also look into if having extra DOM inline is worth the effort (or is it just being used as a media object as a src?)

What is the source for performance information of SVG spinner?

Schepp commented 11 years ago

@nimbupani I wrote "more", not ultimate. But compared to bitmaps there is a higher degree of future proof-ness in regards to ever increasing dots per pixel values. If we leave dpp out of the equation then CSS animated bitmaps should have the lowest impact of all.

I personally would use the SVG as background-image for my spinner, datauri-fied in my CSS declarations - that would prevent my DOM from unnecessarily growing.

padolsey commented 11 years ago

From Chrome Web Inspector's FPS meter, on a very limited test case:

(all taken on the same computer)

I've only added one test so far -- a 'snake' spinner -- it is unrealistically simple though.

If we were to take these results as fact, the obvious advice would be: If your particular spinner is dead-simple enough to be achieved through CSS alone then that's definitely the route to take, but for more complex spinners a PNG Sprite + CSS3 Steps Animation would seem best (for retina, a media query to determine which PNG to load would be possible).

basecode commented 11 years ago

Great! Thanks for sharing the numbers @padolsey! One thing worth mentioning is that in latest browser versions (most of) the CSS3 Animations spec is rendered in its own thread (run the test, more infos). That means the spinner runs smoothly even when the UI-Thread is blocked. That matters because spinners are most likely being used in cases where something needs to be executed in parallel.

but for more complex spinners a PNG Sprite + CSS3 Steps Animation would seem best

@stoyan's demo is lacking a CSS Animation using the "steps" API but on latest canary I can see the animation stopping.

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 5 years ago

This issue has been automatically closed because it has not had recent activity. Thank you for your contributions.