Intro
In HTML browser applications timer events are used all over. And it could impact usability of HTML application in various ways. From slowness of UI interaction to memory leaks and eventually death of application.
The application profiling methods are used for code efficiency measurement. Profilers are available in most popular browsers to some extent, but the high level analysis stays in developer's hands and quite subjective. Especially when it comes to comparison of alternative code implementations.
Scope
- expose available measurements of performance and HTML/JS engine load
- enumerate some methods of efficiency improvement
- compare the methods in numbers
Measurements
The timer-related activities in HTML application mostly exposed as timer event
handling. Most popular low-level API is setTimer
, setInterval
, postMessage
and
special use of XHR. Platform also could provide own specific methods.
Difficult part is how to count application performance impact on those timer event handlers changes in attempt to tune them up.
I see the few criterias could be measured:
- Event handler timing. It will be most efficient and adequate method if not
facing few crucial "buts"
- discrete step for timer by JS
new Date().getTime()
stays is in the range of 15-30 ms. Which suppose to be longer of length for most timer event handlers.
But it will work for long (longer of double detectable time) timing events. - due to lack of reasonable functionality in native timer API event handlers are usually wrapped by framework API. Which on its own has big impact on short event handlers. For those in addition to individual handler timing, the framework wrapper need to be tracked as well.
- discrete step for timer by JS
- System CPU load. Obviously it is indirect and not
precise. Will work only in
conditions where CPU utilization is high enough and
impact of say removal of
timer event handler will be
noticeable. The
artificial
bursting of timer event
handler calls to the level of good detection is needed. Also there is no CPU
utilization JS API exist. It could be simulated by count per second of dummy
events.
postMessage
orsetTimeout
w/ zero interval. Just need to be sure that platform does that asynchronously.
Another option is to have constant timeout but incrementally increase the load. Say just loop on heavy math computations. Operations counter per second until the timer interval is reached will give the CPU availability.
CPU load timing is not intrusive and do not chance characteristics of recearched event handler. Also it allows check system load overall. I.e. no special treatment for specific timer event handler. Also could be used for system performance tracking on other recurrent event handlers like drag, mouse movement, progress animations, etc.
Tips
My todo list during timer handlers optimization.
- Check the timing for event handler. If the execution time for event handler is
sizeable (>30ms) than we have easiest case and all needed is the timing stats.
Better to have average computation capabilities and good sampling set. Average
calculation could be oursourced instead of embedded in JS.
Obvoiusly accounting in proper/no exceptions execution: try/finally impacting
the performace themselves
- Collection of timing stats.
console.time
console.timeEnd
will be sufficient
If those are not available (like in IE) - get time @ start
- print delta time @ end in format available for further average processing.
- OR keep global counter and total execution time, printing out average every time @ end
- Collection of timing stats.
console.time
console.timeEnd
will be sufficient
- If event handler execution time is short or you do not want to alter the event
handlers themselves, than CPU load will be the criteria.
- Create the "CPU filler" routine. It shall act as low-priority thread, letting remaining app to run.
- setTimeout with counter increment and comparing of the current time with last detected. Once new time value changed, update the stats: counter per second overall and for last second.
- Other statistics could be handy. Like max time delay between filler calls - matching longest routine. Since there are few routines need to be tracked separately, routine could set it's key and reset last timer value. That key will be used for stats collection.
- Special treatement need to be done for 0 interval: it shall be ignored in MIN stat computation due to minimum detectable interval (~30 ms)
- Trigger on/off collection of stats. Reset stats. The timing functionality could
be expensive. Especially in CPU load timing. The application load for
development comfort need to be as fast as possible.
Also the load timing is a separate problem and shall not be mixed with timer events profiling. From another side it has a reason to trigger profiling programmatically to see the impact in exact conditions and avoid mix with inrelated statistics. Like start on begin drag and stop on release.- Have a global flag(s) or hash map of "profiling enabled" flags. Check the flag before collecting/printing timing
- Have the triggering code on start/stop or after application load. In Web 2.0 application the onLoad for body is not a proper place to start time-based functionality (and obviously the timer events profiling): it is still the heavy initialization phase.
-
Finally on app level
- collect stats for current app.
- validate by simulation of ideal performance tuning: timer event handler have
only
return
in body. - do the real stuff and see how it goes!
No comments:
Post a Comment