我正在研究<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()
直接指向资源。
答案 0 :(得分:0)
Suspense
等待动态导入的组件文件(例如0.js
)被提取。
现在,0.js
加载并开始解析后,Suspense
停止显示SplashScreen
,并由委托控制您的组件。接下来发生的一切都不是延迟加载。就像您进行静态导入时会发生什么。
在您的情况下,仅在SplashScreen
消失后才加载两个图像。现在,如果您要预加载/延迟加载图像,可以通过几种方法进行。
1)如果使用的是webpack,则可以使用url-loader
以data-uri
的形式内嵌图像。但请注意,这可能会增加捆绑包的大小,并且还会使浏览器缓存通常是静态的图像丢失。
2)对于svg,您可以使用inline-react-svg
babel插件,该插件将svg转换为react组件,从而使其成为捆绑包(0.js
)的一部分。但它也具有上述相同的权衡。
因此,预加载图像有其自身的权衡。可能有更好的替代方法,例如可以轻松完成的延迟加载,也可以从多个第三方库中获得React HOC。