GithubHelp home page GithubHelp logo

Comments (23)

trusktr avatar trusktr commented on April 27, 2024 1

I believe these tests are just determining how long it takes to get from point A to point B in the JavaScript. But what about the renderings that get triggered each time you modify a .style.* property? Are they in sync with the javascript so that a subsequent modification happens only after rendering of the previous modification is finished? Or are they decoupled from rendering so that these tests are missing this part of the performance test because the renderings are queued in the renderer even though the javascript is finished executing?

from jss.

kof avatar kof commented on April 27, 2024

@trusktr

from jss.

kof avatar kof commented on April 27, 2024

http://jsperf.com/csstext-vs-style/29

from jss.

kof avatar kof commented on April 27, 2024

as I have assumed element.style is slightly faster than element.cssText or element.setAttribute('style')

from jss.

trusktr avatar trusktr commented on April 27, 2024

By the way, just from that perf test we can see that using an applyTo workflow would be more performant than creating stylesheets and adding/removing classes. About twice as fast (or whatever "45% slower" means)! EDIT: nevermind, element.classList.add('newClass'); is fastest, I take that back. xD

from jss.

kof avatar kof commented on April 27, 2024
  1. This is a good question. This element is not visible so rendering performance is not realistic.
  2. Of course, but you never create styles just to show an element.

from jss.

kof avatar kof commented on April 27, 2024

Adding/removing classes when stylesheet already added is by far faster in this test.

from jss.

kof avatar kof commented on April 27, 2024

Good question is if we can measure performance of prop change + rendering just by measuring time in javascript. Unclear if this is in sync with rendering and I doubt it is.

from jss.

trusktr avatar trusktr commented on April 27, 2024

Oops, yeah it is. Doh. xD

from jss.

kof avatar kof commented on April 27, 2024

Rendering is also too abstract. The question is what part of it we can measure, composition, layer tree update, paint? I am pretty sure repaint is completely async.

from jss.

trusktr avatar trusktr commented on April 27, 2024

Trying to test this initially using a loop completely blocks rendering: http://fiddle.jshell.net/5qc39drr/3/

from jss.

trusktr avatar trusktr commented on April 27, 2024

It seems logical to assume that styles won't be rendered until the next animation frame of the browser (it might not be true, but would seem to make sense given we have a requestAnimationFrame method given to us). If that's true, then only the javascript line execution matters, and in that case it seems like el.classList.add() would win.

Based on this, here's an example with requestAnimationFrame in jsfiddle: http://fiddle.jshell.net/5qc39drr/16/

Uncomment the test you want. The idea here was to see if we can notice anything visually. It seems to me that the example with setting the style attribute stutters every so often while the others don't, which already indicates setting the attribute might be slower when considering the entire render pipeline.

That fiddle is just a starting point. I have a theory on how we can get conclusive answers. If we stack many requestAnimationFrame calls, more than can be handled in a single animation frame, then we might see something like

........    ........         ........    ........       ........      ........       ........         ........

where the dots are code executions and the spaces are times in between code executions where a browser repaint (and other stuff like DOM updating I suppose?) are happening. We can then calculate the time for each repaint and compare which method results in the faster repaints.

from jss.

trusktr avatar trusktr commented on April 27, 2024

Also, to help make the repaints more distinguishable, each code execution should manipulate lots of css proeprties on lots of elements.

from jss.

trusktr avatar trusktr commented on April 27, 2024

I think that in the vast majority of use cases for jss, people won't be doing things like you see in http://jsperf.com/csstext-vs-style/29, they'll be setting styles only a few times so it's likely that no matter which method they choose they will likely fall within a single animation frame. Updating a large amount of styles on a large amount of elements might only happen in situations like the initial page load, or changing a theme. Also, iframe users will experience lots of changes on lots of elements if they load pages inside the iframes based on navigation links (which, unfortunately, is what I'm doing on my own site, xD It was simply easier to do than starting to worry about moving my famous experiments into multiple famous contexts instead of iframes).

I'm going to try stacking animation frame calls.

from jss.

kof avatar kof commented on April 27, 2024

Yes also I think for animations via javascript they will use some lib. So basically applyTo is an edge case scenario anyways.

from jss.

trusktr avatar trusktr commented on April 27, 2024

Alright, check it out: http://fiddle.jshell.net/5qc39drr/17/

That example causes the animation frame rate to drop a ton. Now let me see if I can get a timestamp that's noticeably different between the last code execution in one frame and the first execution of the next.

from jss.

trusktr avatar trusktr commented on April 27, 2024

Ok here's what I've got so far: http://fiddle.jshell.net/5qc39drr/20/
It measures the time between the last code execution in the previous animation frame and the first code execution in the current animation frame. Look in the console. The numbers seem to be a little high on my system, about 4 to 7 milliseconds. But even so, I think that now I can run whatever code I want in the the requested animation frames, and the average of this number should determine which performs best, (lower is better).

from jss.

trusktr avatar trusktr commented on April 27, 2024

I had to put this aside, but almost done! http://fiddle.jshell.net/5qc39drr/27/

It currently runs 100 trials of whatever test cases you put in the testCases array. the console.log statements shouldn't affect the results since we're not measuring the time of execution of the javascript, but the time between animation frames (the empty spaces from above, there happens to be 1000 dots between each empty space in this case), and (i would think) the inspector rendering is entirely separate from the page since it remains responsive, but we could always remove the logs. Just had them for debugging.

Two things left:

  1. Need to fix: The first few trials of the first testCase take an overly long time for some reason, which throws off the results.
  2. Display the final results.

After that:

  1. make into a configurable module so anyone can use it and supply their initialization function and test case functions to the module.
  2. Use a single requestAnimationFrame instead of 1000, and purposefully waste cpu time in the single call. See if it makes any difference.
  3. also count the time it takes to execute each trial's javascript, then weigh the results with the browser's update times to get the best results.

The results are specific to each browser (different internal implementations).

I'll be back in like 6 or 7 hours.

from jss.

trusktr avatar trusktr commented on April 27, 2024

Nvm, I got so carried away reading and watching videos after you mentioned constraint resolver and posted that link to gss, so I didn't come back to this yet, but I will soon or later. :)

from jss.

trusktr avatar trusktr commented on April 27, 2024

Alright, here's the final working test: http://fiddle.jshell.net/5qc39drr/38/

What I've learned is that the time for each browser layout/render is so high that it completely obscures the original thing we were trying to test. The reflow of the text is resulting in renderings that take about 27 to 29 milliseconds each. If you swap the statements on lines 140 and 141, you'll notice the time for reflow/repaint goes down substantially, but still not enough to show any real difference in the average time for each use case. From this it seems we can conclude that whichever way the css values are set doesn't really matter since the time difference between test cases is almost completely negligible. What really matters is choosing style modifications wisely. This is a nice test to see how style modifications affect the duration of layout/reflow/repaint for each frame.

The FPS has to be less than 60fps or the results of the test will be wrong. That's what the fillerCode method is there for.

Well, that was an interesting experiment. :D Now back to the fun UI dev stuff.

from jss.

trusktr avatar trusktr commented on April 27, 2024

Wow, speaking of what I made above, look at this new API just for that reason!

from jss.

kof avatar kof commented on April 27, 2024

Yeah, I think webkit has already had something like this internally

from jss.

kof avatar kof commented on April 27, 2024

when we have it, people can finally start to write rendering performance tests for their libs ...

from jss.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.