Merri/react-lazy

Unable to get images to load

oyeanuj opened this issue · 10 comments

Hey @Merri, sorry for a generic subject line but I've been unable to get react-lazy to function with my setup. Essentially, when the page loads, the images are not loaded. If I resize the window, or call checkElementsInViewport (in componentDidMount), then the images load but unfortunately, all of the images load (as opposed to only those in viewport) :/

Here is my code:

<div className = {styles.imageGroup} >
  <Lazy onLoad = {this.handleWrapperLoad}>
   {this.renderImages()}
  </Lazy>
</div>
.imageGroup {
	border: 1px solid purple;
	min-height: 600px;
	width: 100%;
	display: flex;
	flex-wrap: wrap;
}

/* imageWrapper is just container for each image */
@media screen and (min-width: 600px) {
  .imageWrapper {
    width: calc(50% - 2rem);
  }
}

@media screen and (min-width: 1000px) {
  .imageWrapper {
    width: calc(33.3333% - 2rem);
  }
}

Here is what the component looks like in Devtools:
screen shot 2017-07-22 at 3 15 34 pm


I also tried using proto-img branch but ran into the following JS errors:
screen shot 2017-07-22 at 3 05 26 pm


I imagine I am doing something simple wrong, so any tips are much appreciated :)

Merri commented

In this case you want to use one <Lazy /> per each image, for example:

    render() {
        return (
            <ol>
                {this.props.images.map((image, index) =>
                    <Lazy key={index} component="li">
                        <img {...image} />
                    </Lazy>
                )}
            </ol>
        )
    }

@Merri I was trying to have one <Lazy /> for the group, as per your note on the README, so that viewport checks are minimal. So, does that mean in my case, the entire group would load at the same time? Or the tradeoff is performance?

Even with that, any ideas on why the entire group is not loading at the same time when I open the page (it only loads on resize or calling checkElementsInViewport?

Merri commented

The tradeoff is performance, a check is required for each individual image each time, but this is the stablest way to use <Lazy / at the moment. It shouldn't be bad if you're dealing with just a couple of images, but it gets worse once the page has hundreds of images and if you have more features on the page than just an image gallery.

The resize / checkElementsInViewport requirement issue is most likely a new one as I swapped from class Lazy extends React.Component to class Lazy extends React.PureComponent; I didn't notice it until playing around with proto-img branch, so that is probably a bug I need to fix. For some reason the production site I work with doesn't have any issue, probably due to other components forcing extra renders :)

Thanks for confirming that, glad it wasn't something wrong on my side phew

Merri commented

Do you still have the "images in viewport don't load on initial render" issue now that v0.4.0 is out?

@Merri Just upgraded to v0.4.0 but still seeing the problem :/ Again with checkElementsInViewport or resizing the window, everything loads rather than only a few lazy loading.

Merri commented

What is your current render code? Are you still using only one Lazy for multiple images?

I am now using one Lazy per image. Here is the code -

<Lazy cushion = {100} onLoad = {this.handleWrapperLoad} >
  {this.renderImageWrapper(styles)}
</Lazy>

@Merri I noticed you closed it - any solutions here?

Merri commented

v1 will use IntersectionObserver which will soon be available natively in all evergreen browsers so there will be no need for checkElementsInViewport. In the other hand I don't want to add more complexity to the method for performance reasons; and it would be overkill to go for perfect detection in most use cases. There are many other lazy loaders that throw an attempt at it and I've preferred to keep this one as lightweight and performant as possible to stand out of the crowd a little.