Firefox: Slow performance with large blurred elements - html

I'm facing a little problem with Firefox : when there is large blurred elements displayed on the dom, everything is stupidly slow.
A few things I noticed :
On some modest configurations, a reflow event can even freeze the tab
On high-end GPU, the FPS is slightly better, so I guess this filter is GPU activated
Chrome & Safari are running very smoothly
Even without animation the CPU usage is very high and any interaction is laggy
Ok show me the code
Make sure to click on expand the window so that all the images can show up, otherwise the animation will stay smooth.
I am creating a reflow event with a padding animation to intentionally stress the browser, but the overall interactions are laggy.
On a more complex webpage like CodePen the FPS is way worse : https://codepen.io/creaforge/pen/mLPqNg
Even without firing the transform editing this pen shows some performance issue (try to select blocks of code)
div {
background-color: #eaeaea;
transition: all .5s;
padding: 20px;
}
div:hover {
padding-bottom: 100px;
}
img {
filter: blur(40px);
}
<div>Hover me --> slow animation</div><br/>
<img src="http://www.placecage.com/c/200/600">
<img src="http://www.placecage.com/c/200/610">
<img src="http://www.placecage.com/c/200/620">
<img src="http://www.placecage.com/c/200/630">
<img src="http://www.placecage.com/c/200/640">

Use translate instead of padding. Animating with padding is quite heavy for your computer.

Related

Why are my CSS animations consuming so many resources?

I have realized that CSS animations with keyframes are really hungry for resources.
I've already eliminated the shadows, which increased performance by almost 50% in my case. I've also heard that I should include a rotateZ(360deg) to trick the browser into using GPU acceleration. But even with those "tricks" applied, my star background is really resource-hungry. As soon as you open my website, CPU and GPU usage goes up drastically and remains at a pretty high level.
I'm wondering if there is a better way to perform my desired animation without wasting so much CPU or GPU power.
I wanted a background of moving stars on my website. My solution to this was to create a div for each star, giving it a size, background colour and CSS animation with keyframes. The opacity, x and y position, as well as the speed of the animation are randomized.
The keyframes are the following:
#keyframes linear-translate {
0% {
left: -10%;
transform: rotateZ(360deg); /* rotateZ tricks the browser to use GPU acceleration for better performance */
}
100% {
left: 110%;
}
}
#keyframes linear-translate-initial {
0% {
transform: translateX(0) rotateZ(360deg);
}
100% {
left: 110%;
}
}
Here is an example for one of the div elements (with tailwind CSS classes):
<div class="absolute block bg-gray-200 rounded-full"
style="left: 1%; top: 8%; width: 3px; height: 3px; opacity: 0.381289;
animation: 90.0069s linear 0s 1 normal none running linear-translate-initial,
110.007s linear 90.0069s infinite normal none running linear-translate;"></div>
Link to codesandbox with a working example:
https://codesandbox.io/s/starbackgroundreacttailwindcss-wzers?file=/src/Starfield.tsx
Any ideas on why those animations are consuming so much power and on how to make them more efficient? It's just a horizontal translation after all...
Update:
I tried to layer the stars in div elements of different speeds as suggested by Marco.
My result can be found here:
https://codesandbox.io/s/layeredstarbackgroundreacttailwindcss-wj71q?file=/src/App.tsx:392-445
Unfortunately, the "improvement" is not that great. The CPU usage went a little down, but the GPU usage increased drastically.
I've played around a bit with your sandbox and yes the solution is that simple - there are just to many / different animations / items to handle for the CPU you can see that easily when opening the task manager and checkout the CPU usage while the sandbox is idle with your page. On my "small" machine Firefox uses up to 53% CPU. when i decrease the amount of stars in your script (down to 10) it goes down to around 18%.
I had a similar problem with a "moving div" background with shadows / gradient colors and rotations while moving from left to right...
Interesting project so far.
An idea might be to have a limited amount of layers with multiple stars fixed there and then to move the whole layer (even if you have 10 layers then there are just 10 objects that moves)...
Yes you will not have the same strong effect like calculating / moving each star by its own but with 10 layers as a background (i think its a Background right?) it should not make any markable difference to the viewer...

Hovering changes opacity again and again

