callmecavs / layzr.js

A modern lazy loading library for images.

Home Page:http://callmecavs.com/layzr.js/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Threshold not working as expected

ndimatteo opened this issue · comments

  1. The threshold doesn't work equally when scrolling up or down.
  2. Images that are already visible on the page on load don't show until scrolling starts

I'm not sure how you intended people to set the threshold, but I found that if I want the image to load after part of the image is revealed, I have to set a ridiculously high negative integer (ie. -800).

It works great as you scroll down, but if you are scrolling up (which can be achieved by scrolling down then refreshing the page) the image doesn't load until wayyyy later compared to scrolling down.

In addition, I have images that are almost completely visible on page load, yet Layzr doesn't fire for them until I start scrolling.

Ideally:

  1. any images that are already visible on the page (above the fold) should load when the script is initiated
  2. threshold should a) be more clearly defined (what values are we expected to use here?) and should work equally going up or down (ie. if it's 100px delay on the way down, it should only be 100px delay on the way up).

@ndimatteo responses below, please dont hesitate to reach out if you have any further questions

  1. please see the options section of the docs detailing threshold. the threshold is a percentage of the viewport height, not a value in px. that might explain some of the weird behavior you're experiencing - a value of over 100 is likely not what you're intending. also, positive numbers make images load sooner (off the screen), and negative numbers make the images load later (on the screen).
  2. I've updated the examples to better show how to handle elements in the viewport when the page loads. using your instance, you can call the check method at any time - just call it when the page loads to handle these elements.

Thanks @callmecavs,

  1. I totally understand that it's doing it via percentage, but no number I input seems to make a noticeable difference until I start using really high integers. Disregarding my comment about 'pixels,' say I want the image to load when 30% of the image container has scrolled past, what would the integer be for that? I can't seem to figure this out. Or, if I'm phrasing this wrong, can you show me an example of any kind where the image loads a bit late?
  2. Sweet, that makes sense. Thanks!

@ndimatteo upon further review, there was indeed a bug in the threshold calculation (oops). just pushed v2.0.1, which fixes it, and I mentioned you in the release notes.

the code that loads images when they're 30% of the way into the viewport looks as follows:

var instance = Layzr({
  threshold: -30
})

using the newest version, let me know if that works for you. i just tested it, and it should now. great catch on the threshold bug, not sure how that one snuck by me.

Awesome, thanks @callmecavs

Still one issue:
I did as you said and placed instance.check() within a .load() and it doesn't do anything. Even calling instance.check() from the console doesn't initiate it.

Here's an example: http://nickdimatteo.co/project/twenty-over-ten

@ndimatteo the problem on that page is that the images have no width/height before they're loaded, so the check function thinks they're offscreen, even though the area the image will eventually fill is on the screen.

add the following to your CSS:

#project .project-wrapper .image > img {
  /* you already have this */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;

  /* add the following */
  width: 100%;
  height: 100%;
}

adding the above, and calling the check function manually, worked on that page for me - let me know if it works for you. great looking site btw, happy to have you using Layzr on it.

@callmecavs Interesting. It's still not working for me after adding that:

It seems like if you go from the homepage into a project, it works great. But if you go directly to a project URL it doesn't update the ones in view: http://nickdimatteo.co/project/twenty-over-ten

And thanks man, much appreciated! Excited to wrap up these last few quirks so I can finish it!

@ndimatteo you're on a roll today man - that's another bug you've found!

the problem was that when the page was first loaded, before the user scrolls, the scroll position was undefined, so all the images were considered "out of the viewport". just pushed v2.0.2, which patches this, setting the initial scroll position to the window.scrollY or window.pageYOffset. this will be 0 if the user hasn't scrolled at all, and will account for refreshing halfway down the page.

update your version to the newest one, and you should be good to go with the code you have currently. thanks again! and congratulations on 2 mentions in the release notes haha

@callmecavs haha, thanks for fixing all of these so quickly man. Really stoked, this seems to be all good now!

Check it out now: http://nickdimatteo.co/project/twenty-over-ten

@ndimatteo no problem - I try to be quick on the turnaround with bugs because its likely other people will run into them, and there's no API changes involved in patching them.

looks dope man - the homepage is lookin slick as well! I was based outta DC until I recently moved up to NYC a couple months ago, small world.

@callmecavs thanks man! And that's awesome, definitely a small world. If you're ever back to visit let me know.

@ndimatteo will do brotha. best of luck with the agency.

not sure what you're using to smooth scroll the homepage (when the user clicks 'work') but I made jump.js, and I think it might scroll it smoother 😉

@callmecavs I'm just using a simple jQuery animate, here's the snippet:

$('html, body').stop().animate({
  scrollTop: $($anchor.attr('href')).offset().top
}, 1000,'easeInOutExpo')

I'm all about making all of this shit smoother, so if you think jump.js will help I'm all ears 😀

generally speaking, jquery animate doesn't give the smoothest results, because the function is a bit clunky, given all the possibilities it can handle.

if you want to give Jump.js a try (it's much smoother, just tested it by pasting it into the console), the code to replicate what you have would look like this:

// create instance
var jumper = new Jump()

// jump to first project
jumper.jump('.project', { duration: 1000 })

if you want a more powerful and heavily optimized "do it all" animate function, to replace jQuery's, take a look at Velocity.js. its a drop-in replacement that uses much faster stuff under the hood, and will give you much better performance across the board. on the homepage, it offers a bit of explanation as to what the problem with jQuerys animate is, and how it solves it

Thanks man,

Aside from this animation and a few others, I actually am using TweenMax to do the work! I'm going to give your plugin a try for this one and the "back to top" links though.

Whoops, back for one more ;)

I noticed on mobile (iOS) that sometimes images are skipped over. And you end up with something like the following:

img_1050

If you scroll back up and stop at regular intervals they'll come in, but since most people 'flick' I don't think this is an expected behavior.

Any ideas? If the image is in view it should fire, perhaps we need to refire on ontouchend for mobile to ensure anything in the viewport is activated?

@ndimatteo unfortunately that's just a limitation caused by how frequently iOS fires the "scroll" event while scrolling. on mobile Chrome, the scroll event doesn't fire at all until you stop, and so you won't see any images at all if you flick. it's not necessarily a bad thing, because if users are scrolling that fast, they likely wont see the image anyways, and so its better to save mobile data and not load it. feel free to experiment with added an ontouchend event that calls check, but I dont think its something ill add to the core of the library