转换到 React.lazy 加载组件时闪烁

问题描述 投票:0回答:3

在此仓库中:https://github.com/tlg-265/react-app-vanilla

$ git clone https://github.com/tlg-265/react-app-vanilla
$ cd react-app-vanilla
$ yarn
$ yarn start

我有一个只有 3 页的虚拟应用程序:

{ Page1, Page2, Page3 }

我的目标是:拆分和延迟加载

Page3
并防止过渡时闪烁。

使用我现有的代码,分割和延迟加载效果很好,但从

Page2
转换到
Page3
时会出现闪烁。

以下是一些主要文件:

react-app-vanilla/src/App.js

import React, { Suspense } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { ReactLazyPreload } from './utils/Functions';
import './App.css';

import Page1 from './components/Page1';
import Page2 from './components/Page2';
const Page3 = ReactLazyPreload(() => import(/* webpackChunkName: "page-3" */ './components/Page3'));

function App() {
  return (
    <Router history={window.history}>
      <Switch>
        <Route exact path="/" component={Page1} />
        <Route path="/page-2" component={Page2} />
        <Suspense fallback={"Loading"}>
          <Route path="/page-3" component={Page3} />
        </Suspense>
      </Switch>
    </Router>
  );
}

export default App;

react-app-vanilla/src/components/Page2.js

import React from 'react';
import { ReactLazyPreload } from '../utils/Functions';

const Page3 = ReactLazyPreload(() => import(/* webpackChunkName: "page-3" */ './Page3'));

class Page2 extends React.Component {

  componentDidMount() {
    Page3.preload();
  }

  handleNext = (e) => {
    e.preventDefault();
    this.props.history.push('/page-3');
  };

  render() {
    return (
        <>
        <h1>Page 2</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer gravida leo in pharetra sagittis. Donec sed tempus ex, nec rhoncus justo. Phasellus auctor diam eleifend, vestibulum justo ac, ultrices ipsum. Donec pretium augue ante, eget eleifend mi vehicula eu. Donec vitae sem erat. Vestibulum tincidunt suscipit ex, vitae condimentum odio ornare in. Vestibulum erat neque, semper sit amet suscipit vel, malesuada in diam. Morbi ut eros eget lectus sodales rhoncus.</p>
        <div style={{ textAlign: 'center' }}>
          <button type="button" onClick={this.handleNext} className="button-next">NEXT</button>
        </div>
      </>
    )
  }
}

export default Page2;

react-app-vanilla/src/utils/Functions.js

import React from "react";

export const ReactLazyPreload = importStatement => {
  const Component = React.lazy(importStatement);
  Component.preload = importStatement;
  return Component;
};

我的最后一次提交是基于我在此链接上找到的一些建议:

https://blog.maximeheckel.com/posts/preloading-views-with-react/

但不幸的是它仍然在闪烁。

您可以预览我的更改:

关于如何防止从

Page2
Page 3
的闪烁有什么想法吗?

欢迎您按照顶部的说明自行尝试。

谢谢!

reactjs react-router lazy-loading react-router-dom react-dom
3个回答
10
投票

这取决于您在加载下一页时要显示的内容。 互联网上的许多答案都显示使用带有延迟的加载旋转器来防止闪烁。

我当前使用的方法是在渲染页面时更新回退。我不使用

<Loading />
组件,而是在准备下一页时显示当前安装的页面。

这里是演示源代码


1
投票

我遇到了同样的问题,在第一次尝试与@Han Moe Htet 类似的方法后,我意识到答案要简单得多。不要用 Suspense 包装单个 Route,而是用 Suspense 包装整个路由器 Switch。这可以防止回退在第一次

/page-3
加载时瞬间闪烁。

例如:

    <Suspense fallback={"Loading"}>
      <Switch>
        <Route exact path="/" component={Page1} />
        <Route path="/page-2" component={Page2} />
        <Route path="/page-3" component={Page3} />
      </Switch>
    </Suspense>

@Viewsonic 我刚刚在 your repo 中尝试过此操作,它解决了我的问题。


0
投票

尝试在Page2组件中使用startTransition

import { startTransition } from 'react';
..........
..........

  componentDidMount() {
    startTransition(() => {
       Page3.preload();
    });
  }

..........
..........

您可以使用下面的 React 文档找到有关此内容的更多详细信息。
https://react.dev/reference/react/Suspense#preventing-already-revealed-content-from-hiding

© www.soinside.com 2019 - 2024. All rights reserved.