如何在内联样式属性(反应)中延迟加载背景图像?

时间:2018-07-31 06:49:09

标签: javascript reactjs lazy-loading

我目前正在开发我的第一个React应用,而我正面临着一些困难。

<div
    className="container-fluid"
    id="cityDetail"
    style={{
        backgroundImage: `url(${camera.lastPhoto})`,
        backgroundRepeat: "no-repeat",
        backgroundPosition: "center",
        backgroundSize: "cover",
        height: "100vh"
    }}
>

我想延迟加载backgroundImage。

我还没有找到执行此操作的良好组件/实用程序。 有人对此有想法吗?

谢谢!

4 个答案:

答案 0 :(得分:11)

这是一个基于Naoise答案的自定义React钩子:

cv.HoughLines(src, lines, 1, Math.PI / 180, 30, 0, 0, 0);

用法:

const useProgressiveImage = src => {  
  const [sourceLoaded, setSourceLoaded] = useState(null)

  useEffect(() => {
    const img = new Image()
    img.src = src
    img.onload = () => setSourceLoaded(src)
  }, [src])

  return sourceLoaded 
}

答案 1 :(得分:2)

这是延迟加载图像的简单组件:

class LazyBackground 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 <div {...this.props} style={{ backgroundImage: `url(${this.state.src || this.props.placeholder})` }} />;
  }
}

您可以用<LazyBackground src='path/to/hd.jpg' placeholder='path/to/placeholder.jpg' />

来称呼它

答案 2 :(得分:0)

具有这样的功能组件:

function LazyBackground({src}) {
    const [source, setSource] = useState("preload.jpg")

    useEffect(() => {
        const img = new Image()
        img.src = src
        img.onload = () => setSource(src)
    }, [src])

    return(
        <div style={{backgroundImage: `url(${source})`}}></div>
    )
}

用法:

<LazyBackground src={"https://example.com/your_image.jpg"}/>

答案 3 :(得分:0)

为了延迟加载 background-image,您需要为使用 url 加载任何文件的 CSS 属性创建样式表,因为您不希望这些图像延迟第一次内容绘制. 例如:

FirstModal.module.less

<块引用>

此文件具有将首先加载的重要 CSS 属性...

.styles {
    &-container {
        position: absolute;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        align-content: center;
        justify-content: center;
        align-items: center;
    }
}

firstModalBackground.module.less

<块引用>

此文件将在关键 CSS 之后加载...

.styles {
    &-container {
        background: url('../../images/code/code.jpg') no-repeat center center fixed;
        background-size: cover;
    }
}

出于演示目的,我将在这里使用 React.Component,但是,如果您想尝试优化一些东西,您也可以使用 React.PureComponent(我测试过,一切正常)。

firstModal.jsx

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),
            ]
        });
    }