While tracking down IE quirks and trying to gain rendering performance in the overlay, I tried to use a transparent PNG instead of using an opacity filter, since it generally renders faster than opacity. And it does ! Everything really runs smoother and is less CPU intensive in all versions of IE.

Then came the time to make this without too many tricks and without any javascript if possible.
Long story short : I ended up by simply using a transparent png for all browsers.

Incredibly, it renders faster in Safari and Firefox too ! Less obvious, but anyway.

To test this, open one window with the patch, one other without, and resize the window rapidly while the overlay is displayed. The module page is a good test. If anyone has a more scientific approach... :)

Bottom line : this brings big performance gains in overlay rendering.

Put the overlay-bg.png image in /misc.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jide’s picture

Issue tags: +Performance

Tagging.

Kiphaas7’s picture

Looks great! But did you run the .png through smush.it? I know, it's a micro optimization, but it shouldn't have any drawbacks... I got a 40 byte decrease.

http://developer.yahoo.com/yslow/smushit/

Dries’s picture

Status: Needs review » Needs work

1. Overlay specific images should live in modules/overlay/images not in misc.

2. Let's name the image background.png.

3. I'm not a big fan of those IE6 specific filter hacks so it would be good to get more people to confirm that this improves performance.

Kiphaas7’s picture

Straight from head:

.ui-widget-overlay {
  background-color: #222;
  opacity: 0.85;
  filter: alpha(opacity=85);
  background-image: none;
}

It would be just trading one filter for the other. Yes, filters are bad in IE (6), but there is no way around it if you want something at xx% opacity in IE6.

However, the impact on IE6 between these 2 filters could be different.

EDIT: even better, since the star hack in the patch only addresses IE 6, IE7 and beyond shouldn't have to bother with the filter: alpha(opacity=85); anymore.

Only real downside with the patch I can see is that it won't be so easy to change the opacity, as in, it would require a new image instead of just changing the opacity in css.

jide’s picture

FileSize
70 bytes
1.1 KB

@Dries :

1/ I hesitated, but seems logical.

2/ Let's do this.

3/ As I explained, this is not an IE6 hack. This affects all browsers performances.
And in fact, using background image can feel less hacky in a way, since instead of :

  // Standard browsers
  opacity: 0.85;
  // IE6, IE7 and IE8 hack :
  filter: alpha(opacity=85);

We do :

  // All browsers
  background: transparent url(images/background.png) repeat;

The only "hack" is to support IE6 specifically :

* html .ui-widget-overlay {
  // IE6 specific
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='modules/overlay/images/background.png', sizingMethod='scale');
  background: none;
}

