I am trying to figure out how I can measure the rendering time of SVG.
When I make changes to the SVG elements (e.g Zoom In or Zoom Out), it takes a few seconds to take effect because SVG is huge.
And I need to measure the time it took to update for performance analysis purposes.
I have tried several DOM events like DOMContentLoaded DOMNodeInserted DOMNodeSubtreeModified but all these events are triggered before changed SVG is rendered on screen.
I have also tried PerformanceTimingAPI and PerformanceElementTimingAPI but no luck.
Thanks in advance!
There’s also MutationObserver but if you’re already experiencing trouble with JS events saying a change happened in the DOM, but you’re not seeing the browser engine re-render, then you might not be able to use JS to measure this and may need to use a more “manual” method.
Try using Chrome DevTools’ Performance recording feature. If you enable screenshots, you should be able to see when the rendering took effect. Combine this with performance.mark() and you should be able to see when you triggered the DOM mutation, and when the screenshot actually updated.
Related
At various points in my 1-page web app I want to do some fairly heavy DOM manipulation, moving various divs around (which each have lots of sub-elements). I don't want the browser trying to repeatedly redraw the page mid-manipulation. Is there a way to say to the browser "pause redrawing until I give the go ahead"?
requestAnimationFrame() seems like one candidate, but is that suitable for DOM rearranging, or just for animation? Are there any other things I could do?
Thanks
You can try using documentFragment.
Create the documentFragment.
Write everything into a documentFragment first.
When done, replace DOM content with documentFragment.
Then the manipulation does not take place on-the-fly, you use the documentFragment as a sort of buffer.
Having discovered requestAnimationFrame just a moment ago, I have dived into all the information I could find about it. To name just a few of the resources I came across in case there are others looking for more info about it:
http://creativejs.com/resources/requestanimationframe/ - explains the basics about it.
http://www.html5rocks.com/en/tutorials/speed/animations/ - explains how to use it.
Anyway, all of these resources tell me something about how requestAnimationFrame works or how it could/should be used, but none of them tell me when it is right to use it.
Should I use it for animations (repeated changes to the style of an element, much like CSS animations)?
Should I use it when an automated event wants to change the css/classes of one or multiple elements?
Should I use it when an automated event wants to change the text value of one or multiple elements? (e.g. updating the value of a clock once every second)
Should I use it when an automated event wants to modify the DOM?
Should I use it when an automated event needs values like .offsetTop, .offsetLeft and then wants to change styles such as top and left a few lines further?
Should I use it when a user generated event causes any of the above changes?
TL;DR: When is it right to use requestAnimationFrame?
You shouldn't yet. Not really, at least. This is still experimental and may or may not reach full recommendation (it is still a working draft at this point). That said, if you don't care about older browsers, or willing to work with the polyfill available the best time to use it is when you are looking to draw things to the screen that will require the browser to repaint (most animations).
For many simple modifications of the DOM, this method is overkill. This only becomes useful when you are doing animations when you will be drawing or moving items quickly and need to make sure that the browser repainting is keeping up enough to make it smooth. It will allow you to ensure that every frame you calculate will be drawn to the screen. It also provides a utility for more accurate time measurements to your animations. The first argument is the time at which the paint will occur, so you can ensure that you are where you should be at that moment.
You should not use it when you are doing many simple modifications to the DOM, or things that don't need to be smoothly transitioned. This will be more expensive on your users' computers so you want to limit this to making things smoother in transitions, movements and animations. Forcing a frame redraw is not needed every time you make a change on the page, since the response will be fast enough most of the time you don't need to worry about that extra couple milliseconds between draws.
As the previous answer says, you should not use it in the discontinuous animation because that don't need to be smoothly transitioned. In most cases, it's used for properties which vary continuously with time.
I want to create my own mouse tracker, like Clicktale and Crazy Egg. Tracking the mouse movements and scrolling shouldn’t be too hard. But what about all changes to the document (HTML, inputs and selects).
Is there an easy way to record all javascript actions on a site. So I can save the actions and later be able to repeat them when I want to replay the visitor’s actions?
Or somehow record all changes that are done to the document (saving the innerHTML everytime there is a change is probably not an option).
The recording must be related to time.
When the recording is done there will be an AJAX request that copies the page and insert the new Javascript in to it so it is possible to watch...
First of all I would like to say that even though the task you are describing sounds to be pretty easy, it is actually far more complex when you dig into it. I should know since I've been spending almost 3 years making stuff like this work and work well for my company Ehavior.
You can use the DOM mutation events to monitor changes to the DOM tree. I guess this will give you what you are asking for. You should be aware though, that the mutation events are only available in newer browsers.
Hope this is still helpful to you, even though your question is a little dated :-)
If I have an img tag like
<img src="example.png" />
and I set it via
myImg.src = "example.png";
to the same value again, will this be a no-op, or will browsers unnecessarily redraw the image? (I'm mainly interested in the behaviour of IE6-8, FF3.x, Safari 4-5 and Chrome.)
I need to change many (hundreds of) images at once, and manually comparing the src attribute might be a little bit superfluous - as I assume, that the browser already does this for me?
Don't assume the browser will do it for you. I am working on a project of similar scale which requires hundreds of (dynamic-loading) images, with speed as the top priority.
Caching the 'src' property of every element is highly recommended. It is expensive to read and set hundreds of DOM element properties, and even setting src to the same value may cause reflow or paint events.
[Edit] The majority of sluggishness in the interface was due to all my loops and processes. Once those were optimized, the UI was very snappy, even when continuously loading hundreds of images.
[Edit 2] In light of your additional information (the images are all small status icons), perhaps you should consider simply declaring a class for each status in your CSS. Also, you might want to look into using cloneNode and replaceNode for a very quick and efficient swap.
[Edit 3] Try absolutely-positioning your image elements. It will limit the amount of reflow that needs to happen, since absolutely-positioned elements are outside of the flow.
When you change a bunch of elements at once, you're usually blocking the UI thread anyway, so only one redraw after the JavaScript completes is happening, meaning the per-image redraw really isn't a factor.
I wouldn't double check anything here, let the browser take care of it, the new ones are smart enough to do this in an efficient way (and it's never really been that much of a problem anyway).
The case you'll see here is new images loading and re-flowing the page as they load, that's what's expensive here, existing images are very minor compared to this cost.
I recommend using CSS Sprite technique. More info at: http://www.alistapart.com/articles/
You can use an image that contains all the icons. Then instead of changing the src attribute, you update the background property.
I am developing a site which creates many table rows dynamically. The total amount of rows right now is 187. Everything works fine when creating the rows, but in IE when I leave the page, there is a large amount of lag. I do not know if this is some how related to the heavy DOM manipulation I am doing in the page? I do not create any function closures when building the dynamic content's event handlers so I do not believe this problem is related to memory leaks. Any insight is much appreciated.
Are you creating the element nodes by hand, or using innerHTML? Although I'm not sure, my suspicion is that IE has its own memory leaks related to HTML nodes.
I made a demo page that adds 187 rows to a table via jQuery. I believe jQuery.append() uses a clever little trick to turn a string into a set of nodes. It creates a div and sets the innerHTML of that div to your string, and then clones all the child nodes of that div into the node you specify before finally deleting the div it created.
http://www.andrewpeace.com/stackoverflow/rows/rows.html
I'm not getting any lag in IE8, but maybe it will lag in the version you're using. I'd love it if you'd let me know! Maybe I can help some more.
Peace
YUI (and probably some other popular javascript libraries) provides automatic listener cleanup, so I highly recommend using YUI or another library with this feature to minimize problems with IE. However, it sounds like you might be experiencing plain slowness rather than any kind of memory leak issue; you are attaching event handlers to a whole bunch of elements. IE6 is known to be less than optimized, so it might just be taking forever to clean everything up.
apeace also has a good point: innerHTML can get you in trouble and set you up with DOM weirdness. It sounds like JQuery has a fix for that.
Try taking advantage of event bubbling to replace all event handlers with just one.
I agree with porneL. Attach one event handler to the <table> and let bubbling work its magic. Most frameworks provide a way for you to find the element that caused the original event (usually referred to as a "target").
If you're making lots of elements using document.createElement(), you can add them to a DOM fragment. When you append the fragment to the page, it appends all the child nodes attached to it. This operation is faster than appending each node one-at-a-time. John Resig has a great write-up on DOM document fragments: http://ejohn.org/blog/dom-documentfragments/