extremely slow CSS3 box-shadows in Chrome - google-chrome

I've been developing an app specifically for modern browsers and have made very heavy use of the box-shadow property.
Until recently this has been absolutely fine on all supporting browsers. However about a month ago when testing in Chrome I noticed that scrolling was 'extremely' slow, to the point of being almost unusable.
Over the past month I have tried ripping out scripts/messing with my html structure, everything you can think of until finally today I have found the cause.
With box-shadow / webkit-box-shadow disabled on all elements that I had it set for, the problem disappears.
What strikes me as odd is that it worked fine in Chrome until around a month ago. Incidentally the scrolling on the windows version of safari is fine, albeit a little slower than IE/Opera and Firefox.
Is this a known problem? Does anyone have a workaround for this?
And most importantly, is there another method of replicating the same effect without using the CSS3 property?

There was a bug report opened and closed in Webkit last year:
CSS3 box-shadow causes scroll-lag (slow performance) on Safari 5.0.2?
It seems Chrome has an open bug on an older version:
http://code.google.com/p/chromium/issues/detail?id=95164
Airbnb discussed the problem recently, and actually changed their final design because of it:
http://nerds.airbnb.com/box-shadows-are-expensive-to-paint
There's a group of people recently gaining an interest in programmatically testing CSS performance. Here's a bookmarklet you can use to start your own testing:
http://andy.edinborough.org/CSS-Stress-Testing-and-Performance-Profiling
In the meantime, you're right that hacking border-image is an option. Check it out here:
Scroll Lag with CSS3 box-shadow property?

It may not be the box-shadow particularly, maybe something else in your app just consumes way too much resource and box-shadow just happens to be the cherry on top.
Nevertheless, I can confirm that box-shadow on overly long or large elements causes performance issues. I work for a certain drag'n'drop form builder and tried setting box-shadow on a 900px x 1000px div and the scrolling started lagging up immediately. Ours is a very ajax heavy web-app, so others might afford to get better results, but still, I think this is a valid example.
So I went old-school and created images instead. I think the most proper way to get image-box shadows working without too much image load is to have an element with a fixed width.
What I did was three image slices. One slice from top to just beneath top corners, one from the bottom to just above the bottom corners and one thin slice from the middle which I used on a div as background image with a repeat-y so that I can dynamically change to divs height fit the users page.
You can slice even more to fit any box but it becomes too much(at least 5 extra images and 8 extra divs to be precise) for a box-shadow imo.

Related

Does negative z-index affect performance or compatibility?

I have a web application where I need to show a 3D model using webGl in the background then showing different stuff on top of it.
All is working VERY fine in firefox except in chrome where I need to give the canvas a negative value for the z-index rule in CSS.
So I would say I need one of two things:
If I fix this issue giving a negative z-index to the canvas, will this cause any harm on to my application in any of the browsers (in both desktop and mobile)
Could anybody guess why its not working in Chrome (perhaps from a previous experince)
I've asked the question differently a second time and I got my answer, for more details check out here: https://stackoverflow.com/a/19830934/1358670

Browser adds a style of border at the bottom in tooltip library (weird behavior)

