The issue discussed in this question happened to me with a production site, but in addition to Firefox, we saw it in IE.
This is how it should look, with all three fading to different pictures intermittently:
We got these screenshots from clients:
Abmormally small images:
Weird sized images:
We were able to reproduce it reliably with Firefox with a hard refresh (ctrl-f5), but the only one in our office that could reproduce it in IE was running IE8 on Windows 7, and then not reliably. The client was using IE7, I believe on XP.
I fixed it by setting up the slideshow in $(window).load() instead of $(document).ready(), but I never figured out why it was so hard to reproduce in IE. Management is unsettled by the fact that we could not reliably reproduce it in IE or explain why it happened, and I've been asked to investigate.
Does anyone have an idea? Does the same issue discussed in the linked question apply to IE in certain circumstances? All I can say at this point is "we can't always pin down things like this."
UPDATE: I was able to make it happen reliably in IE by not setting the src attributes in the slideshows until after I set up the slideshow in Javascript. I think this proves it was indeed the same timing issue, just happening more rarely because IE is a different rendering engine. Management is still curious what other circumstances intervened, but I'm confident now that it was indeed a timing issue in all browsers, and our production site is safe from further issues.
Also, I asked the same question on jQuery forums here and was told to explicitly set image sizes in the img elements. This also fixed the issue.
It's explained in the link you posted. It's a timing issue. Sometime the cycle starts early, sometimes not. And 'sometimes' may just be 'almost never' in some browsers.
Starting the cycle in document.ready ensures that all images have been loaded before the cycle starts so the dimensions are properly detected.
It can very well depend on CPU speed, network latency, browser, OS and whatnot.
The reason it's so hard to reproduce consistently is because the environment is very complex, and the results depend on things you don't see right away.
I know this is late in the game, but I, too very recently experienced this problem. It drove me nuts. The solution is, in fact to use the $(window).load event method to start the cycle plugin--it guarantees that all associated page-load activity (including any downloads associated with ANY child elements) is complete before it fires. It works in all of the 'big five' browsers.
In my case, I am displaying images of different sizes and aspect ratios, and populating the image list automatically by using a server-side script to populate a variable containing dynamically created tags for all the image types in a designated directory that I tell it to include. Consequently, I can't include the image width and height in the tags, because I don't know what they are. In order to get around this, at the client side I use cycle's onbefore: to fire a script that dynamically looks at the image being processed and then sets the slideshow container to a width and height matching the photo's native width and height. I display a "Loading xx photos..." message with an animated GIF loader graphic so that the user knows something is going on while the images are downloaded.
The slideshow(s) in question reside in an area on the hangmanhills.org website that is restricted to Hangman Hills Residents' Association members only, so I can't show you the end product.
Related
I'm experiencing sluggishness in rendering the contents of a scrollable list in my android app built using cordova. You can view an example of the problem in this video, it's from a sample app containing a minimal reproduction of the problem. You can see in these screenshots:
Segments of the screen are slow to paint while scrolling, and the problem seems to particularly affect the text at the bottom of the scrollable list. The source code for the sample app is at this github repo, and you can download the APK here. There are a number of similar stackoverflow posts about this problem, but so far I've not found a workable solution. In particular this post seems to report the exact same problem, but you can see in the source code above that there are not very many requests going out. More so, my video was recorded after the images had fully loaded, so the problem is not because the images are still loading as the main answer suggested. In fact in the main app where I have this problem, the slow scroll starts happening after the images have fully loaded, not before. A comment in that thread also mentions that slow scroll may also be due to touch event listeners that are not passive, but there are no touch event listeners in the sample app as you can see in the source code.
Some other things to be aware of:
optimizing the images may help with the problem, but I'm not sure of this yet as I haven't been able to get the optimization working correctly from the cdn. Nevertheless, I think optimization will at most minimize the problem rather than fix it, but please correct me if I'm wrong
in the index.css file you will notice that I use content-visibility: auto, which can cause some of the images to be re-rendered while they scroll in/out of the viewport. That actually minimizes the problem even if it seems like it worsens the problem. When it's removed the problem gets worse.
You will also notice some hardware acceleration using transform: translate3d(0,0,0); and backface-visibility: hidden, which are intended to push items into a separate layer for compositing. Some people recommend hardware acceleration as a fix for this problem, but it doesn't help in this case. More importantly, hardware acceleration solves other problems in the real app, and even when I remove it this problem still persists.
I'd greatly appreciate your insights/suggestions, thanks! :)
I have a strange problem on a small page I made.
When the content extends the height of the browser and I scroll down fast, the pixelated box appears for a split of a second and then goes away.
Why is this happening and how can I fix this?
Seems to be a chrome issue. I'm noticing this on a lot of websites since I moved from Firefox to Chrome.
This is just Chrome's rendering engine being crap. For the supposed "fastest browser", it fails to render part of the page when scrolling consistently often.
That said, there are some factors involved in when it happens. Generally, it can occur when there's a lot of layout recalculation. This may happen if you have a large table with images loading in, as each image's load causes the table to recalculate. Additionally, JavaScript can often cause recalculation in the layout. And it all depends on how powerful your computer is and how busy it is with other tasks.
I've been working on a slideshow script that uses CSS3 transitions, or jQuery's animate when they are unavailable. I've created a custom function to do the slide animations, which does so appropriately. Everything seemed to be working fine, but I've hit a major snag during testing.
For one reason or another, there is an large delay applying the jQuery CSS before and after the transition on large slideshows. For example, the slideshow in the link below is around 9900 pixels wide (container width, most of which is hidden). The container is maneuvered to display the appropriate slide, using CSS3 transition and transform properties. The delay occurs applying the CSS between lines 75 - 82 in the paste below. In particular, applying the 'transition' CSS causes the problem. Add the 'transition' CSS to the stylesheet (rather than applying it with JS), and delay disappears. This isn't really a solution however, because we only want to use CSS3 transitions on specific properties, that can vary (using 'all' in the stylesheet would transition some CSS that we don't want to animate, but change regularly).
Animation function:
http://pastebin.com/9wumQvrP
Slideshow Demo:
http://www.matthewruddy.com/demo/?p=2431
The real problem is with iOS, in which the slideshow (and even the browser sometimes) becomes completely un-usable. I can't pinpoint any errors, and have really exhausted my knowledge of debugging JS. I'm sure it is related to this section of the function after playing around a bit, and disabling CSS3 support within the plugin altogether removes the problem completely.
I'm completely stuck, and really appreciate any help anyone can give.
--- Edit ---
I've tried applying the CSS with native Javascript rather than jQuery's .css function. Same results, no better performance. Also worth noting that this isn't happening at all in Firefox, and seems to only be a problem with Webkit browsers.
Anyone with a solution, would happy to make a donation towards a few beers! I really cannot figure this out!
--- Second Edit ---
Ok, so been debugging and I can see that the slowdown is caused by the browser repaint cycle that is taking a very long time. Is there a better way to handle this that the way it is already doing? Positioning the element absolutely is a known way to reduce repaints, but that isn't really working because the slideshow is responsive. Absolutely positioning the slide images or the slides themselves causes it to collapse.
--- Third Edit ---
A day later, and I've made some progress. Adding 'transition: all 0s ease' to the elements stylesheet CSS has gotten rid of the repaint caused by adding the inline CSS transition property via the custom animation function mentioned in the original post. This causes a significant performance gain, especially when removing the inline CSS transition property when the transition itself has finished.
Good stuff! However, now there is still a slowdown when the inline CSS translate is being removed (that was used to create the hardware accelerated transition effect itself) after the transition, and the left positioning is being applied. When the two happen together, there is a slowdown.
Breaking them up into two separate tasks (the translate removed, then the left position added in a setTimeout with no time specified), again gets rid of the repaints = performance gain, and looks likes problem solved. But sometimes, the CSS transition property isn't get negated fast enough, and the translate removal gets animated. No good, and don't know where to look next to work around it.
I think the problem is you're loading HUGE images :)
They are too big for the container you have them in, so you scale them down, which is even more resource intensive.
Try resizing them.
First of all congrats for your debugging!
I have been working on the exact same stuff lately and found out that ios devices don't support a large number of images positionned in the same page. It causes crashes and the only solution I found was removing elements instead of just hiding them. The downside is that removing and appending elements causes lags so you have to do it cleverly, when your transitions are done. I thought the best way to go was keep 3 or 5 images in the DOM and replacing the rest with thumbnails of the images, resized to fit the original. When transitions are done, I'd just put the large images back into place...
Hope this helps you a bit on the ios problem at least...
After spending some time analysing your code TimeLine with Chrome Dev Tools, I believe there's some optimization you could do.
As far as I can tell, every single one of your 16 images gets fully repainted every time an animation is requested. This seems quite obvious to me, as there are 16 images in your example, and the Chrome Dev Tools reports 16 long "Paint" executions every time in hit "Next".
In my humble opinion, you should figure out a solution that considers only translating two images: the one you want to hide and the one you want to show. So, consider please, not moving the rest of the images and, instead, leaving them all side-by-side to the shown image.
One more thing, using scaled down images is probably making the paint cycles quite longer. Avoid them whenever you can.
Well, think I've managed to figure it out! Just so you know, original post links don't reflect the changes as I've done them on my localhost environment.
Absolutely positioning the slides container has fixed the problem that was occurring with repaint speeds after the transition had taken place (whilst applying CSS properties). Obviously taking them out of the DOM has done the trick, allowing painting to take place much more efficiently.
I originally didn't try this too much because I knew this would add a lot of work to the resizing functionality. I had originally intended to not resize at all in JS, and rely on percentages to do the dirty work. Absolutely positioning the container would cause the slideshow viewport to collapse, rendering the native resizing useless.
However, I was already having problems with sub-pixel rendering in other browsers anyway, so I guess it was time to bite the bullet and rely on fixed pixel values. I then used JS to handle the resizing, using the window resize event. All seems good, however the slideshow was still collapsed due to the positioning. Assigning height values wasn't working correctly, so was at a bit of a loss.
Thankfully, I came across a neat little trick of setting the 'padding-top' of the slideshow viewport to a percentage value, dynamically calculated (desired slideshow height, set in the settings panel for this script, divided by desired width). As padding-top percentages are relative to the width of the element, this did a great job of providing responsive height and correcting the viewport again (no longer looking collapsed).
Here is some info on using padding-top for responsive elements that maintain aspect ratio. Great little trick: http://f6design.com/projects/responsive-aspect-ratio/
All is good now, and things are working well in iOS and webkit browsers. Everything is extremely quick and working as it should. Four days later, and it is finally figured out. Not happy about having to resort to JS for resizing, but I guess it was always going to happen due to percentage inconsistencies between browsers. Lots of decimals = no good!
Thanks to all who tried to point me in the right direction. Definitely got me thinking, and learned a lot of debugging skills that I can use again to make sure transitions are performing well. Thanks again!
not sure if this helps or not but I noticed you use 3d translation - I would think a simple 2d translation would be enough especially since your third parameter is 0 and might accelerate the issue, also go with fewer images as Armel L. suggested, don't have an iphone to test though... alternatively, this is a solution I used before css3 but should still work move the element containing the images using javascript by modifying left (?and top - the demo only moves left and right though? without the transition effects) and this way you can fine-tune the refresh rate which I think might account for the slowdown... you can go as low as 18 fps without anyone noticing, might even be good enough with just 16fps
I had this when I was first designing a magazine carousel-style page device.
If you have a series of images within a long "tray", even if they are not within the viewport, they will still take up ram, and you can effectively have five or so before leaks and nastiness begin to happen.
What I found works is "hiding" them ... But make sure they take up the physical space necessary.
What I also found worked was that one could make the 'previous' current and 'next' image are visible and move the tray, 'unhiding' them as they reach those three positions.
In my own system, I skipped the 'tray' holding e images and only had them at -100% width, 100% width and the current one a 0.
I never had much luck with the typical long-tray carousel with large scale background images... Especially with css3 acceleration.
I'm currently fighting a very frustrating bug on Safari, and I'm not sure where else to turn.
It seems most elements (but not all, and I can't discern the differentiating factor) that will trigger a focus event will cause all elements on the page that are transitioned or animated to jump ~2px to the top and left. And this only occurs on the first focus event after the page loads.
It's a little annoying to see the bug, as it's in the logged-in portion of droplr.com, and I have been completely unable to distill down a simpler case on JSFiddle.
If you have/create an account and log-in, click on this edit icon for a drop:
You'll see that on the first focus of the page, things jitter. Here's the timeline when there's a single drop on the page and I trigger focus on an offending element:
With more drops, it's just more of the same, but it seems to max out around 40 paints. And the profiler doesn't suggest anything nefarious. Just a trip through jQuery internals.
If instead of laying elements out via a translate3d or matix3d, I simply use top and left, this bug goes away. After hours and hours of debugging this, I'm at a complete loss.
Hoping someone has seen something similar, could take a look, or could give me advice on debugging next steps.
Thanks so much!
Update: Dave Desandro suggested it was the 3d acceleration kicking in, so I tried it out with a translate instead, and sure enough, that did not cause the jitter. I have no idea why the hardware acceleration would be firing up with a focus event though, and only once.
I've tried setting a transformZ of 0 on page load to go ahead and ramp-up the hardware, but no luck there, either. Any more ideas are welcomed.
I've had this issue a while back and honestly I don't remember what exactly was the cause but here are some of the steps I followed:
Check that you don't have hide() and show() for the same element in the next line or vice versa.
Example:
el.show()
el.hide()
Change Custom fonts to "Arial"
For the elements you don't want focus events add this code at the bottom of your scripts:
noFocusElem.off('focus');
This will make sure to remove any focus handlers you might have added by mistake
Finally place your css before any scripts. It's a know fact that adding css rules after an inline style has been applied may cause jitter especially if you're using line-hieght property
Hope this helps :)
I've had this happen when using custom font kits. Could this be the issue? Some events cause custom fonts to re-draw, which can cause a ever so slight "jitter" in page display.
Sometimes, manually setting heights and widths on all the parent HTML elements can reduce the flicker.
I know this question was posted a while ago and this is a bit of a long shot but here goes:
Maybe as a starting point go back to chrome and look at the composite layering:
Hit this into the address bar:
about:flags
You will be able to enable composite borders from within there. The red borders generally indicate a rendering issue:
http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome
What I have found from time to time is that although there are rendering issues in Chrome the browser copes pretty well with hiding them from me. In other webkit based browsers however the result can be more noticable (i.e. android).
I've also seen flickering occur when z-indexes are being used in conjunction with content that is being transformed.
Either way it would be great to know how you resolved this issue (if you did). Post an answer to your own question perhaps?
A way to avoid spending time fixing load time twitches; you could set the page to hidden then make elements visible with the load. If your page is slow to load, you may want to have a spinner default to visible, then have load hide it. Then you could come back to the issue when you have nothing better to do.
Just my 2c worth.
The first thing I would try:
First in chrome, whack in 'about:flags' (yes I know you're not using Chrome). Find the 'Composited render layer borders' and turn it on. Once this feature is switched on you'll get a rough idea of what is being rendered/hardware accelerated.
See: http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome
and look for any rendering problems. These are normally caused by z-indexes. Play around with any z-indexes and hide/show certain elements until the rendering issues are resolved. Then work from there. translate-z hacks and opacity can also cause problems.
From experience I've found rendering problems in other webkit browsers can be diagnosed using chrome. Flickering is a common occurrence on the stock android browser.
Secondly: take a look at the focus event itself and try things like preventing the default behaviour. Seems like a long shot to me but give it a go.
I haven't tested this, so I will be very surprised if it works... but here's an idea:
$(document).ready(function() {
$(document).focus(function(e) {
e.preventDefault();
});
$(document).click(function() {
$(document).unbind();
});
});
I've been running into the same issue recently and found something that fixed it in my case.
Check for anything that's hidden offscreen like:
text-indent: -9999px;
left: -9999px;
Removing any instance of these from the 3d accelerated elements (including children) stopped the content jump on focus for me.
A website I'm currently designing displays and works perfectly in all mac browsers, and Windows Firefox, Chrome and IE 8.
I'm having major problems in IE 7 though. Whilst the CSS is pretty much there (a few tweaks needed), the site is maxing out my CPU at 100% rendering the site almost unusable and giving me scripting errors and javascript functionality is not working.
I don't even know where to start trying to find out what's maxing out the CPU, or how to get more info on the scripting messages - it tells me the line the problem is on but it doesn't tell me what file.
I'd like to provide a link but the client has asked me not to.
Any help would be greatly appreciated.
Thank you
Most likely, this issue is caused by ie's poor png rendering capabilities. In the situation that I have experienced, we were using jquery ui 1.8.7 to render modal dialogs and seeing the memory usage spike by 6-8 mega every time a dialog box was opened. It turns out that the culprit was the opacity and alpha CSS settings in the default jquery styles. See this post for a possible partial fix.
Other things to note include:
There seem to be many fixes that attempt to address this issue.
Jquery 1.8.16 has a partial fix where the large memory jump will only happen when the first dialog box is opened.
We have also experimented by setting a single pixel png as the modal background and this rendering of a single pixel caused the memory used by IE to spike 80 megs and caused a temporary spike in CPU usage.
One other peculiar observation was that if we set the modal value of the jquery dialog to false and created our own modal background by appending a div whose background was set to a semi-transparent png, the memory leak seemed to be smaller.
The short of it was to stop using transparent pngs and the opacity and alpha settings foe rendering in IE.