Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Web and WebWorks Development

Reply
Highlighted
Retired
Posts: 3,708
Registered: ‎10-16-2008
My Device: Z10
My Carrier: Rogers

PLEASE READ - PERFORMANCE TIP: Speeding up your UI

[ Edited ]

Hi Everyone,

 

I have been doing a bunch of reading lately around innerHTML vs DOM manipulation and general JavaScript optimization tips.  I found a really good article here:

http://www.peachpit.com/articles/article.aspx?p=31567&seqNum=5

 

Even though the article was from 2003, the concepts for the most part still hold true.  Different browsers have different levels of impact based on each optimization.  As I was working through a little project of mine I was finding that my UI updates/manipulation were taking longer than they should so I started to apply some of the optimization tips from the above URL.

 

What I found was quite interesting.  I was doing a lot of DOM manipulation and measuring the pixel lengths of text.  Before optimization my DOM manipulation function was taking 2048ms on a Bold 9700 actual device.  I then applied the trick of removing the element(s) that I was going to manipulate from the LIVE DOM before manipulating them.  I actually pulled out my root div from the <body> tag so that all my updates to the DOM would not reflect in a LIVE change and I could manipulate to my heart's content.

 

 

var parent = myNode.parentNode;
parent.removeChild(myNode);

//.... Manipulate "myNode" ....

parent.appendChild(myNode);

 

 

By simply performing this removal of the node before manipulating it, it brought my time down to 1020ms!!!!  You got it... cut the time in HALF.  The reason for this is that when you manipulate the LIVE DOM it is doing a bunch of things in the background.  Things like re-laying out the page so that  you can calculate element widths etc.  It is also cascading DOM changed events throughout the DOM structure.  Both of these are expensive events and reducing the number of LIVE DOM changes significantly reduces your layout times.  Especially in the BlackBerry browser.  This also shows why using toolkits such as JQuery have a significant impact on UI performance since they are all performing LIVE DOM manipulations cascading events and layouts all over the place.

 

At this point I was quite happy with myself, but I wanted to do some more profiling to see where I could get some additional significant gains.  In my scenario I needed to measure the length in pixels of a string and then size a <div> according to my text.  Basically resizing a <div> for an image button to a text length.  There are a few ways of going about this, and one common example is found in the following link:

http://blog.mastykarz.nl/measuring-the-length-of-a-string-in-pixels-using-javascript/

 

This method of string measurement is dead-on accurate.  The issue is that you need a LIVE DOM <span> node to be able to measure your string.  This causes all of the DOM events and layouts that we were trying to avoid from the above optimization.

 

So what I did was augmented the method shown in the above link for measuring a string.  Instead of using a LIVE DOM <span> node to measure my string, I went through the painstaking effort of enumerating all the keys on the keyboard into a hash table of lengths for the font that I was using so that I could measure the length of the string.  Yes, that meant screen shots into MSFT paint and measuring the letter widths Smiley Sad

 

 

var bbalphasans = new Array();


String.prototype.visualLength = function()
{
  // See if we have already populated the array first
  if (bbalphasans.length == 0) {
    bbalphasans['a'] = 4;
    bbalphasans['b'] = 7;
    bbalphasans['d'] = 7;
    bbalphasans['c'] = 5;

    // Continue until you have all your characters
  }

  var result = 0;
  for (var i = 0; i < this.length; i++) {
    if (bbalphasans[this[i]] == null)  // In case I missed a character
      result = result + 10;
    else 
      result = result + bbalphasans[this[i]];
  }

  return result;
}

 

 

Yes, mind numbing fun!!  But the result was that my DOM manipulation routine that had originally taken 2048ms now took 350ms after my two optimizations!!!  This is because with each string measurement it was firing DOM events and re-laying the page.  The more and more measurements I did, the longer that things took.

 

So in summary the performance gains looked something like the following:

 

On an actual Bold 9700

Original DOM manipulation time: 2048ms

Removed element from LIVE DOM before manipulation: now 1020ms

Manually calculated text size: now 370ms

 

On the Bold 9700 Simulator

Original DOM manipulation time: 570ms

Removed element from LIVE DOM before manipulation: now 300ms

Manually calculated text size: now 78ms

 

This also shows you that small amounts of improvements in the simulator are exponentially valuable on an actual device.  These small changes in performance are definitely noticeable by your end user.

 