I have numbers. Using a rough testing snippet (Sorry it's ugly, but useful) :

(function ($) {
Drupal.behaviors.testOverlay = {
  attach: function (context, settings) {
    if (this.processed) {
      return;
    }
    this.processed = true;
    
    // Window resizing
    var testResize = function() {
      window.resizeTo(300, 300);
      window.scroll(0, 0);
      var start = (new Date).getTime();
      var size = 300;
      var interval = setInterval(function() {
        if (size >= 800) {
          clearInterval(interval);
          var diff = (new Date).getTime() - start;
          alert(diff);
        }
        size = size + 10;
        window.resizeTo(size,size);
      }, 10);
    };
    
    // Window scrolling
    var testScroll = function() {
      window.resizeTo(1000, 1000);
      window.scroll(0, 0);
      var start = (new Date).getTime();
      var size = 0;
      var interval = setInterval(function() {
        if (size >= 1200) {
          clearInterval(interval);
          var diff = (new Date).getTime() - start;
          alert(diff);
        }
        size = size + 10;
        window.scroll(0, size);
      }, 10);
    };
    
    // Launch test
    $('#toolbar').click(function() {
      //testResize();
      testScroll();
    });
  }
};
})(jQuery);

I got these results :

Results pattern :

Browser :
WITH PATCH or WITHOUT PATCH : min value / max value = average value
GAIN / LOSS difference in percentage

- Window resizing :

Firefox :
WITHOUT : 2155 / 2452 = 2303,5
WITH : 1760 / 2060 = 1910
GAIN : 120%

IE8 :
WITHOUT : 5668 / 5978 = 5823
WITH : 2634 / 2864 = 2749
GAIN : 211%

IE6 :
WITHOUT : 12828 / 13209 = 13018,5
WITH : 3795 / 3905 = 3850
GAIN : 338%

- Scrolling results :

Firefox :
WITHOUT : 2113 / 2090 = 2104,5
WITH : 1501 / 1509 = 1505
GAIN : 139%

Safari :
WITHOUT : 8554 / 8615 = 8584,5
WITH : 5850 / 5864 = 5857
GAIN: 146%

IE8 :
WITHOUT : 6779 / 6830 = 6804,5
WITH : 8422 / 8943 = 8682,5
GAIN : 78% (performance loss)

IE7 :
WITHOUT : 7330 / 7350 = 7340
WITH : 9794 / 9814 = 9804
GAIN : 75% (performance loss)

IE6 :
WITHOUT : 1322 / 1352 = 1337
WITH : 1482 / 1513 = 1497,5
GAIN : 89% (performance loss)

I could not test resize in IE7 from IETester and Safari since they both do not allow window resizing using javascript.

So overall this is a performance gain, although it seems to impact performance negatively for IE on scrolling.
Otherwise, all browsers see performance improvements in all situations.

At least we have concrete data !

I attached an updated patch according to Dries suggestions and a minimized png image.
background.png should go in modules/overlay/images.

jbrown’s picture

jbrown’s picture

FileSize
68 bytes

Knocked 2 more bytes off background.png .

jide’s picture

@jbrown, about #6 :

In our case, this affects only IE6, since we use a regular background for other IEs.
And performance benchmarks show better results than with opacity.

This background image will disappear if we continue to shrink it down :)

jide’s picture

Status: Needs work » Needs review

I updated the test snippet :

(function ($) {
Drupal.behaviors.test = {
  attach: function (context, settings) {
    if (this.processed) {
      return;
    }
    this.processed = true;
    
    var diffResize;
    var diffScroll; 
    
    // Window scrolling
    var testResize = function() {
      var start = (new Date).getTime();
      var size = 0;
      var interval = setInterval(function() {
        if (size >= 1000) {
          clearInterval(interval);
          diffResize = (new Date).getTime() - start;
          testScroll();
        }
        size = size + 10;
        window.resizeTo(size, size);
      }, 1);
    };
    
    // Window scrolling
    var testScroll = function() {
      var start = (new Date).getTime();
      var size = 0;
      var interval = setInterval(function() {
        if (size >= 1000) {
          clearInterval(interval);
          diffScroll = (new Date).getTime() - start;
          alert('resize: '+diffResize+' scroll: '+diffScroll);
        }
        size = size + 10;
        window.scrollTo(0, size);
      }, 1);
    };
    
    // Launch tests
    $('#toolbar').click(function() {
      testResize();
    });
  }
};
})(jQuery);

And updated results :

WITH PATCH :

IE8 : resize: 5107 scroll: 6499
IE8 compat 7 : resize: 4696 scroll: 6610
IE6: resize : 6740 scroll: 1191
FF: resize: 4094 scroll: 1307
Safari: resize: N/A scroll: 4983
Chrome: resize: N/A scroll: 4048

WITHOUT PATCH :

IE8 : resize: 12057 scroll: 6519
IE8 compat 7 : resize: 11657 scroll: 6229
IE6: resize: 23223 scroll: 1512
FF: resize: 4862 scroll: 1765
Safari: resize: N/A scroll: 5009
Chorme: resize: N/A scroll: 6702

Forgot to set this back to CNR.

jide’s picture