The problem is the following: I have a gallery plugin on Wordpress, called Fancy Plugin installed. Works fine, except now when I look at the gallery, the images are very very faint (the opacity is very low), then, if I hover over the image, it gets less opaque, then I hover again and it gets better and better. I need like 10-15 mouse passes for the image to be on opacity close to 0.9, but then it does not change anymore. I want to switch this off completely, I do not want any kind of opacity in the gallery, I want it to be 1. I don't know what CSS to use to do this.
I tried inspecting with Chrome DevTools, that's how I found this piece of code:
<img class="fg-thumb" src="http://www.faktumkft.hu/wp-content/plugins/radykal-fancy-gallery/admin/timthumb.php?src=http%3A%2F%2Fwww.faktumkft.hu%2Fwp-content%2Ffancygallery%2F2%2F2%2Fvizszintes_palcas_korlat__09.jpg&w=200&h=150&zc=0&q=100" alt="Vízszintes pálcás korlát, ívelt" style="width: 200px; height: 150px; opacity: 0.825593;">
I can see the weird opacity number that seems to be kind of random, there, but I don't know how to change it. Can someone help please? Thanks!
Fast fix would be adding next to your css:
.fg-thumb{
opacity:1 !important;
}
However what you find pointing to so called in-line styles, and they may come from some javascript (may be from that plugin). You may want to read some documentation or/and check source code if it is available.

Firefox 34 causes element to vanish unless page repaint

