17

I have noticed a weird performance thing in IE8 when using mouseover events on a table with many rows (100 in this example). I have tried a lot of different approaches but I can't seem to find any way to get it as fast as I like/need.

If I switch classes on each event the performance goes down in all IE versions, and If I use direct manipulation of the CSS through javascript IE6 and IE7 speeds up alot, but IE8 still performs lousy.

Any ideas ? I would really like to know what it is that makes the mouseover event to perform so sluggish compared to all the other browsers.

If this only happened to IE6 I could understand and let it pass, but when the newest version of the browser is the slowest one, there is only going to be more and more users with a bad experience.

Example using JQuery hover: http://thedungheap.net/research/

EDIT: I have now updated the example so that it is easy to see the difference between having 10 rows and 200. This is in the same document, so this cannot be a problem with the whole DOM size, i guess

bobmoff
  • 2,415
  • 3
  • 25
  • 32
  • Would love to hear an answer to this one as I'm having the exact same issue. The problem is that I can't use the css :hover solution as the hover event must change the style of a different element than the one the mouse is over. – Morten Christiansen Nov 09 '09 at 14:34

7 Answers7

5

The :hover IS very slow on IE8, no matter how you intend to implement it. In fact, the javascript onmouseover, onmouseout events provides way faster methods for creating a hover effect, than CSS does

Fastest example on IE8:

<table>
<tr style="background-color:#FFFFFF" onmouseover="this.style.backgroundColor='#000000'" onmouseout="this.style.backgroundColor='#FFFFFF'">
   <td>foo bar</td>
</tr>
</table>

Slower example:

<style type="text/css">
   tr.S1    {background-color:#000000}
   tr.S2    {background-color:#FFFFFF}
</style>
<table>
<tr class="S1" onmouseover="this.className='S2'" onmouseout="this.className='S1'">
   <td>foo bar</td>
</tr>
</table>

VERY slow example: JSFiddle

<style type="text/css">
   tr.S     {background-color:#000000}
   tr.S:hover   {background-color:#FFFFFF}
</style>
<table>
<tr class="S">
   <td>foo bar</td>
</tr>
</table>
lulalala
  • 17,572
  • 15
  • 110
  • 169
Thomas Williams
  • 533
  • 6
  • 9
  • Though I do have the problem, but for this particular example, my IE8 runs fast & fine. – lulalala Jul 09 '14 at 06:10
  • Try adding 100 rows to your sample. Then open your Task list [Ctrl+Shit+Esc] and watch how IExplore goes up to max CPU while you move the pointer back and forth on your rows. – Thomas Williams Aug 10 '14 at 09:07
4

Btw for all browsers you can use :hover selector using css only. And only for IE6 you can add your fastest soluton.

Kane
  • 1,420
  • 2
  • 8
  • 5
1

Try using event bubbling. Add the hover event to the table only, and then look at the target element.

$(function() {
    $('table').hover(function(e) {
        $(e.originalTarget.parentNode).css('backgroundColor', '#ffc000');
    }, function(e) {
        $(e.originalTarget.parentNode).css('backgroundColor', '#fff');
    });
});
Justin Johnson
  • 30,978
  • 7
  • 65
  • 89
  • I tried this before with the same effect, what am I doing wrong? It does not work, example: http://thedungheap.net/research/eventbubbling.aspx – bobmoff Oct 07 '09 at 07:48
0

Have you tried to see what happens if you only have one per row? Curious if it is the number of elements in the DOM [or in each row] could affect performance. Otherwise, it could be an issue with the way ie8 traverses tags in the selector engine. Not really an answer, but something to try.

No IE8 or I'd try it myself.

Mgan
  • 21
  • 1
  • 3
  • I tried with one column only and that is ofcourse faster, it but if i increse the amount of rows to have the equal amount of elements inside the table it is slow again, so it seem to be locked down to how many elements is between inside the table tag. – bobmoff Oct 07 '09 at 08:42
0

Seems fast enough to me, without actually looking at metrics.

You could try mouseover/mouseout instead of toggling. You could also try event delegation, which often helps with this many elements in the dom.

    $("tr").mouseover(function() {
            $(this).css('backgroundColor', '#ffc000');
        })
        .mouseout(function() {
            $(this).css('backgroundColor', '#fff');
        });
ScottE
  • 21,530
  • 18
  • 94
  • 131
  • As Justin suggested, I tried event bubbling(delegation) but cant get it to work, look at the link: thedungheap.net/research/eventbubbling.aspx – bobmoff Oct 07 '09 at 07:58
  • I also tried mouseover/mouseout without any difference in performance – bobmoff Oct 07 '09 at 08:39
0

Sorry to post on an answer this old but I think it is relevant and this page is well ranked by google so...

Wow, I just spent a great amount of time on this problem, I tried to use Javascript, but it was still slow.

This is a solution if you use background images :

This was a real issue for me, because the project I had this problem on was the hover effect on Left and Right buttons / arrows that I use to animate tabs left and right, the tabs would go under the buttons, a tab slideshow if I may say and when the cursor entered the button area the normal image would disappear, the image below would be visible for a few millisecs and then, the hover image would eventually display, ugly.

The real solution was to use image sprites, that way there is absolutely no lag even in pure css. The idea is to have a single image with all the differents images states insides (normal / hover / selected / inactive / etc), you set the image as background-image, and you just adjust the background-position value for the hover effect and others.

If you want to know better about css sprites : http://css-tricks.com/css-sprites/

Michel
  • 1
0

I have faced this issue and implemented the following workaround

var viewTable = jQuery("table.MyTable");
var temDiv = jQuery("<div class=\"HighlightClass\" style=\"display:none\"></div>").appendTo("body");
var highlightColor = temDiv.css("background-color");
viewTable.mouseover(function(eventObj){
    jQuery(eventObj.target).parents("tr:first").css("background-color", highlightColor);
}).mouseout(function(eventObj){
    jQuery(eventObj.target).parents("tr:first").css("background-color","");
});

I hope this could be useful for you.

Amer
  • 1