Just to clarify, window resizing is awfully slow in all versions of IE and this patch addresses this issue. This is very annoying for IE users, and unfortunately, there are still a lot of them ;)

If we want to have a good user experience out of the box, I think this patch is a good thing.

Moreover, all browsers benefit from these performance gains and CSS is cleaner, apart from the IE6 specific CSS rule.

Dries’s picture

The performance results are very convincing. Let's get some more IE users to test this, and report back.

jbrown’s picture

Is there any performance increase if the background image is bigger than 1x1?

jide’s picture

@Dries : Yes, more testing would be nice, particularly for IE.

@jbrown : Cannot hurt to try, I'll give it a shot.

jide’s picture

And... yes ! it does render faster with a bigger image, at least on IE8.
My first tests show improvements until around 250x250 pixels, above it decreases.

I'll make some more robust and complete tests later.

Status: Needs review » Needs work

The last submitted patch, 704182-overlay-bg-5.patch, failed testing.

jide’s picture

Status: Needs work » Needs review

Hmmm, finally, changing image size is not so much faster.

Here are new tests for different image sizes (what a PITA to run those).
Each row represents an image size (50 means 50x50 pixels).
10 pixels seems the most optimal size, so I ran test twice for 1 pixel image and 10 pixels image on IE 6, 7 and 8.
Does not seem to affect performance in other cases.

FF: No visible change
1/ resize: 3992 scroll: 1335
10/ resize: 3964 scroll: 1337
50/ resize: 3861 scroll: 1326
100/ resize: 3906 scroll: 1383
200/ resize: 3994 scroll: 1321
250/ resize: 3838 scroll: 1332
300/ resize: 3886 scroll: 1324
500/ resize: 3907 scroll: 1333

IE8: 10px image is faster
1/ 4537 6259 - 2nd pass : 4606 6370
10/ 4217 4897 - 2nd pass : 4186 4877 - is faster than 1px
50/ 4146 4987
100/ 4146 4897
200/ 4206 4888
250/ 4396 4717
300/ 4115 4707
500/ 4417 4857

IE8 compat 7: 10px image is faster
1/ 4416 6339 - 2nd pass : 4366 6319
10/ 3906 4867 - 2nd pass : 3936 4696 - is faster than 1px
50/ 3965 4867
100/ 4016 4777
200/ 3946 4697
250/ 3925 4717
300/ 3986 4607
500/ 3876 4766

IE6: No visible change
1/ 6670 1202 - 2nd pass : 6359 1212
10/ 6890 1152 - 2nd pass : 6549 1172
50/ 7040 1162
100/ 7300 1212
200/ 7471 1191
250/ 7491 1202
300/ 7701 1192
500/ 7851 1172

Setting this back to CNR, since bot is wrong I think.

Dries’s picture

Thanks a lot for the rigorous testing jive. Great job.

As next steps, it sounds like we'll want to reroll the patch with a 10x10 image.

jide’s picture

FileSize
118 bytes

Thanks Dries.

Here is an updated image, I upload it here first and will pass it through smushit in the next comment.

jide’s picture

FileSize
78 bytes

Here is the image shrinked down through smushit.

@jbrown : Some more bytes to knock off ?

jide’s picture

Patch from #5 still applies.

jbrown’s picture

FileSize
76 bytes
aspilicious’s picture

#5: 704182-overlay-bg-5.patch queued for re-testing.

Dries’s picture

Status: Needs review » Fixed

Committed to CVS HEAD. Thanks jide.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Gábor Hojtsy’s picture

Priority: Normal » Critical
Status: Closed (fixed) » Needs review
FileSize
572 bytes
13.9 KB
13.83 KB

There is a little problem with this change. Now that we use the same properties as jquery.ui.theme.css does, we need to take care of possible overrides happening. And indeed, if jquery.ui.theme.css is loaded before overlay-parent.css, the overlay backrgound dim will almost look as if it is not there. It is a white-is very transparent layer in that case. So we should make sure we override the jquery.ui.theme.css declaration even if it is put in the document after our style.

