Unsure why jQuery .animate is crashing browser - javascript

I have a site housing a good deal of image thumbnails (currently ~500) on the homepage. Each image is small, about 200px by 150px (but have different aspect ratios). Also small in file size (each is about 10-20k).
I have two buttons to adjust the visible size of the thumbnails (large:200px height and small:100px height).
I decided to use the jQuery .animate function with 0 seconds for the animation to adjust this and keep the ratio of each image:
$('#small_thumbnails').click(function(){
$('.thumbnail').animate({height: '100'}, 0);
return false;
});
This for some reason is causing browsers to become unresponsive and crashes the page. Is it due to the large number of images? I was going to implement lazyload to cut down on the images on the page but lazyload is no longer supported. I could also just write NEW js to do this but am confused as to why the animate function is not capable.
Here is the dev site that has the issue:
http://selfportraitproject.com/dev/
Any help would be greatly appreciated.

Have you tried to use height: '100px' ? That would be the correct syntax, although i don't know why this would crash the browser.
Also calling .animate with a duration of 0 is the same as just setting the css, so just use .css instead, it will perform a lot better.

Related

Responsive image slider particular case

I'm looking for an responsive image slider for a particular case.
This is what I would look to happen on desktop/tablet/mobile.
You can also swipe through the images on tablet/mobile.
It's important that the images don't need to have the same width. (height is always the same)
Does someone knows a js library for this?
I searched but most of the time you only have view of 1 image.
How's this?
http://jquery.lemmonjuice.com/plugins/slider-variable-widths.php
It supports IE6+ and is very lightweight. You can easily make it responsive by wrapping it in a div with overflow: hidden; that varies in width as you require. Alternatively, you could have a go at rewriting it as you require (it's quite a lightweight script!)
The lemmon slider works great with Touch Swipe. The instructions to add this are here:
https://github.com/lemmon/Lemmon-Slider/issues/5#issuecomment-25177163

Repaint slowdown with CSS via Javascript in webkit browsers

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.

addClass that changes bg-image but without a flicker on first load

I'm running a function on every keyboard keyup to monitor a text field.
Depending on the input, I am using jquery to .removeClass("classwithBGImage").addClass("classwithnewBGimage")
This is working nicely, expect on the first load there is a flicker in the background image.
I have tried preloading the images with Javascript and CSS, even tried using a sprite - but there is always a flicker on the first load when .removeClass("classwithBGImage").addClass("classwithnewBGimage") is triggered.
Update:
Seems to be a documented chrome bug:
http://code.google.com/p/chromium/issues/detail?id=102706
As witnessed in this jsfiddle: http://jsfiddle.net/QpvUQ/2/
Any ideas? Much appreciated.
Apply the background-image to a div positioned absolutely and left:-99999px.
#preload{
background-image : url(large-image.png);
position:absolute;
left:-99999px;
}
Later, use it for the actual div
.classwithnewBGimage{
background-image : url(large-image.png);
}
This is one of the hacks that I am aware of for pre-loading images so that they don't take time when you actually use them.
Also, .removeClass() without arguments does nothing. To avoid flickers use smooth transitioning.
.stylesWithoutImage{
///
}
.classwithnewBGimage{
//img
}
Using Move.js you can Animate CSS Changes.
move('.box')
.set('background-image', 'url(img)')
.end();
PS : Not tried but it say's you can animate CSS with it.
I did an implementation with only CSS to do the same than your jsfiddle.
How it works?
.class {
background: url(...);
}
.class:hover {
background: url(...);
}
I left the JS code if you need to do it with Javascript, but with only CSS should be enought.
http://jsfiddle.net/QpvUQ/7/
I've figured out the problem in case anyone else runs into the same issue.
With preloading, the images are preloaded but many browsers still receive a 304 response for the image causing a flicker on first load. You can force the browser to cache images in the case with rails applications.
Enable image caching in development mode in Rails 3.1

JQuery lightbox plugin: Scaling very large images to fit screen

I'm using the jQuery "Lightbox" plugin, although I don't know if that's necessary information about the problem at hand.
The images I'm putting through my slideshow are quite large; each of them is far larger than the screen (I don't host the images on my server so I cannot resize them). I need to scale them to fit within the bounds of the screen (probably with some margin as well). Are there some JQuery or other Javascript snippets out there to take care of this?
Edit
Now I use "zoombox", which certainly fixes the scaling issue. However, now all the nice slideshow features are lost! I.e., I cannot use the arrow keys or cycle through the gallery of images!
Here are three plugins which are pretty feature rich and widely used, they should do the job with ease :
http://www.jacklmoore.com/colorbox
http://fancybox.net/
http://www.grafikart.fr/zoombox
Edit: Pretty much every lightbox solution is listed and compared at : http://planetozh.com/projects/lightbox-clones/
I've settled on Floatbox after testing out a dozen of these libraries. The default settings size the image to fit the screen and allow navigation with the arrow keys. Clicking on an image zooms it to 100%. It's easily configurable in terms of colors, window decorations, and the like.
I forked Lightbox2 to include automatic scaling.
Now, if an image is larger than the window, it will automatically resize to 80%.
You can find it here, on my new repo.

Choppy animated slideshow background on a web page

I'm working on a web page with an animated background. I'm using MooTools to crossfade a series of images that are of a decent size (like 1100px x 750px).
I think since the browser is having to do so much rendering work crossfading these images, when you make the page fullscreen, the crossfade animation will become choppy.
In looking for ways to overcome this, I'm already planning on rewriting the slideshow in the most efficient JavaScript I can muster.
Does anyone have any other ideas on how to have the animated background run smoothly at large browser window sizes?
Crossfade effect is expensive and you'll get very low frames per second at that resolution. Instead of a crossfade I'd try a slide up/down/left/right or wipe effect. I'm a big fan of the jQuery tools Scrollable plugin.
AS you said yourself, this is probably a rendering issue, and not really an issue with the speed of your javascript, especially since there is a performance difference between fullscreen and non-fuulscreen.
I doubt optimizing your js will have any real effect.

Categories