Skip to content
This repository has been archived by the owner on Apr 13, 2021. It is now read-only.

Performance Evaluation of the Loading Spinner™ #103

Closed
nimbupani opened this issue Nov 14, 2012 · 28 comments
Closed

Performance Evaluation of the Loading Spinner™ #103

nimbupani opened this issue Nov 14, 2012 · 28 comments
Labels

Comments

@nimbupani
Copy link
Member

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

  1. Time taken to load resources required (network, render, all in one)
  2. CPU usage when loader is visible
  3. Runtime Memory usage (pretty sure dev tools have tracing mechanisms for this & above)
  4. How smooth are the animations
  5. Same measurements for usage in retina cases (2x size of what is required)
  6. 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
Copy link
Member

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
Copy link
Member Author

Valid.

@nirzar
Copy link

nirzar commented Nov 14, 2012

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
Copy link
Member Author

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

@nirzar
Copy link

nirzar commented Nov 14, 2012

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
Copy link
Member Author

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
Copy link

nirzar commented Nov 14, 2012

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

@nimbupani
Copy link
Member Author

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//issues/103#issuecomment-10383705.

@nirzar
Copy link

nirzar commented Nov 14, 2012

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

@nimbupani
Copy link
Member Author

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//issues/103#issuecomment-10384236.

@sindresorhus
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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

@tbranyen
Copy link
Member

Isn't that what people said about rounded corners?

@sindresorhus
Copy link
Member

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

@nimbupani
Copy link
Member Author

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//issues/103#issuecomment-10392746.

@niyazpk
Copy link

niyazpk commented Dec 9, 2012

@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
Copy link

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:

  • Canvas spinner powered by setInterval+drawImage on each frame
  • 16 FPS GIF (only 256 colors of course)
  • PNG Sprite

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:

  • Repaint cost
  • FPS
  • CPU
  • RAM

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:

  • Time spent authoring
  • Ease of maintenance
  • Learning curve

@Schepp
Copy link

Schepp commented Mar 28, 2013

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
Copy link

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

@padolsey
Copy link

@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
Copy link

Schepp commented Mar 29, 2013

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
Copy link
Member Author

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
Copy link

Schepp commented Mar 29, 2013

@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
Copy link

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

(all taken on the same computer)

  • GIF: ~20FPS (EXPECTED:: GIF Framerates are limited)
  • SVG with animateTransform: ~38FPS
  • CSS3 steps animation with PNG Sprite: ~57FPS
  • CSS3 Rotation of PNG: ~59FPS
  • CSS3 Pure Rotation (spinner built with ::before/border-radius etc.): ~59FPS

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
Copy link

basecode commented Apr 2, 2013

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
Copy link

stale bot commented Mar 1, 2019

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 stale bot added the stale label Mar 1, 2019
@stale
Copy link

stale bot commented Mar 8, 2019

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

@stale stale bot closed this as completed Mar 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

9 participants