我创建了一个Section组件,它将图像作为属性,其子项作为内容显示在该部分中,因此该组件看起来如下......
<Section image={'path/to/image'}>
//content
</Section>
该组件将获取image属性并将其设置为背景图像样式的URL ...
let sectionStyle = {
backgroundImage: `url(${this.props.image})`
}
然后将在返回元素中处理...
return (
<section
style={this.props.image ? sectionStyle : null}>
<div>
{this.props.children}
</div>
</section>
)
我的问题是,是否可以延迟加载背景图像,同时也不会影响SEO的内容可用性?换句话说,我想避免LazyLoading整个Section,但不知何故,LazyLoad只是与Section相关联的图像。
答案 0 :(得分:3)
这是延迟加载图像的简单组件:
class LazyImage extends React.Component {
state = { src: null };
componentDidMount() {
const { src } = this.props;
const imageLoader = new Image();
imageLoader.src = src;
imageLoader.onload = () => {
this.setState({ src });
};
}
render() {
return <img src={this.state.src || this.props.placeholder} />;
}
}
您可以用<LazyImage src='path/to/hd.jpg' placeholder='path/to/placeholder.jpg' />
答案 1 :(得分:1)
@naoise-golden 答案的更新版本
import PropTypes from 'prop-types';
import React from 'react';
export default class LazyImage extends React.Component {
constructor (props) {
super(props);
this.state = {
src: null,
};
}
componentDidMount () {
const { src } = this.props;
console.log('LazyImage componentDidMount props:', this.props);
const imageLoader = new Image();
imageLoader.src = src;
imageLoader.onload = () => {
console.log('LazyImage loaded src:', src);
this.setState({ src });
};
}
render () {
const { placeholder, className, height, width, alt } = this.props;
const { src } = this.state;
return (
<img src={src || placeholder} className={className} height={height} width={width} alt={alt} />
);
}
}
LazyImage.propTypes = {
src: PropTypes.string,
placeholder: PropTypes.string,
className: PropTypes.string,
height: PropTypes.number,
width: PropTypes.number,
alt: PropTypes.string,
};
答案 2 :(得分:0)
我为延迟加载图片创建了一个库。它的主要功能是提供动态调整图像大小,但它也可以解决您的问题。我最近在背景图片延迟加载方面做了一些改变。
https://github.com/peterlazzarino/react-adaptive-image
这是一个可用于延迟背景图片加载的示例,可以解析来自imgur的图像。在我的生产应用程序中,我的图像解析器指向图像服务器,但这完全可以自定义。您只需要将.header-image类设置为具有高度和宽度。
import React from 'react';
import ReactDOM from 'react-dom';
import { initImages } from 'react-adaptive-image';
import AdaptiveImage from 'react-adaptive-image';
initImages({
imageResolver: function(image){
return `https://i.imgur.com/${image.fileName}`
}
})
class App extends React.Component {
render() {
return (
<AdaptiveImage backgroundImage className="header-image" fileName={'U6zWkcZ.png'} />
);
}
}
ReactDOM.render(<App />, document.getElementById('react-root'));
答案 3 :(得分:0)
为了延迟加载 background-image
,您需要为使用 url
加载任何文件的 CSS 属性创建样式表,因为您不希望这些图像延迟第一次内容绘制.
例如:
此文件具有将首先加载的重要 CSS 属性...
.styles {
&-container {
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-content: center;
justify-content: center;
align-items: center;
}
}
此文件将在关键 CSS 之后加载...
.styles {
&-container {
background: url('../../images/code/code.jpg') no-repeat center center fixed;
background-size: cover;
}
}
出于演示目的,我将在这里使用 React.Component,但是,如果您想尝试优化一些东西,您也可以使用 React.PureComponent(我测试过,一切正常)。
const classNames = require('classnames');
const React = require('react)';
const {stylesContainer} = require('./firstModal.module.less');
class FirstModal extends React.Component {
constructor(props) {
super(props);
this.state = {
classNames: classNames([stylesContainer])
};
}
async componentDidMount() {
const backgroundImage = await import(
'./firstModalBackground.module.less'
);
this.setState({
classNames: [
classNames(this.state.classNames, [backgroundImage.stylesContainer]),
]
});
}
render() {
// console.log(this.state.classNames);
return <div className={this.state.classNames}>It werks!</div>;
}
}
module.exports = FirstModal;
你甚至可以更进一步,如果你有一个加载速度更快的低分辨率图像,你可以有一个“三步背景图像加载”,例如,在 componentDidMount 上:
async componentDidMount() {
const lowResolutionBackgroundImage = await import(
'../greeting-page/firstModalLowResBackground.module.less'
);
const baseClass = this.state.classNames;
this.setState({
classNames: [
classNames(baseclass,
lowResolutionBackgroundImage.stylesContainer),
]
});
const backgroundImage = await import(
'./firstModalBackground.module.less'
);
this.setState({
classNames: [
classNames(baseClass,
backgroundImage.stylesContainer),
]
});
}