We are running into a weird bug with disappearing elements in the new Firefox (version 34.0.5).
The bug occurs on a page with two (or more) flash objects that are before an other element in the html. Whenever the page is loaded, the element just disappears.
You can see it in this demo:
FF 34 Flash Bug
Just open it in the newest Firefox and you will see the red div disappearing. Every repaint of that page will display it again, e.g switching the browser tab or editing the css via dev tools.
When it does work normally
- One flash file - no matter the position
- Having all flash files after the element in the html
- Having one flash file below and one flash file above the other element (html structure)
What we tried - what it produces
- Repainting the page after flash files are loaded (we are using SWFObject for adding the flash files, but we are not able to attach a load event to the files) - works on the first load of the page (cache clear), doesn't work after refreshes (F5).
- After the page is loaded, scrolling, resizing, changing tabs helps - element is then visible (in some cases)
- Creating an element with width/height with js at the end of the document - helps on first load, after refreshes it doesn't work.
- Animating with css the opacity of the object infinite (we have a wrapper around the flash files and animate this one) - works (not a permanent solution)
- Swf object with a "wmode" other than "transparent" works (not an acceptable solution for us)
What we know
- Bug happens only when MORE THAN ONE FLASH FILE is beneath the element
- Bug happens on flash versions 15 and 16 (these are tested)
- Bug happens in mozilla 34.0.5 (this one is tested)
- Multiple elements after the flash files will also disappear
- When you open the page for the first time, it doesn't show the element. If you then refresh (F5) multiple times, in some cases it will show everything normally, and in some cases it doesn't show the element nor one or both flash files that are overlapping.
Current solution
A constant browser repaint of the disappearing element (or elements!). We do this with a simple CSS3 animation that animates the opacity infinitely between 0.97 and 1 with the duration of 1s.
JavaScript:
if( navigator.userAgent.match(/Firefox\/3[4-9]/i) ){
$('.animation').addClass('firefox34FlashBug');
}
CSS:
.firefox34FlashBug {
animation: 1s linear 0s firefoxFix infinite;
}
#keyframes firefoxFix {
0% {
opacity: 0.97;
}
100% {
opacity: 1;
}
}
That is a very hacky and not a nice solution, but the only "fix" we could find that doesn't change the structure of the html (we need multiple flash files below other elements in our project).
Did anyone else ran into the same problem? We know a couple ways to deal with that behaviour, but we can't explain it yet.
Thank you very much in advance! I hope that we can find a good way of dealing with this problem and that we can find an explanation for the new ninja elements in FF 34 ;-).
Update #1:
Applying border: 1px solid transparent; to a container around every object is fixing it in the demo (also see comments in the answer from akmozo).
This worked for me:
Added to CSS:
.firefox34FlashBug {
animation: 1s linear 0s firefoxFix infinite;
}
#keyframes firefoxFix {
0% {
opacity: 0.97;
}
100% {
opacity: 1;
}
}
Added class="firefox34FlashBug" to my container div outside flash
Note: The demo URL "FF 34 Flash Bug" isn't working, you need to add "index.html" to it. IE http://quickbm.com/ff34flashbug/index.html
Thanks for the fix.
I think that the problem is because your swf objects have absolute positions.
So to avoid this problem, you can put your swf objects into a container and you can use z-index to select it's depth
compared the other elements :
CSS :
.ninja-element {
z-index: 2;
position: absolute;
...
}
.objects {
z-index: 1;
position: absolute;
...
}
HTML :
<div class="objects">
<object>
...
</object>
<object>
...
</object>
...
</div>
<div class="ninja-element">
Watch me disappear in FF 34!
</div>
I had the same problem, but for me it worked to force the browser to repaint just once. After all the SWF Objects are added, I added this line (everything inside of $(document).ready(function() ):
$('#wrapper').css("transform", "scale(1)");
Where #wrapper is a div around the disappearing elements. Scale(1) forces a repaint, but should not change anything about the design (unless you use scale for that element already).
edit:
or maybe better: $('#wrapper').css("-moz-transform", "translatez(0)");, because this will also force a repaint, but only in Firefox.
Just throwing this in there for anyone else.
FF craps the bed when you have a position: fixed element inside a parent element that has been shifted around with left (or something).
To fix this. Shift your parent element around with translate instead.
Spent hours trying to get one of these hacks to work before figuring this out... :(

Chrome redraw issue

I'm getting an odd redraw issue in chrome:
See the broken right side? This is a div with a single background img.
HTML
<div id="resultsSortFilter>
<!-- ... -->
</div>
CSS
#resultsSortFilter {
float: left;
width: 712px;
height: 109px;
margin: 7px 0 0 8px;
background: url('../images/search_sortfilter_bg.png') no-repeat;
}
No issues in any other browser
Happens on newer versions only, we blocked the update to prevent this causing issues internally.
Seems to be triggered by scrolling up and down before rendering is finished.
Same issues on multiple sites
Has anyone else seen this? Anybody knows what's causing it or what Chrome intends to do about it?
Chrome version 26.0.1410.64 m
Update
The issue is on Windows and Mac OS. In fact seems worse on Mac.
I might have pinned it down further. We get the error on a page that contains lots of large images. I'm wondering if it has to do with the size of the data Chrome has to download?
This appears to make the issue go away (not going to call it a fix):
"It might be that the newer version of Chrome simply does not like
your GPU. I have had issues similar to yours and have solved them by
turning off the compositing and 3D acceleration features.
Type
chrome://flags into the address bar and set the following items:
GPU compositing on all pages: Disabled (Three options in a drop-down.)
Disable accelerated 2D canvas: Enable (Click the link that says
'Enable', the box will turn white.)
Disable accelerated CSS
animations: Enable (Like above, the item will turn white.)
Then click
the button that shows up at the bottom of the page Relaunch now to
restart chrome and test if this worked."
From https://askubuntu.com/questions/167140/google-chrome-with-strange-behavior
Update
The issue seems to be gone in later versions of Chrome.
Chrome is getting buggier. Something worth trying is forcing gpu hardware acceleration on the element.
Add this to the CSS to force hardware acceleration:
-webkit-transform: translate3d(0, 0, 0);
I have had problems with this in webkit browsers, not only Chrome.
I solved it by placing the following rule on my CSS:
html *:not(svg) {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0); /*only in IE10*/
}
This applies hardware acceleration on all elements except for svgs on FF/IE/Safari/Chrome if supported.
I do not apply the transformation on SVG tags since for some reason this was causing my svgs to not render properly, oddly applying this to the elements like rect inside the tag itself causes no problems.
So try to add this rule to your css and see if it solves your problem.
I have had this kind of issue when toggling display:none; display:block;
For example with jQuery.toggle()
The element in question was just a wrapper for the content I wanted to show and hide. So this is its parent which would expand or shrink vertically. It would look like this:
<div class="parent">
<div class="child-to-toggle">
</div>
</div>
child-to-toggle had no styling rules and, when hidden, a part of the parent wasn't redrawn correctly. (the bottom part)
Then, I added a css rule to child-to-toggle and the problem was solved. It looks like adding a css rule will force some redrawing in that case.
Despite the accepted answer, I am adding this one because enabling hardware acceleration on my computer, Macbook pro, OSX Maverick, Chrome 36, would completely mess up the UI with artefacts so I had to find another way.
Adding a css rule might help. In my case I added a border-top to child-to-toggle.

Chrome slow scrolling with fixed position elements

