Skip to content

Commit

Permalink
speed(homepage) offload images until in viewport
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneHlushko committed Apr 24, 2019
1 parent 198c534 commit 8ba8d6a
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 24 deletions.
50 changes: 29 additions & 21 deletions src/components/Contributors/Contributors.jsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import React from 'react';
import VisibilitySensor from '../VisibilitySensor/VisibilitySensor';
import SmallIcon from '../../assets/icon-square-small-slack.png';
import './Contributors.scss';

export default ({contributors}) => {
if (!contributors.length) {
return <noscript />;
}

return (
<div className="contributors">
<div className="contributors__list">
{
contributors.map(contributor => (
<a key={ contributor }
className="contributor"
href={ `https://github.com/${contributor}` }>
<img alt={ contributor } src={ `https://github.com/${contributor}.png?size=90` } />
<span className="contributor__name"> {contributor}</span>
</a>
))
}
export default class Contributors extends VisibilitySensor {
render() {
const { isVisible } = this.state;
const { contributors } = this.props;

if (!contributors.length) {
return <noscript />;
}

return (
<div className="contributors" ref={ this.visibilityTarget }>
<div className="contributors__list">
{
contributors.map(contributor => (
<a key={ contributor }
className="contributor"
href={ `https://github.com/${contributor}` }>
<img alt={ contributor }
src={ isVisible ? `https://github.com/${contributor}.png?size=90` : SmallIcon } />
<span className="contributor__name"> {contributor}</span>
</a>
))
}
</div>
</div>
</div>
);
};
);
}
}
8 changes: 5 additions & 3 deletions src/components/Support/Support.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Import External Dependencies
import React from 'react';
import VisibilitySensor from '../VisibilitySensor/VisibilitySensor';

// Import Data
import Backers from './_supporters.json';
Expand Down Expand Up @@ -61,9 +62,10 @@ function formatMoney(number) {
return str;
}

export default class Support extends React.Component {
export default class Support extends VisibilitySensor {
render() {
let { rank } = this.props;
const { isVisible } = this.state;

let supporters = SUPPORTERS;
let minimum, maximum, maxAge, limit, random;
Expand Down Expand Up @@ -108,7 +110,7 @@ export default class Support extends React.Component {
}

return (
<div className="support">
<div className="support" ref={ this.visibilityTarget }>
<div className="support__description">
{ rank === 'backer' ? (
<p>
Expand All @@ -134,7 +136,7 @@ export default class Support extends React.Component {
href={ supporter.website || `https://opencollective.com/${supporter.slug}` }>
{<img
className={ `support__${rank}-avatar` }
src={ supporter.avatar || SmallIcon }
src={ (isVisible && supporter.avatar) ? supporter.avatar : SmallIcon }
alt={ supporter.name || supporter.slug ? `${supporter.name || supporter.slug}'s avatar` : 'avatar' }
onError={ this._handleImgError } />}
</a>
Expand Down
47 changes: 47 additions & 0 deletions src/components/VisibilitySensor/VisibilitySensor.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';

export default class VisibilitySensor extends React.Component {
state = {
isVisible: false
};

constructor(props) {
super(props);
this.visibilityTarget = React.createRef();
}

componentWillUnmount() {
this.stopListeningForVisibility();
}

componentDidMount () {
if (this.visibilityTarget.current) {
this.startListeningForVisibility();
}
}

startListeningForVisibility = () => {
if (typeof IntersectionObserver !== 'function') {
// fall back to rendering images
// browser doesnt support IntersectionObserver;
return this.setState({ isVisible: true });
}

this.observer = new IntersectionObserver(this.visibilityChanged, {
threshold: 0.05
});
this.observer.observe(this.visibilityTarget.current);
}

stopListeningForVisibility = () => {
this.observer && this.observer.unobserve(this.visibilityTarget.current);
delete this.observer;
}

visibilityChanged = (entries) => {
if (entries[0].isIntersecting) {
this.setState({ isVisible: true });
this.stopListeningForVisibility();
}
}
}

0 comments on commit 8ba8d6a

Please sign in to comment.