Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

progressive loading issues with prev/next buttons and paused slideshow #111

Closed
albell opened this issue Mar 2, 2013 · 11 comments
Closed

Comments

@albell
Copy link
Contributor

albell commented Mar 2, 2013

I'm using the progressive loading pattern with previous/next buttons. I'm hiding the "previous" button at the beginning, and the "next" button at the end of the slideshow with "data-cycle-allow-wrap='false'". (Actually for development I'm just dimming the opacity of the buttons so you can see what's going on.)

The issues are:

  1. When the slideshow initially launches, both the previous and the next buttons have the "disabled" class!

  2. My declaration of data-paused="true" isn't getting any respect, and the slideshow is auto-advancing:

https://gist.github.com/baloneysandwiches/5069370

**** UPDATE ****

Putting two slides (images) in markup instead of just one partially solves the first problem. With two images in markup, and the rest loaded via script, only the "previous" button initially gets the "disabled" class.

But this doesn't solve the auto-advance problem. Even though the first slide stays correctly paused on initial load, when the user gets to the second slide, the auto-advancing behavior kicks in. Also, the "next" button retains the disabled class, even though there are slides left to show. The counter that I'm using for the caption also isn't being incremented to the total number of slides until all the slides have actually been shown. I really can't tell why your "manual" progressive demo works and my code doesn't. See:

https://gist.github.com/baloneysandwiches/5086702

As a separate but related issue, one problem with the "progressive" loading pattern is that it doesn't provide any kind of preloading capabilities. What I'd really like is an intermediate option, combining progressive loading with a preloading option, where, for each slide, all imgs in the "next" slide are requested in advance, but only at the time that the current slide is shown. I'd like the user to be loading the imgs in the next slide while he's looking at the current slide.

For a consecutive, sequential, non-random slideshow that's really large, my One True Big Slideshow Pattern would be to load the first two slides in markup, and the rest in script, with a preloading option. It seems like this could be addressed by hardcoding the "1" in this line of the progressive plugin:

            if ( fwd && opts.currSlide == ( opts.slideCount-1) ) {

to be a "2", so that the loading behavior is always one slide ahead, but I would really like to see this exposed as an full-fledged option.

NOTE: My concern isn't bandwidth per se. It's that if I have 150 slides in a slideshow's markup (yes, I've done this), the browser fires off 150+ many requests during load. This is normal, but the problem is that things that are immediately visually necessary (e.g. CSS background images in the page's header) get put in the hopper last, after the 150th image, even though that background image is more urgently needed in terms of visual layout. The result is a background image that, on slow connections, takes a full minute to appear! Given modern browser pre-parser behavior, the only way to work around this is taking the later slides out of markup, and waiting until page load fires to call them via script.

@daltonrooney
Copy link

Regarding your second issue, related to preloading slides, take a look at how I do it: https://gist.github.com/daltonrooney/4726327

I only include src images for the first two slides, and load the rest one by one from a data attribute as the slideshow advances. This seems to be a pretty good workaround, I'm loading 50-100 slides with large images and it was much too slow otherwise.

@albell
Copy link
Contributor Author

albell commented Mar 15, 2013

@daltonrooney Excellent. I've generalized the pattern so the options aren't hardcoded:

https://gist.github.com/baloneysandwiches/5173623

I'm using Paul Bonser's Tiniest GIF Ever (smaller even than your data-URI :p, and also old-IE compatible).

The Good

• Full progressive loading with "one-slide-ahead" preloading.
• Simple as hell. Just ten lines of code.
• Full layout calculations on initial page load. The slides are all in the DOM to begin with, including the inline dimension attributes, which are essential for layout calculations when mixing sizes. (It's impossible to get the naturalHeight and naturalWidth of an unloaded image.)
• Keeps the slides in markup. Arguably easier to maintain and troubleshoot.
• No issues with having to escape special characters in slide texts to deal with them being parsed as JSON. That seems potentially error prone, especially on a frequently-updated site.
• No extra specialized script tags in the body, etc.

The Bad

The 1x1px dummy GIF leaves the horrible taste of 1999 in my mouth. More than just an extra HTTP request, it just feels hacky. Still, this might be the best progressive loading solution at the moment.

@malsup
Copy link
Owner

malsup commented Mar 17, 2013

Looks like this would be a useful optional plugin for C2.

@malsup
Copy link
Owner

malsup commented Mar 17, 2013

BTW, progressive slides don't have to be JSON. Markup inside the script tag works. See example #3:

http://jquery.malsup.com/cycle2/demo/progressive.php

@malsup
Copy link
Owner

malsup commented Mar 17, 2013

Here's an example that uses a generic plugin (jquery.cycle2.lookahead.js) and assumes only a convention of using data-cycle-src attributes on your images with the real source path. You choose if you want to use tiny images or data uris.

http://jquery.malsup.com/cycle2/demo/lookahead.php

plugin:

http://jquery.malsup.com/cycle2/jquery.cycle2.lookahead.js

@daltonrooney
Copy link

That is really nice, thank you Mike!

@dfector
Copy link

dfector commented Apr 5, 2013

I'm not sure if this is related. But in attempting to use the progressive loading with the carousel plugin, the slides are appearing stacked. The progressive loading seems to be defining the inline styles of the slides as position:absolute rather than position:static They also seem to be loading into the DOM outside of the cycle-carousel-wrap.

@albell
Copy link
Contributor Author

albell commented Apr 29, 2013

Mike, the only trouble with the lookahead.js as you've written it is that it breaks auto-height: calc with slides of mixed sizes, because the image dimensions of the later slides can't be calculated. Your demo works perfectly partly because your demo slides and the 1x1 placeholder image are both square :)

Pure CSS doesn't help with the 1x1 placeholders, because it goes by the natural dimensions. height:auto sets the height to be the computedWidth times the naturalHeight divided by the naturalWidth. In other words, since the "naturalProportion" (coining a term here) of the 1x1 placeholders is always 1, height:auto makes all "unloaded" imgs square, screwing up any sentinel calculations.

Here's what I worked out:

  1. Always use inline height and width attributes on imgs (probably good for minimizing repaints anyways)
  2. On doc ready, for each img[data-cycle-src], calculate "attrProportion" based on the attribute dimensions and set it as jquery data on the img. Set the heights of the imgs directly using script. (yech, but...)
  3. On resize/orientationChange/slideAdded etc, get the new image widths and do it all over again, before the sentinel calculation happens.
  4. Change the hiding of the unseen slides to use opacity:0 instead of display:none in the plugin core. This puts them back in the render tree, to allow retrieving their dimensions across resize. There is probably a miniscule performance cost to this, but I can't detect it.

It's slightly convoluted, but for non-carousels it works perfectly:

  • mixed size slide content
  • fully responsive, handles resize
  • fast initial page load

Only downside is non-js users just see the first two slides, but I can live with that.

I will maybe post it as a fork if I can find the time, or please adapt/reuse/improve...

BTW did you see the new editor's draft for <img delay />? This may ultimately solve most of this use case, if and when it's implemented.

@superbia
Copy link

The link to the lookahead plugin is broken. Is it still available somewhere?

@malsup
Copy link
Owner

malsup commented Jul 16, 2013

@malsup malsup closed this as completed Jul 16, 2013
@superbia
Copy link

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants