关于React,Suspense,lazyLoad和预加载/渲染元素

时间:2019-06-06 09:54:07

标签: javascript reactjs lazy-loading

我正在研究<Suspense>React.lazy()的概念,并且我想更好地理解为了将逻辑添加到现有应用程序中会发生什么。

让我们从定义开始:

  

React.lazy函数使您可以渲染动态导入作为常规组件。

(我突出显示的渲染

  

如果在MyComponent渲染时尚未加载包含OtherComponent的模块,我们必须在等待其加载时显示一些后备内容[...]

(我突出显示的已加载

现在,Suspense定义使用术语 load lazy()使用 render

让我们在概念上添加一些代码。

const ComponentOne = React.lazy(() => import("./ComponentOne"));
const ComponentTwo = React.lazy(() => import("./ComponentTwo"));

function BigBang() {
    return (
        <Suspense fallback={<SplashScreen/>}>
            <section>
                <ComponentOne/>
                <ComponentTwo/>
            </section>
        </Suspense>
    );
}

好。这个想法是我们要延迟加载ComponentOne和ComponentTwo。 在此过程尚未结束时,我们将显示SplashScreen。

问题 现在,假设我已经将一些本地图像导入了ComponentOne和ComponentTwo中(我将仅为其中一个添加代码,让我们假设另一个为类似的代码):

import avatar from "../../img/avatar.svg";
import logo from "../../img/logo.svg";

export default class ComponentOne extends React.Component {
    componentDidMount() {
        console.log("ComponentOne@componentDidMount");
    }

    render() {
        console.log("ComponentOne@render");
        return (
            <div style={{display: 'none'}}>
                <img src={avatar}/>
                <img src={logo}/>
            </div>
        );
    }
}

现在应该清楚我想问什么:

加载所有导入文件时,SplashScreen是否消失?换句话说,当SplashScreen消失时,我是否可以假定ComponentOne和ComponentTwo中的所有图像都已加载?

这是主要问题。

第二个问题(似乎与我有关,但如果不是,我可以打开另一个线程):如果上一个问题的答案为“否”,那么确保图像/字体的最佳策略是什么? /“ api响应” /“其他资源”在渲染之前已加载,是否可能由于已经存在的流程而保持逻辑?目前不支持将fetch()直接指向资源。

1 个答案:

答案 0 :(得分:0)

Suspense等待动态导入的组件文件(例如0.js)被提取。 现在,0.js加载并开始解析后,Suspense停止显示SplashScreen,并由委托控制您的组件。接下来发生的一切都不是延迟加载。就像您进行静态导入时会发生什么。

在您的情况下,仅在SplashScreen消失后才加载两个图像。现在,如果您要预加载/延迟加载图像,可以通过几种方法进行。

1)如果使用的是webpack,则可以使用url-loaderdata-uri的形式内嵌图像。但请注意,这可能会增加捆绑包的大小,并且还会使浏览器缓存通常是静态的图像丢失。

2)对于svg,您可以使用inline-react-svg babel插件,该插件将svg转换为react组件,从而使其成为捆绑包(0.js)的一部分。但它也具有上述相同的权衡。

因此,预加载图像有其自身的权衡。可能有更好的替代方法,例如可以轻松完成的延迟加载,也可以从多个第三方库中获得React HOC。