woocommerce / FlexSlider

An awesome, fully responsive jQuery slider plugin
http://www.woocommerce.com/flexslider/
GNU General Public License v2.0
4.92k stars 1.7k forks source link

loading large amount of images on demand? #310

Closed o-l-e closed 11 years ago

o-l-e commented 11 years ago

Hi, i want to know if there are any ways to load images inside the slider one after one?

To explain, i have used flexslider 2 on a website that some times has up to 50 images in a slideshow, with ca 700x700px images. Obviously this takes time to load, and at the moment i the viewer has to wait up to several minutes to finish loading the entire slideshow, before the first image appears.

I would really appreciate any ideas on how to enhance the "experience" on this. I was hoping that maybe one could "lazy load" the images, or load and show the images one after one as they are ready. Is this even possible with Flexslider?

Anyway, love the plugin, and don't really want to switch to another slider because of this. Flexslider has just the right features.

Thanks in advance.

o-l-e commented 11 years ago

Bump on this. Any tip that sends me in the right direction on this would be greatly appreciated :)

o-l-e commented 11 years ago

Hi again,

Tyler, is it possible for me to send you a link by email to this site i have for a client? I am hoping maybe you could take a look at what is causing the images to load so slowly, and if there is anything that could be done to speed it up.

Would be very grateful.

alexandriacuellar commented 11 years ago

o-l-e,

Are your images saved for web? Make sure your images are 75 dpi and reduce the quality 30%-60%.

Also, if you look on https://github.com/woothemes/FlexSlider you'll see under "Updates" that there is a way to add slides through javascript.

o-l-e commented 11 years ago

Hi alexandria,

and thank you for trying to help :)

The site is using an image resizer that caches resized versions of each image. So this bit is covered. I guess the biggest problem is that all the slides are hidden until loaded, and 40 large images still takes a long time even if resized correctly

The "updates" on adding slides looks interesting, and look forward to seeing the documentation on that. It says coming soon. But i must admit i am not very good at javascript, but still look forward to it.

Thanks again.

alexandriacuellar commented 11 years ago

o-l-e, It may not be officially documented but it is being used. Check stackoverflow.com

alexandriacuellar commented 11 years ago

o-l-e,

lazy loading images is also something I am looking to integrate with flexslider. Through a lot of trial and error I was able to get the new slider.addSlide() function to work for my project on the "end" callback for content that I am adding to the page from a json file. That has helped reduce the initial file size of my page. I am still researching a way to reduce my initial file size even more with lazy loading the images. I didn't find any sample code on that but I did see that someone attempted to use http://www.appelsiini.net/projects/lazyload. Maybe you can give that a try.

o-l-e commented 11 years ago

thanks again Alexandria, but i think i will wait for some documentation on the "add slide/remove slide" as i am not that skilled on mixing scripts like the lazy load.

Also i see this issue is similar: https://github.com/woothemes/FlexSlider/issues/205

Hopefully we will see some update on this. Thanks again though.

danielpuglisi commented 11 years ago

+1

vanilla-thunder commented 11 years ago

Peace! i just made a quick and dirty solution for loading images on demand. I made it only for fade animation and there is no spinner animation or something like this, but it works for me:

open jquery.flexslider.js and somewhere aroud the line 430 starts the function flexAnimate(): // public methods slider.flexAnimate = function(target, pause, override, withSync, fromNav) {

about 100 lines below that you will find the code for fading animation, here are my changes:: } else { // FADE: if (!touch) { slider.slides.eq(slider.currentSlide).fadeOut(vars.animationSpeed, vars.easing);

// ########## loading images ondemand var nextImg = slider.slides.eq(target).children("img"); if(nextImg.attr("src") == "") { nextImg.attr("src", nextImg.attr("rel")); } // ################################

slider.slides.eq(target).fadeIn(vars.animationSpeed, vars.easing, slider.wrapup); } else { slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 });

// ########## loading images ondemand var nextImg = slider.slides.eq(target).children("img"); if(nextImg.attr("src") == "") { nextImg.attr("src", nextImg.attr("rel")); } // ################################

slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 }); ... ...

and on your page move the image's urls from the src attribute into the rel attribute (except the first picture) and let the src attribute be empty, like this: < li>< img src="pic1.jpg" /> < li>< img src="" rel="pic2.jpg" /> < li>< img src="" rel="pic3.jpg" /> < li>< img src="" rel="pic4.jpg" /> so pic1 gonna be loaded ob page load and other pictures on demand

perhaps it can help you with your projects

cheers!

aaronhb commented 11 years ago

Will your code work if you do not load the first image and use the REL for all images?

vanilla-thunder commented 11 years ago

not really: the slider loads pictures only after fading out the actual picture and before the fading in the next one, so the first picture will be loaded after the first loop

o-l-e commented 11 years ago

Hi again,

and thank you for the response, i do have another question about "loading large amounts if images", and hope you can help me.

Never mind the lazy load question, but is there any simple way to not hide all the slides and navigation untill all images have loaded? Ie. simply have the slider containing 40+ images (with retina size) to just A. show the navigation straight away on page load B. just show the loading images one after one as they load naturall (no lazy loading)

