react-progressive-bg-image
react-progressive-bg-image copied to clipboard
Request large image only when it is in the viewport?
Thanks for the super cool library.
Just wondering, is it possible to request the original image only if the image is present in the current viewport. This feature will save lots of bandwidth and improves performance, especially in mobiles.
Thanks
Lazy loading is out of scope of this library. Actually, I use react-waypoint to achieve this feature in some of my projects. It is super easy to compose with any components, something like:
<Waypoint>
<ProgressiveImage />
</Waypoint >
I wanted to do this too. Maybe it's not the best way, but this is my process incase anyone else is searching. I did it by having a flag in the component state to check if the waypoint had been entered or not. If so, change the flag to true and show the ProgressiveImage. Here's the codes:
Make sure both are imported:
import ProgressiveImage from 'react-progressive-bg-image';
import Waypoint from 'react-waypoint';
Add a state for when we should render the progessiveimage. This goes in your constructor, or the earliest point of your component lifecycle:
this.state={
showImage:false
}
- Use the waypoint's onEnter handler - hook it up to a
handleEnter
function:
render(){
<Waypoint onEnter={this._handleEnter}>
<div>
{this._getProgressiveImage()}
</div>
</Waypoint>
}
- the handlenter function simply changes the state. Should we show the progressiveimage or not? We only change this state if it's currently false, so it doesn't fire every time the waypoint goes in and out of view:
if(this.state.showImage===false){
this.setState({
showImage:true
})
}
- Depending on if this flag is set to true(whether the waypoint has been entered or not), either the actual progressive image component is returned, or just a placeholder that keeps the size nice. See this below:
_getProgressiveImage(){
if(this.state.showImage==true){
return(
<ProgressiveImage
src={realImageurl}
placeholder={'placeholderimageurl'}
style={{
height:190,
backgroundSize: 'cover',
backgroundPosition: 'center center',
}}
/>
)
}
else{
return(
<div className="overlay-image" style={{background:"placeholderimageurl')", width:"100%", height:"190px", backgroundSize:'cover', backgroundPosition:'center'}}>
</div>
)
}
}
It would be nice to not have to depend on not rendering ProgressiveImage
at all. What I'd like to be able to do is initially load all the placeholder images, and not wait to do that until the element in the viewport. Once in the viewport, I want to tell ProgressiveImage
to switch to the full image. But, there's no way to tell ProgressiveImage
this currently.