延迟渲染直到加载所有资源的系统方法

时间:2019-06-07 16:34:14

标签: reactjs

我使用Webpack 4,Babel 7,React 16.8。当用户加载我的页面时,我的应用程序会加载google网络字体,许多组件所需的外部图像,这些组件会参与初始渲染。

我用这样的sass文件加载字体:

@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700');

我在所有组件中使用图像,例如:

import SearchSvg from '../../images/search_icon.svg';

并像这样使用它们:

<img src={ SearchSvg } />

现在,我对<img onLoad=.....>有所了解,并且知道有一些软件包可以测试是否已经加载了网络字体。我的问题是:是否有任何 SYSTEMIC 方法/模式来获取React组件的初始呈现,等到所有这些外部资源被加载?

现在,我将setTimeout500 ms一起使用来延迟index.js中的根渲染。

setTimeout(function() {
    render(
        ...
    );
}, 500);

我希望用一个真正知道何时加载所有内容的东西来替换此硬编码值-理想情况下不必在我使用的每个单个组件中添加代码。

动机当然是为了避免在我最初渲染我的应用程序时出现字体/图像闪烁-由于在图像/字体尚未完全加载时进行渲染。

3 个答案:

答案 0 :(得分:3)

您可以在触发onload事件后渲染根组件。

  

加载整个页面(包括样式表图像等所有相关资源)后,将触发load事件。   https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event

window.onload = function() {
   ReactDOM.render(<App/>, document.getElementById('root'));
};

如果您的目的是提高性能,那么我强烈建议您考虑使用服务器端渲染。

答案 1 :(得分:2)

在您的情况下,您可以使用document.fonts.ready检查字体是否准备好,然后在条件为真时有条件地渲染所需的部分

在此找到一个示例:

https://developer.mozilla.org/en-US/docs/Web/API/Document/fonts

对于您的用例,可以使用上面的链接中提供的类似功能,然后将状态值设置为true(如果就绪)。然后,您可以有条件地渲染想要的内容

例如:

在componentDidMount中调用该函数:

  componentDidMount() {
    this.isFontLoaded()
  }

该函数使用document.fonts.ready,它返回一个Promise。然后,一旦承诺返回,我们便将状态值fontReady设置为true:

  isFontLoaded = () => {
    document.fonts.ready.then(this.setState({ fontReady: true }))
  }

仅在fontReady为真时呈现您想要的东西:

{fontReady && <img src={ SearchSvg } />}

答案 2 :(得分:1)

您可以使用包装器组件进行所有检查,并在发生负载以及完成所有操作后显示加载或不显示任何内容,从而呈现应用程序。像这样:

class LoadApplication {
  state = { loaded: false }
  timer = null

  componentDidMount() {
    this.timer = setInterval(this.checkStuff, 50)
  }

  componentWillUnmount() {
    clearInterval(this.timer)
  }

  checkStuff() {
    if (stuffIsLoaded) {
      this.setState({ loaded: true })
    }
  }

  render() {
    return this.state.loaded ? this.props.children : null;
  }
}

...

ReactDOM.render(<LoadApplication><App /></LoadApplication>, document.querySelector('#root'))

这有点与CRA处理错误的方式相同。建议使用相同的方法来捕获React documentation中组件中的错误,因此我认为这可能是您正在寻找的。希望对您有所帮助。