On my I have a fixed DIV at the top, 3 fixed tabs and a fixed div at the bottom (this will only be shown when logged in - in the future).
I am getting poor scrolling performance on Chrome only - FF & IE are fine.
I have ready some problem reports about Chrome, Fixed Positioning and Scrolling and wanted to see if anyone had any suggestions? I really would like to fix these elements in their locations but I would also like good scrolling performance in Chrome.
Any Ideas on a fix?
Note: its much more noticeable when zoomed on chrome...
Update: I have read other people have a similar issues and updated this Chrome issue, which was later merged into 136555, allegedly fixed since Chrome 26.
Problem and How to Monitor It
The reason for this is because Chrome for some reasons decides it needs to redecode and resize any images when a fixed panel goes over it. You can see this particularly well with
► Right-Click ➔ Inspect ➔ Timeline ➔ Hit ⏺ Record
► Go back to the page and drag scrollbar up and down (Mouse-wheel scrolling not as effective)
Edit (9/1/2016): Since posting this, Chrome added new features to help monitor this:
► Right-Click ➔ Inspect ➔ Rendering (Bottom tabs)
    ➔ ☑ Scrolling Performance Issues
    ➔ ☑ Paint Flashing
    ➔ ☑ FPS Meter (less important, but can be useful)
This will help you identify exactly what elements require repaints on scrolls and highlight them clearly on screen.
This seems to just be a problem with the method Chrome is using to determine if a lower element needs to be repainted.
To make matters worse, you can't even get around the issue by creating a div above a scrollable div to avoid using the position:fixed attribute. This will actually cause the same effect. Pretty much Chrome says if anything on the page has to be drawn over an image (even in an iframe, div or whatever it might be), repaint that image. So despite what div/frame you are scrolling it, the problem persists.
.
The Easy Hack Solution
But I did find one hack to get around this issue that seems to have few downside.
By adding the following to the fixed elements
/* Edit (9/1/2016): Seems translate3d works better than translatez(0) on some devices */
-webkit-transform: translate3d(0, 0, 0);
Some browsers might require this to prevent flickering
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
This puts the fixed element in its own compositing layer and forces the browser to utilize GPU acceleration.
EDIT: One potential issue was pointed out to me by albb; when using
transform, all descendant position:fixed
elements will be fixed to that composition layer rather than the
entire page.
.
Alternative Solution
Alternatively, you could simply hide the top navigation while scrolling and bring it back in afterwards. Here is an example that could work on the stackoverflow.com's header or a site like theverge.com if pasted in DevTools > Console (or manually type "javascript:" into this pages URL bar and paste in the code below after it and hit enter):
/* Inject some CSS to fix the header to the top and hide it
* when adding a 'header.hidden' class name. */
var css= document.createElement("style");
css.type = 'text/css';
css.innerHTML = 'header { transition: top .20s !important; }';
css.innerHTML += 'header.hideOnScroll { top: -55px !important; }';
css.innerHTML += 'header { top: 0 !important; position: fixed !important; }';
document.head.appendChild(css);
var header = document.querySelector("header");
var reinsertId = null; /* will be null if header is not hidden */
window.onscroll = function() {
if(!reinsertId) {
/* Hides header on scroll */
header.classList.add("hideOnScroll");
setTimeout(function() { header.style.visibility = "hidden"; }, 250);
} else {
/* Resets the re-insert timeout function */
clearTimeout(reinsertId);
}
/* Re-insert timeout function */
reinsertId = setTimeout(function(){
header.classList.remove("hideOnScroll");
header.style.visibility = "visible";
reinsertId = null;
}, 1500);
};
The first solution of #Corylulu works, but not completely (still a little stutter, but much less).
I also had to add -webkit-backface-visibility: hidden; to the fixed element to be stutter free.
So for me the following worked like a charm to prevent scroll down stutter in chrome when using fixed elements on the page:
-webkit-transform: translateZ(0);
-webkit-backface-visibility: hidden;
Edit: Webkit-transform and webkit-backface-visibility both cause blurry fonts and images. So make sure you only apply both on the hover state.
Add this rule to your fixed element,
will-change: transform;
Read about solution from Here,
and read about will-change property from Here.
There's a recent bug report on this particularly annoying issue:
http://code.google.com/p/chromium/issues/detail?id=155313
It has to do with the combination of floating elements and large images. Still a problem on Chrome Canary 24.0.1310.0.
There are a number of ways you could speed up this front end, try out the PageSpeed Insights Chrome plugin for some ideas. Personally I'd recommend rebuilding this front end with the same design on top of a framework like Twitter's Bootstrap, but if you'd like some specifics on this front end:
As you say, the positioning of your header bar is causing the most time in terms of CSS rendering (CSS stress test results). Get rid of that big image that's in there and replace it with a 1px wide background image. You're also resizing images like your logo (and every other image in this header) unnecessarily, replace with actual-size versions
You could save a lot of bytes transferred by optimizing all your content images