This way you would not have to wait for ages untill the 40+ images have loaded, and risk losing the viewer because they don't even know it is a slider untill several minutes later when the slider appears.

I hope you can understand the challenge here, and help point me in a simple direction on basically deactivating the "hide all images+navigation untill slider has finished loading before showing".

Thanks in advance, and keep up the good work with this great plugin :)

mattyza commented 11 years ago

@o-l-e - Sure. :)

The gradual loading of images is the same as lazy-loading. :)

To have the slider show by default and have the images gradually loading in by themselves (like would naturally happen), please use the following CSS example:

body .flexslider .slides > li {display: block; }

I hope this helps. :)

asteriksman commented 11 years ago

Does this answer anyone's question:

// fire the flexslider script (please ensure flexslider.js)
    // Can also be used with $(document).ready()
    $(window).load(function() {
      $('.sliderName').flexslider({
        animation: "fade",
// -----------------------------------
// Lazy-Load type function
        before: function(slider){
            //alert(slider.slides[slider.animatingTo].childNodes[0].src);
            if( $(slider.slides[slider.animatingTo].childNodes[0]).attr("src") == "") 
                { $(slider.slides[slider.animatingTo].childNodes[0]).attr("src", $(slider.slides[slider.animatingTo].childNodes[0]).attr("rel")); }

        },
        start: function(slider){
            //alert( $(slider.slides[slider.currentSlide].childNodes[0]).attr("rel") );
            if( $(slider.slides[slider.currentSlide].childNodes[0]).attr("src") == "") 
                { $(slider.slides[slider.currentSlide].childNodes[0]).attr("src", $(slider.slides[slider.currentSlide].childNodes[0]).attr("rel")); }
        }
// -----------------------------------

      });
    });

</script>

And obviously, setup the image list like so:

< li>< img src="pic1.jpg" />
< li>< img src="" rel="pic2.jpg" />
< li>< img src="" rel="pic3.jpg" />
< li>< img src="" rel="pic4.jpg" />
ivancasbar commented 10 years ago

Hi,

Maybe, anybody need the same but in effect "slide". I hope it´s useful.

// SLIDE:
        if (!fade) {
            var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW,
            margin, slideString, calcNext;
            // INFINITE LOOP / REVERSE:
            if (carousel) {
                margin = (vars.itemWidth > slider.w) ? vars.itemMargin * 2 : vars.itemMargin;
                calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo;
                slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext;
            } else if (slider.currentSlide === 0 && target === slider.count - 1 && vars.animationLoop && slider.direction !== "next") {
                // ########## loading images ondemand
                if ( (slider.direction == "prev") ){
                    var prevImg = slider.container.find('.clone').children("img");
                    var nextImg = slider.slides.eq(target).children("img");
                    if(prevImg.attr("src") == "") { prevImg.attr("src", prevImg.attr("rel")); }
                    if(nextImg.attr("src") == "") { nextImg.attr("src", nextImg.attr("rel")); }
                }
                // ################################
                slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0;
            } else if (slider.currentSlide === slider.last && target === 0 && vars.animationLoop && slider.direction !== "prev") {
                slideString = (reverse) ? 0 : (slider.count + 1) * dimension;
                slider.find('.clone').eq(1).children("img").attr( 'src' , slider.slides.eq(0).children("img").attr('src') );
            } else {
                // ########## loading images ondemand
                if (slider.direction == "next") {
                    var nextImg = slider.slides.eq(target).children("img");
                    if(nextImg.attr("src") == "") { nextImg.attr("src", nextImg.attr("rel")); }
                }else if ( (slider.direction == "prev") ){
                    var nextImg = slider.slides.eq(target).children("img");
                    if(nextImg.attr("src") == "") { nextImg.attr("src", nextImg.attr("rel")); }
                }
                // ################################
                slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension;
            }
            slider.setProps(slideString, "", vars.animationSpeed);
            if (slider.transitions) {
                if (!vars.animationLoop || !slider.atEnd) {
                    slider.animating = false;
                    slider.currentSlide = slider.animatingTo;
                }
                slider.container.unbind("webkitTransitionEnd transitionend");
                slider.container.bind("webkitTransitionEnd transitionend", function() {
                    slider.wrapup(dimension);
                });
            } else {
                slider.container.animate(slider.args, vars.animationSpeed, vars.easing, function(){
                    slider.wrapup(dimension);
                });
            }
        }
padma28 commented 10 years ago

Hi ivancasbar - thanks for this solution :-) How can i put the slide-version into my html? Is this an addition to the first one?

i have now this, but it seems to be wrong - there are only white boxes instead of images, except the first one: //

<? include ("inc.header.php");
?>
<div id="container">
  <div id="slider" class="flexslider">
    <ul class="slides slide-textgross">
      <li> <img src="image-wechselnde/1.jpg">
                  </li>
      <li> <img src="" rel="image-wechselnde/2.jpg" width="1024px" height="700px">  
      </li>//

and so on..