Images of before and after the patch:




casey’s picture

Priority: Critical » Normal
tstoeckler’s picture

@Gábor Hojtsy: Could you provide some way of testing this? I'd like to help, but don't really know how.

Gábor Hojtsy’s picture

@casey: I believe if the overlay is incomprehensible from the rest of the page and they look like mashing together, it is a pretty big problem.

@tstoeckler: just get jquery.ui.theme.css load after overlay-parent.css. I'm not entirely sure how the weight calculations end in my setup to get that, but they certainly do. Here are two screenshots of Safari's inspector showing how the theme css overrides the parent.css unless parent.css is more specific.

Without the patch:

With the patch:

casey’s picture

Status: Needs review » Closed (fixed)

Overlay is no longer based upon jQuery UI dialog; #668640: Overlay shouldn't be based on jQuery UI Dialog.

jide’s picture

I'm totally out of core issues right now because of work, but I saw the issue about the rewrite of the overlay without jquery ui.

Anyway, does the patch use opacity for the semi-transparent background ? In this case, performance is still to be considered and a PNG background will most probably be faster than opacity, so this should be considered.

casey’s picture

Core still uses the PNG background.

JohnAlbin’s picture

Assigned: jide » Unassigned
Priority: Normal » Major
Status: Closed (fixed) » Needs review
FileSize
64.04 KB

Up in #25, Gábor shows what the overlay looked like before the updated image in #21 landed.

And the overlay is way, way too dark now. The purpose of the overlay is to provide context and having the background image be nearly black negatively effects that context.

I reviewed all the images above and, indeed, all the images after comment #7 are too dark. It seems you guys over-“smushit”ed it. ;-)

I think we should use the image from comment #7. <-- this is my patch.

Here's a screenshot of what the current overlay looks like followed by what it looks like with the image from comment #7.

Jeff Burnz’s picture

FileSize
54.59 KB
78 bytes

I made a new png thats 75% #000, 10x10, screenshot shows comparison to the current background.png (on the right), on the left is the new one attached here. Its the same size 168 bytes (Drupal says its 78, but Fireworks tells me its 168). Its been smushed ;)

The one is #7 is just 1px square, but as far as I can see the 10px square image is more performant - I would concur with this, although I have not bench-marked this anecdotally I would say this is true, for many years I have sized tiles like this to 10x10 as they just seemed to be faster.

Just out of interest did anyone bench-mark adding the bg in an img element and stretching it?

Overlay background comparisons

JohnAlbin’s picture

Status: Needs review » Reviewed & tested by the community

I've confirmed that the image in comment #33 produces a #404040 grey when overlaying a white background. And the image in comment #7 produces a #414141 grey when overlaying a white background. Close enough for me!

Just out of interest did anyone bench-mark adding the bg in an img element and stretching it?

That would require additional markup with z-index and… blech. It might be more performant, but it's a can of worms with browser support. Let's commit the modules/overlay/images/background.png image in #33.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

deekayen’s picture

Status: Fixed » Needs review
FileSize
76 bytes

The last commit wasn't smushed. This one is by ImageOptim.

mikey_p’s picture

Status: Needs review » Reviewed & tested by the community

I tested this with the resources tab of Chrome and Digital Color meter on OS X. Both images report the same color value and it does save a whole 2 bytes.

Whether or not this is really necessary? I have no idea, but it works as advertised, and I see no issues with committing it.

deekayen’s picture

My explanation for doing so is in #13 of #552000: Smush core images.

Jeff Burnz’s picture

I can't see any perceivable difference in this new image and 2 bytes is 2 bytes - good to go!

FYI it was smushed so maybe this smushing is not the best png optimizer out there? Think I'll stick to using using minipng.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Smushed!!

Committed #36 to HEAD. Thanks!

Status: Fixed » Closed (fixed)
Issue tags: -Performance

Automatically closed -- issue fixed for 2 weeks with no activity.