在Next.js和/或其他形式的React服务器端渲染中延迟加载图像

时间:2019-01-04 20:34:47

标签: javascript reactjs next.js ssr

我正在使用Next.js进行新项目的服务器端渲染。我有一个路由和运行的基本项目。我正在使用TypeScript,但我怀疑这很重要。

我想延迟加载图像,但是没有找到任何支持延迟加载图像以进行服务器端渲染的组件。

这是我目前的看法-

服务器端呈现将使用页面第一次呈现的HTML模板来响应客户端。

在客户端,一旦加载HTML,图像就会根据客户端逻辑开始延迟加载。

我对服务器端渲染非常陌生,我想我应该在运行时在客户端上渲染其他功能时也会遇到类似的问题。

我正试图了解如何将发生在服务器端的第一个渲染的逻辑与以后希望像其他任何单页应用程序一样在客户端进行的进一步动态渲染的逻辑分开。

>

1 个答案:

答案 0 :(得分:0)

我认为您的看法是正确的,对于客户端代码(例如lazyload),我经常使用componentDidMount生命周期方法。

这样的HOC应该可以解决问题。

function lazyLoadImages(selector = 'img') {
    function createObserver() {
        const elements = document.querySelectorAll(selector);
        const observer = new window.IntersectionObserver((entries, observerChild) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting && entry.target.getAttribute('data-src')) {
                    entry.target.src = entry.target.getAttribute('data-src');
                    entry.target.removeAttribute('data-src');
                    observerChild.unobserve(entry.target);
                }
            });
        }, {});

        Array.prototype.map.call(elements, function(item) {
            observer.observe(item);
        });
    }

    if (!('IntersectionObserver' in window)) {
        const polyfill = document.createElement('script');
        polyfill.src = 'https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver';
        document.head.appendChild(polyfill);

        polyfill.onload = () => {
            createObserver();
        };
        return;
    }

    createObserver();
}

const LazyLoadHOC = (Page) => {
    return class extends React.Component {
        static getInitialProps(ctx) {
            if(Page.getInitialProps)
                return Page.getInitialProps(ctx);
        }

        componentDidMount() {
           lazyLoadImages('img');
        }

        render() {
            return <Page {...this.props}/>
        }

    }
}

现在,您可以使用LazyLoadHOC包装页面,并用srcdata-src替换为所有要延迟加载的图像。