Skip to content

Commit

Permalink
Optimize image loading
Browse files Browse the repository at this point in the history
  • Loading branch information
kokororin committed Jun 23, 2018
1 parent e30f271 commit ebb44db
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 41 deletions.
122 changes: 83 additions & 39 deletions src/components/Item.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,28 @@ export default class Item extends React.Component {

constructor(props) {
super(props);

this.state = {
width: 0,
height: 0,
hasLoaded: false
};
}

componentDidMount() {
this.wait = setInterval(() => {
const width = this.imgRef.naturalWidth;
const height = this.imgRef.naturalHeight;
const offsetWidth = this.wrapper.offsetWidth;
if (width && height) {
this.setState({
width: offsetWidth,
// eslint-disable-next-line prettier/prettier
height: offsetWidth * height / width
});
clearInterval(this.wait);
}
}, 30);
}

onImageMouseMove(event) {
Expand All @@ -27,11 +49,20 @@ export default class Item extends React.Component {
}
}

@autobind
onImageLoad() {
this.setState({
hasLoaded: true
});
this.wait && clearInterval(this.wait);
}

@autobind
onImageError() {
this.imgRef.src = require('@/images/img-fail.jpg');
typeof this.props.masonryRef !== 'undefined' &&
this.props.masonryRef.performLayout();
this.wait && clearInterval(this.wait);
}

renderRankText() {
Expand All @@ -42,12 +73,14 @@ export default class Item extends React.Component {
</span>
);
}
let icon;
if (this.props.item.previous_rank < this.props.item.rank) {
icon = <Icon styleName="trending_down" name="trending_down" />;
} else {
icon = <Icon styleName="trending_up" name="trending_up" />;
}

const icon =
this.props.item.previous_rank < this.props.item.rank ? (
<Icon styleName="trending-down" name="trending_down" />
) : (
<Icon styleName="trending-up" name="trending_up" />
);

return (
<span styleName="rank-text-outer">
{icon}
Expand All @@ -60,50 +93,61 @@ export default class Item extends React.Component {
}

render() {
return this.props.item.hasOwnProperty('work') ? (
const isRank = this.props.item.hasOwnProperty('work');
return (
<div styleName="cell" onMouseMove={this.onImageMouseMove}>
<Link styleName="link" to={`/illust/${this.props.item.work.id}`}>
<div styleName="image-wrapper">
<Link
styleName="link"
to={`/illust/${
isRank ? this.props.item.work.id : this.props.item.id
}`}>
<div ref={ref => (this.wrapper = ref)} styleName="image-wrapper">
<img
ref={ref => (this.imgRef = ref)}
src={this.props.item.work.image_urls.px_480mw}
onError={this.onImageError}
src={require('@/images/img-placeholder.gif')}
width={this.state.width}
height={this.state.height}
style={{
display: this.state.hasLoaded ? 'none' : 'block'
}}
/>
</div>
<div styleName="title">
<span>{this.props.item.work.title}</span>
</div>
<div styleName="meta">
<span styleName="rank-num">
<FormattedMessage
id="x rank"
values={{ rank: this.props.item.rank }}
/>
</span>
<span>{this.renderRankText()}</span>
</div>
</Link>
</div>
) : (
<div styleName="cell" onMouseMove={this.onImageMouseMove}>
<Link styleName="link" to={`/illust/${this.props.item.id}`}>
<div styleName="image-wrapper">
<img
style={{
display: this.state.hasLoaded ? 'block' : 'none'
}}
ref={ref => (this.imgRef = ref)}
src={this.props.item.image_urls.px_480mw}
src={
isRank
? this.props.item.work.image_urls.px_480mw
: this.props.item.image_urls.px_480mw
}
onLoad={this.onImageLoad}
onError={this.onImageError}
/>
</div>
<div styleName="title">
<span>{this.props.item.title}</span>
</div>
<div styleName="meta">
<span styleName="count">
<Icon name="star" />
{this.props.item.stats.favorited_count.public +
this.props.item.stats.favorited_count.private}
<span>
{isRank ? this.props.item.work.title : this.props.item.title}
</span>
</div>
{isRank ? (
<div styleName="meta">
<span styleName="rank-num">
<FormattedMessage
id="x rank"
values={{ rank: this.props.item.rank }}
/>
</span>
<span>{this.renderRankText()}</span>
</div>
) : (
<div styleName="meta">
<span styleName="count">
<Icon name="star" />
{this.props.item.stats.favorited_count.public +
this.props.item.stats.favorited_count.private}
</span>
</div>
)}
</Link>
</div>
);
Expand Down
Binary file added src/images/img-placeholder.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/styles/Item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@
}
i {
font-size: 20px;
&.trending_down {
&.trending-down {
color: #3f51b5;
}
&.trending_up {
&.trending-up {
color: #d32f2f;
}
}
Expand Down

0 comments on commit ebb44db

Please sign in to comment.