I've been working in this tooltip library since yesterday. I don't know if this problem is for my sleep or what, but I can't figure what's happening.
The subjacent idea about this tooltip library is simple: The user adds in any HTML element the custom data attribute (I mean data-) with the message that he wants to display in the tooltip, and it has to appear. There are some options to add, like the orientation of the tooltip and if the user wants to "cut" the words inside the tooltip.
Here's an example:
<div data-msg="Hi, I'm a tooltip with a text veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery large" data-orient="right" data-break="yes">Hover me and the tooltip will show!</div>
Everything is fine with bottom, right and left orientations, but when I add the top orientation, the browser adds a species of "border" at the bottom of the tooltip.. I don't know why, but I can't fix it.
Is strange because in the others orientations the problem don't occur.
You can see the problem in the below image (the first tooltip has data-orient="top" and the second tooltip has data-orient="right".
If anyone knows how fix this problem, I'd like to explain me what happens.
Here's the Fiddle.
Thanks,
Leo!
EDIT: I'm working with Chrome 28 version and my OS is Windows 7.
This is a workaround, not a real solution - but shouldn't have any serious side effects in this case (no guarantees, though, see below). And I have little explanation other than this appears to be a Chrome rendering bug.
Add this to [data-msg]::before:
-webkit-backface-visibility: hidden;
backface-visibility tends to fix quite a few Chrome rendering bugs, regardless of the fact that it actually has to do with 3D transforms - it appears to fix this case too.
The reason that it fixes problems possibly has to do with Chrome using a different (hardware accelerated) transition engine the moment you add anything to do with 3D transforms to your element. This may have performance penalties, which leads us to another non-sensical rule that at least used to improve performance if you run into problems:
-webkit-transform: translate3d(0,0,0);
ETA: -webkit-transform alone actually seems to be enough to fix the problem. Experiment with the two, and see if any of them cause other problems.
There have been reports of -webkit-backface-visibility crashing iOS. So do test it there, and try with translate3d instead - or disable the fix specifically on iOS (and live with the bug if it appears there).
As posted in the comments, here's a more minimal example of the problem - although it sometimes fails to... fail, it should mostly have the unwanted darker border at the bottom:
JSFiddle
The bug seems to be caused by transitions combined with border-radius and opacity. Possibly inline-block and padding have a role in the bug too, but sometimes their removal fixes the border, sometimes it doesn't. I hope the backface-visibility workaround is more consistent.

Chrome 27: Fixed Element Leaves Artifacts Behind After JQuery Animation

I have run into a really weird bug. I have an element that the background colors drops off of until you take your cursor and select it.
Here is the page:
http://austinpray.com/test
Here is a video:
https://www.dropbox.com/s/t1f7fnvxslebjwj/2013-05-16%2016.33.21.mov
The video is taken with an iPhone because the issue does not occur when I am using a screen recorder oddly enough. It only happens inside of chrome. I have tried both chrome and a blank install of chromium will all caches cleared and such and this still occurs.
What am I missing? I will update as I do more testing on different devices.
EDIT (05/22/2013):
I did some more research and I found the following behavior:
https://www.dropbox.com/s/7tdz41l89qttmnx/2013-05-22%2017.20.20.mov
The problem seems to arise when animation and scrolling happen at the same time.
I froze the entire site with the issue here: mirror
EDIT:
Example
Here is a stripped down version of my code that actually works:
DEMO
The issue is not present in this one. What is different about the following demo and the code that is causing the issue? I have tried stripping out the parallax background code and that does nothing to fix the issue. I am currently rewriting the entire menu's css to see if I missed something simple.
temporary workaround
After learning a TON about how chrome renders elements (especially fixed elements) I came across this temporary solution:
-webkit-transform: translateZ(0);
I added this to my nav bar's style. This is basically a quirky little hack that does nothing to the page and turns on GPU acceleration. This will have to do for now either until chrome is updated or until I rewrite the entire menu bar functionality. The only downside is that resizing the window suffers a performance hit.
a more elegant solution
After all this research and troubleshooting I figured out that the only real problem is that chrome needs to redraw the element all the way rather than stop at an arbitrary point and leave artifacts. Since the pure CSS solution creates some performance issues I I found an excellent method of forcing the browser to redraw an element via jQuery!
$.fn.redraw = function(){
$(this).each(function(){
var redraw = this.offsetHeight;
});
};
I'm using this on the deployed page and it seems to be working great with no performance hits. I'll keep it around as long as chrome 27 is still floating around.
I also found weird behavior and possibly the root of the problem:
The issue does not occur when I have Compositing for fixed position elements enabled in the chrome about:flags section (chrome://flags/). I am running Chrome Version 27.0.1453.93.
My issue is somehow connected with how chrome handles the stacking context of fixed elements and animating fixed elements as the browser scrolls. This article expands a bit on the changes.
How Chrome handles compositing
GPU acceleration as it related to compositing
As this answer showed up first when searching for this issue I thought it would be helpful to link to another answer that seemed to resolve the problem more fully.
https://stackoverflow.com/a/12023155/2192201
And if you don't feel like clicking through, all that was needed to prevent the artifacts while animating was this one line of css:
-webkit-backface-visibility: hidden

Transparency/opacity issues in Internet Explorer 8

I'm developing a 'one page' website for a customer.
The website displays as I want it in most browsers however I'm experiencing problems in a specific combination of Internet Explorer 8 installed on Windows XP.
Because of a combination of requirements from the customer and the design of the graphical designer different elements are placed on top of eachother and need to fade in or out based on navigation.
All works fine in browsers like IE9&10 (Including IE8 document property in developer tools), Chrome and also IE8 on Win2K8 server.
However in IE8 it seems like the transparency of invisible elements is inherited by 'would be' visible siblings at the same position.
I've searched for different solutions and have tried different things like:
opacity: 0;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
-filter: alpha(opacity=0);
also with an additional but mostly unneccesary:
display: block;
or
zoom: 1;
But none of the above does the trick.
Has anyone experienced, or solved, this problem before.
Or is fading multiple elements at the same position in IE8 just not the right way to go.
See this fiddle for my intended functionality:
http://jsfiddle.net/6HZGw/11/
PS. I tried to post an image of what exactly was my problem but since I've just registered this is not possible as a spam prevention measure.
So here is the link to the problem:
http://img338.imageshack.us/img338/4458/ie8f.png
And the link to the expected view:
http://img255.imageshack.us/img255/8391/chromeothers.png
IE8's opacity filter is really awful. It kinda works some of the time, but it's riddled with bugs and gotchas. jQuery makes it slightly less painful, but even then it's easy to get caught out by one of the quirks.
I don't have IE8 or XP available to test it on right now, but I have been down this path myself and suffered similar results, particularly when dealing with multiple elements, and even more particularly when those elements are a mix of text and graphics.
As I say, I can't try it out for myself right now, but my guess is that you've hit one of those problems that just can't be resolved. So I would suggest looking for alternative solutions.
In our case, after a lot of work, we ended up completely abandoning the idea of fading the elements in and out because of this, and switched to a tactic of sliding them out from behind other elements. The effect was similar enough that the customer was happy, and it worked in all browsers.

What causes lazy/laggy scrolling in CSS?

I have a design I'm creating in CSS, and it has started to sort of, er, lazy scroll. By that I mean the scrollbar lags a bit when you are scrolling. What are common causes of this so that I can debug it from my site?
EDIT:
The document has very little content (not even a paragraph), so not much at all. No flash, two images.
EDIT:
I feel so stupid. Improperly formatted background: property was causing the issue. Thanks nonetheless, everyone.
It's likely to be due to heavy processing requirements via css.
(CSS does affect scrolling in every browser) I have seen this scenario many times (the worst case is with SVG). It usually hits browsers like Chrome hard because of it's AA.
There was a great website that detailed the heaviest to the safest properties to use in regards to CSS effects, sorry I don't have the link. Though from my experience I would say to consider:
Gradients: The more you feature or the larger the area they cover the more exponential the rendering calculations. Abusing stops and additional colors also adds to the mayhem.
Border-Radius: Is usually clipping off its internal content whatever it may be. I've noticed differences when excluded.
Opacity can be the main issue if coupled with other css effects. In certain scenarios I've found great improvements when removing opacity or reducing it's usage. As it's not just transparency it's driving it's also for some browsers anti-aliasing text.
Images: The way images can affect scrolling should be obvious, though I've discovered re-sizing imaged from it's native resolution can become a more noticeable factor.
Use of properties such as background-size:; draws huge power in certain situations, a workaround could be to scrap the div, replace with < img > and overlay with a blank div
containing text/ content.
Animations transitions & translations are obvious power eaters if abused, especially animation that loops continuously or re-sizes to the browser via percentages.
Bare in mind someone on a low spec celeron PC will have a terrible experience on a site that lags on your reasonably/ high powered PC/ mac