After being very proud of myself, I figured I would share my experience Smiley Happy

 

Cheers

 

 

 

 

Tim Neil
Director, Application Platform & Tools Product Management
Follow me on Twitter
Contributor
Posts: 13
Registered: ‎04-21-2011
My Device: Playbook
My Carrier: AT&T

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

Tim,

Thanks for sharing this! I am going to revisit my Playbook WebWorks app and see if I doing anything that could benefit from this optimization.

I was curious why you needed to size a DIV to a string of text instead of using something like inline-block or a float to cause the div to auto size to the length of the string.

Cheers,
Doug


Doug Neiner - Official jQuery Team Member, Senior Designer at appendTo
http://dougneiner.com | @dougneiner
Retired
Posts: 3,708
Registered: ‎10-16-2008
My Device: Z10
My Carrier: Rogers

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

Hi Doug,

 

My example was done on a BlackBerry 5.0 device that has some "quirks" with CSS Smiley Sad

 

 

Tim Neil
Director, Application Platform & Tools Product Management
Follow me on Twitter
Developer
Posts: 71
Registered: ‎02-04-2011
My Device: Blackberry Bold & Pearl
My Carrier: Telecom NZ

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

I'm doing lots of dynamic text manipulation in my current app, just a thought, instead of measuring the text by hand couldn't you have looped through the alphabet appending the letter to an absolutely positioned div with no padding, margin, or border and written out the text size that way?

Developer
Posts: 669
Registered: ‎02-19-2011
My Device: BlackBerry PlayBook 32GB
My Carrier: Sprint

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

I tried to apply this to my app 'Screamager' and had no success unfortunately.

When running animations it 'renders' each frame by setting css classes on every 'dot' in two nested loops. This manipulation happens on the live DOM.

 

What I did was clone the 'screen', perform all my manipulations on the clone and then bang the clone's innerHTML to replace the previous frame.

 

One would EXPECT that to be way faster but in reality there's no difference. In fact it even seemed to introduce some added choppiness.

 

I'm overall a bit disappointed in the speed of the browser. The simulator is definitely faster with a lot of things. My animations run almost twice as fast in the simulator compared to the real device.

 

Tim, do you know how much optimization is still left to work on for the webkit engine team? Is this 'it' or can we expect rendering speed improvements as time passes?

Staff UI Prototyper (read: full-time hacker)


My BB10 apps: Screamager | Scientific RPN Calculator | The Last Weather App

Developer
Posts: 669
Registered: ‎02-19-2011
My Device: BlackBerry PlayBook 32GB
My Carrier: Sprint

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

Ok i was totally wrong. It DOES make a difference. A huge one even. I think I got about 40% performance gain in playing animations by taking the display node out of the DOM, doing the rendering and then inserting it back in. The app just became a LOT better.

 

VERY cool indeed!

Staff UI Prototyper (read: full-time hacker)


My BB10 apps: Screamager | Scientific RPN Calculator | The Last Weather App

Retired
Posts: 3,708
Registered: ‎10-16-2008
My Device: Z10
My Carrier: Rogers

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

I'm glad to see that it worked out for you Smiley Happy

 

Live DOM manipulation is just plain nasty because of the constant re-layouts in memory.  Even though the display isn't updated until the JavaScript thread ends, it is still doing all that re-layout calculation in the background on each line of JavaScript that touches the DOM so that the next line of JavaScript can read the changes Smiley Sad

Tim Neil
Director, Application Platform & Tools Product Management
Follow me on Twitter
Trusted Contributor
Posts: 152
Registered: ‎02-12-2011
My Device: Not Specified

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

TheMarco How this it make it better when playing animations? does the animation play AFTER you re-insert the node back into the DOM? please explain
Developer
Posts: 289
Registered: ‎10-17-2008
My Device: Torch 9800
My Carrier: Rogers

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

Hi Tim,

 

Would you expect to see similar performance benefits when using jQuery if I used .hide(), then manipulate, then show()?

 

Thanks,

 

feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
Retired
Posts: 3,708
Registered: ‎10-16-2008
My Device: Z10
My Carrier: Rogers

Re: PLEASE READ - PERFORMANCE TIP: Speeding up your UI

I would doubt it.. hide() will make it invisible, but not out of the DOM

Tim Neil
Director, Application Platform & Tools Product Management
Follow me on Twitter