使用react-lazyload可以实现背景图片的延迟加载吗?

9
我创建了一个Section组件,该组件将接收一个图像作为属性和子元素作为要显示在该部分中的内容,因此该组件如下所示...
<Section image={'path/to/image'}>
 //content
</Section>

该组件将使用image属性并将其设置为background-image样式的URL...
let sectionStyle = {
  backgroundImage: `url(${this.props.image})`
}

然后该返回元素将被处理...
return (
  <section
    style={this.props.image ? sectionStyle : null}>
    <div>
      {this.props.children}
    </div>
  </section>
)

我的问题是,是否可以同时懒加载背景图像而不影响SEO的内容可用性?换句话说,我想避免懒加载整个部分,但以某种方式只懒加载与该部分相关联的图像。

4个回答

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

1
为了推迟加载背景图片,您需要创建一个样式表来处理加载任何带有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),
            ]
        });
    }

0
这是一个简单的组件,用于懒加载图片:
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' />


3
这并没有回答问题。问题是如何在background-image: url('image');的CSS中应用lazyload。 - Jovylle
它通过提供回退(占位符)和通过onload进行懒加载的src来执行与lazy load相同的操作。我在下面附上了我们使用的更详细的版本。 - spodell

-1

我创建了一个用于懒加载图片的库。它的主要特点是提供动态调整图像大小的功能,但它也可以解决你的问题。最近,我为背景图片懒加载提交了一些更改的PR。

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'));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接