Réagir - Afficher l'écran de chargement pendant le rendu du DOM?

151

Ceci est un exemple de la page d'application Google Adsense. L'écran de chargement affiché avant la page principale s'affichait après.

entrez la description de l'image ici

Je ne sais pas comment faire la même chose avec React car si je rend l'écran de chargement rendu par le composant React, il ne s'affiche pas pendant le chargement de la page car il doit attendre le rendu du DOM avant.

Mise à jour :

J'ai fait un exemple de mon approche en installant le chargeur d'écran index.htmlet en le supprimant dans componentDidMount()la méthode du cycle de vie React .

Exemple et écran de chargement de réaction .

Thanh Nguyen
la source
Montrez ce que vous voulez montrer dans plain js, puis rendez-le caché ou supprimez-le du DOM lorsque react est monté. Tout ce que vous avez à faire est de le cacher du code de réaction.
FurkanO
C'est tout simplement merveilleux! Je vous remercie.
Arman Karimi

Réponses:

101

Cela pourrait être fait en plaçant l'icône de chargement dans votre fichier html (index.html par exemple), de sorte que les utilisateurs voient l'icône immédiatement après le chargement du fichier html.

Lorsque votre application a fini de se charger, vous pouvez simplement supprimer cette icône de chargement dans un hook de cycle de vie, je le fais généralement dans componentDidMount.

kkkkkkk
la source
11
Si vous montez le composant racine sur le nœud parent de cette icône, il n'est même pas nécessaire de le supprimer manuellement. React nettoiera les enfants du nœud de montage et y placera son propre DOM nouvellement rendu.
rishat
6
Je ne mets pas l'icône à l'intérieur du nœud racine de l'application React, cela ne me semble tout simplement pas correct
kkkkkkk
172

Le but

Lorsque la page html est rendue, affichez immédiatement un spinner (pendant le chargement de React) et masquez-le une fois React prêt.

Puisque le spinner est rendu en HTML / CSS pur (en dehors du domaine React), React ne doit pas contrôler directement le processus d'affichage / masquage, et l'implémentation doit être transparente pour React.

Solution 1 - La pseudo-classe: vide

Puisque vous effectuez le rendu de react dans un conteneur DOM - <div id="app"></div>, vous pouvez ajouter un spinner à ce conteneur, et lorsque react se chargera et s'affichera, le spinner disparaîtra.

Vous ne pouvez pas ajouter un élément DOM (un div par exemple) dans la racine de réaction, car React remplacera le contenu du conteneur dès qu'il ReactDOM.render()sera appelé. Même si vous effectuez un rendu null, le contenu serait toujours remplacé par un commentaire - <!-- react-empty: 1 -->. Cela signifie que si vous souhaitez afficher le chargeur pendant le montage du composant principal, les données se chargent, mais que rien n'est réellement rendu, un balisage de chargeur placé à l'intérieur du conteneur ( <div id="app"><div class="loader"></div></div>par exemple) ne fonctionnera pas.

Une solution de contournement consiste à ajouter la classe spinner au conteneur de réaction et à utiliser la :emptypseudo-classe . Le spinner sera visible tant que rien n'est rendu dans le conteneur (les commentaires ne comptent pas). Dès que react rendra autre chose qu'un commentaire, le chargeur disparaîtra.

Exemple 1

Dans l'exemple, vous pouvez voir un composant qui effectue le rendu nulljusqu'à ce qu'il soit prêt. Le conteneur est également le chargeur - <div id="app" class="app"></div>et la classe du chargeur ne fonctionnera que si c'est :empty(voir les commentaires dans le code):

Exemple 2

Une variante de l'utilisation de la :emptypseudo-classe pour afficher / masquer un sélecteur consiste à définir le spinner en tant qu'élément frère du conteneur d'application et à l'afficher tant que le conteneur est vide à l'aide du combinateur frère adjacent ( +):


Solution 2 - Passer les "handlers" de spinner comme accessoires

Pour avoir un contrôle plus fin sur l'état d'affichage des fileurs, créez deux fonctions showSpinneret hideSpinner, et transmettez-les au conteneur racine via des accessoires. Les fonctions peuvent manipuler le DOM, ou faire tout ce qui est nécessaire pour contrôler le spinner. De cette façon, React n'est pas conscient du "monde extérieur", et n'a pas besoin de contrôler directement le DOM. Vous pouvez facilement remplacer les fonctions pour les tests, ou si vous avez besoin de changer la logique, et vous pouvez les transmettre à d'autres composants dans l'arborescence React.

Exemple 1

Exemple 2 - crochets

Cet exemple utilise le useEffectcrochet pour masquer la double flèche après le montage du composant.

Ori Drori
la source
Pourriez-vous préciser où devraient se trouver les 2 dernières sections de code? Le premier est clairement dans le fichier javascript src pour le composant react, le troisième, je suppose, va dans le modèle html à rendre par ledit fichier js, mais où va le second?
levraininjaneer
1
Le 2ème est le CSS. J'ai utilisé le CSS global, mais vous pouvez utiliser des modules CSS ou CSS dans JS. Le 3ème est le fichier HTML, qui peut inclure un balisage de spinner si nécessaire (2ème exemple).
Ori Drori
Ce délai n'est pas bon lorsque les performances sont prises en compte.
dryleaf
4
@dryleaf - le setTimeout ne fait pas partie de la solution. Il simule l'attente d'une action asynchrone avant de rendre le contenu.
Ori Drori
J'utilise une approche similaire. Je ne trouve rien dans webpack qui puisse m'aider à casser le cache pour le fichier css requis pour le chargeur. Pouvez-vous m'aider?
hamza-jutt
40

La solution de contournement pour cela est:

Dans votre fonction de rendu, faites quelque chose comme ceci:

constructor() {
    this.state = { isLoading: true }
}

componentDidMount() {
    this.setState({isLoading: false})
}

render() {
    return(
        this.state.isLoading ? *showLoadingScreen* : *yourPage()*
    )
}

Initialiser isLoading comme true dans le constructeur et false sur componentDidMount

Amoolya S Kumar
la source
Lorsque nous avons appelé la méthode ajax pour charger des données dans les composants enfants. componentDidMount appelé avant le remplissage des données du composant enfant. Comment surmonter ce genre de problème?
dush88c
2
Pour le cycle de vie de montage, c'est bien, souhaitez-vous ajouter quelque chose pour le cycle de vie de mise à jour?
zakir
Dois-je le faire dans toutes les pages ou simplement dans l'entrée de l'application
Pedro JR
16

Si vous recherchez une bibliothèque de type drop-in, zero-config et zero-dependencies pour le cas d'utilisation ci-dessus, essayez pace.js ( http://github.hubspot.com/pace/docs/welcome/ ).

Il se connecte automatiquement aux événements (ajax, readyState, pushstate d'historique, boucle d'événements js, etc.) et affiche un chargeur personnalisable.

A bien fonctionné avec nos projets react / relay (gère les changements de navigation à l'aide de react-router, relayer les demandes) (non affilié; avait utilisé pace.js pour nos projets et cela a très bien fonctionné)

Hafiz Ismail
la source
Hey! Pouvez-vous me dire comment l'utiliser avec React?
uneet7
attachez simplement le script public/index.htmlet choisissez un style. c'est un plugin très simple et incroyable. Merci.
PJ3
Je n'aurais pas trouvé le rythme sans cette réponse. C'était si facile à inclure, et avec un peu de magie CSS et quelques pièces jointes d'événements, j'ai pu bloquer / désactiver l'application pendant les transitions et personnaliser le spinner.
invertedSpear
12

Lorsque votre application React est massive, il faut vraiment du temps pour qu'elle soit opérationnelle après le chargement de la page. Dites, vous montez votre partie React de l'application sur #app. Habituellement, cet élément de votre index.html est simplement un div vide:

<div id="app"></div>

Ce que vous pouvez faire à la place, c'est y mettre un peu de style et un tas d'images pour le rendre meilleur entre le chargement de la page et le rendu initial de l'application React vers DOM:

<div id="app">
  <div class="logo">
    <img src="/my/cool/examplelogo.svg" />
  </div>
  <div class="preload-title">
    Hold on, it's loading!
  </div>
</div>

Une fois la page chargée, l'utilisateur verra immédiatement le contenu original de index.html. Peu de temps après, lorsque React est prêt à monter toute la hiérarchie des composants rendus sur ce nœud DOM, l'utilisateur verra l'application réelle.

Remarque class, non className. C'est parce que vous devez le mettre dans votre fichier html.


Si vous utilisez SSR, les choses sont moins compliquées car l'utilisateur verra la vraie application juste après le chargement de la page.

rishat
la source
Cela fonctionne aussi j'ai deux endroits où le chargement se produit. L'un est l' application massive. et ensuite est la préparation (montage de divers composants.) Donc j'obtiens une étape clignotante parce que l'app.render prend le relais et l'animation est réinitialisée ( remplacée vraiment.) Y aurait-il un moyen d'éviter ce flash? React comparera-t-il le DOM un à un? Mais d'après ce que j'ai compris, React ajoute toutes sortes de données privées dans les balises ...
Alexis Wilke
12

Cela se produira avant de ReactDOM.render()prendre le contrôle de la racine <div> . C'est-à-dire que votre application n'aura pas été montée jusqu'à ce point.

Ainsi, vous pouvez ajouter votre chargeur dans votre index.htmlfichier à la racine<div> . Et cela sera visible à l'écran jusqu'à ce que React prenne le relais.

Vous pouvez utiliser tout élément de chargeur qui vous convient le mieux ( svgavec une animation par exemple).

Vous n'avez pas besoin de le supprimer sur aucune méthode de cycle de vie. React remplacera tous les enfants de sa racine <div> par votre rendu <App/>, comme nous pouvons le voir dans le GIF ci-dessous.

Exemple sur CodeSandbox

entrez la description de l'image ici

index.html

<head>
  <style>
    .svgLoader {
      animation: spin 0.5s linear infinite;
      margin: auto;
    }
    .divLoader {
      width: 100vw;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
  </style>
</head>

<body>
  <div id="root">
    <div class="divLoader">
      <svg class="svgLoader" viewBox="0 0 1024 1024" width="10em" height="10em">
        <path fill="lightblue"
          d="PATH FOR THE LOADER ICON"
        />
      </svg>
    </div>
  </div>
</body>

index.js

Utilisation debuggerpour inspecter la page avant de ReactDOM.render()s'exécuter.

import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";

function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

debugger; // TO INSPECT THE PAGE BEFORE 1ST RENDER

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
cbdeveloper
la source
une solution belle et élégante
Gal Margalit
1
Je suis content que ça aide!
cbdeveloper
9

De nos jours, nous pouvons également utiliser des hooks dans React 16.8:

import React, { useState, useEffect } from 'react';

const App = () => {
  const [ spinner, setSpinner ] = useState(true);

  // It will be executed before rendering

  useEffect(() => {
    setTimeout(() => setSpinner(false), 1000)
  }, []);

  // [] means like componentDidMount

  return !spinner && <div>Your content</div>;
};

export default App;
Max Kalik
la source
5

La définition du délai d'expiration dans componentDidMount fonctionne mais dans mon application, j'ai reçu un avertissement de fuite de mémoire. Essayez quelque chose comme ça.

constructor(props) {
    super(props)
    this.state = { 
      loading: true,
    }
  }
  componentDidMount() {
    this.timerHandle = setTimeout(() => this.setState({ loading: false }), 3500); 
  }

  componentWillUnmount(){
    if (this.timerHandle) {
      clearTimeout(this.timerHandle);
      this.timerHandle = 0;
    }
  }
Rich Costello
la source
4

J'ai dû faire face à ce problème récemment et j'ai trouvé une solution, qui fonctionne très bien pour moi. Cependant, j'ai essayé la solution @Ori Drori ci-dessus et malheureusement cela n'a pas fonctionné correctement (il y a eu des retards + je n'aime pas l'utilisation desetTimeout fonction là-bas).

Voici ce que j'ai proposé:

index.html fichier

headBalise intérieure - styles pour l'indicateur:

<style media="screen" type="text/css">

.loading {
  -webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
  animation: sk-scaleout 1.0s infinite ease-in-out;
  background-color: black;
  border-radius: 100%;
  height: 6em;
  width: 6em;
}

.container {
  align-items: center;
  background-color: white;
  display: flex;
  height: 100vh;
  justify-content: center;
  width: 100vw;
}

@keyframes sk-scaleout {
  0% {
    -webkit-transform: scale(0);
    transform: scale(0);
  }
  100% {
    -webkit-transform: scale(1.0);
    opacity: 0;
    transform: scale(1.0);
  }
}

</style>

Maintenant le bodytag:

<div id="spinner" class="container">
  <div class="loading"></div>
</div>

<div id="app"></div>

Et puis vient une logique très simple, à l'intérieur du app.jsfichier (dans la fonction de rendu):

const spinner = document.getElementById('spinner');

if (spinner && !spinner.hasAttribute('hidden')) {
  spinner.setAttribute('hidden', 'true');
}

Comment ça marche?

Lorsque le premier composant (dans mon application, c'est app.jsaussi dans la plupart des cas) se monte correctement, le spinnerest masqué avec un hiddenattribut qui lui est appliqué .

Ce qui est plus important à ajouter - la !spinner.hasAttribute('hidden')condition empêche d'ajouter un hiddenattribut au spinner avec chaque montage de composant, donc en fait, il ne sera ajouté qu'une seule fois, lorsque l'application entière se chargera.

gentil utilisateur
la source
4

J'utilise le package npm react -progress-2 , qui est sans dépendance et fonctionne très bien dans ReactJS.

https://github.com/milworm/react-progress-2

Installation:

npm install react-progress-2

Incluez react-progress-2 / main.css dans votre projet.

import "node_modules/react-progress-2/main.css";

Incluez-le react-progress-2et placez-le quelque part dans le composant supérieur, par exemple:

import React from "react";
import Progress from "react-progress-2";

var Layout = React.createClass({
render: function() {
    return (
        <div className="layout">
            <Progress.Component/>
                {/* other components go here*/}
            </div>
        );
    }
});

Désormais, chaque fois que vous avez besoin d'afficher un indicateur, il vous suffit d'appeler Progress.show(), par exemple:

loadFeed: function() {
    Progress.show();
    // do your ajax thing.
},

onLoadFeedCallback: function() {
    Progress.hide();
    // render feed.
}

Veuillez noter que showet les hideappels sont empilés, donc après n appels consécutifs, vous devez masquer n appels pour masquer un indicateur ou vous pouvez utiliser Progress.hideAll().

Alex Zavrazhniy
la source
4

J'utilise également React dans mon application. Pour les demandes que j'utilise des intercepteurs axios, un excellent moyen de créer un écran de chargement (page complète comme vous l'avez montré un exemple) est d'ajouter une classe ou un identifiant, par exemple au corps à l'intérieur des intercepteurs (ici le code de la documentation officielle avec du code personnalisé):

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
     document.body.classList.add('custom-loader');
     return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
       document.body.classList.remove('custom-loader');
       return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  }); 

Et puis implémentez simplement en CSS votre chargeur avec des pseudo-éléments (ou ajoutez une classe ou un id à un élément différent, pas au corps comme vous le souhaitez) - vous pouvez définir la couleur de l'arrière-plan sur opaque ou transparent, etc ... Exemple:

custom-loader:before {
    background: #000000;
    content: "";
    position: fixed;
    ...
}

custom-loader:after {
    background: #000000;
    content: "Loading content...";
    position: fixed;
    color: white;
    ...
}
adrian95999
la source
3

Modifiez l'emplacement de votre fichier index.html dans le dossier public . Copiez votre image au même emplacement que index.html dans le dossier public. Et puis remplacez la partie du contenu de index.html contenant les <div id="root"> </div>balises par le code html donné ci-dessous.

<div id="root">  <img src="logo-dark300w.png" alt="Spideren" style="vertical-align: middle; position: absolute;
   top: 50%;
   left: 50%;
   margin-top: -100px; /* Half the height */
   margin-left: -250px; /* Half the width */" />  </div>

Le logo apparaîtra maintenant au milieu de la page pendant le processus de chargement. Et sera ensuite remplacé au bout de quelques secondes par React.

Magnus Melwin
la source
2

Vous n'avez pas besoin de beaucoup d'efforts, voici un exemple de base.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="theme-color" content="#000000" />
  <meta name="description" content="Web site created using create-react-app" />
  <link rel="apple-touch-icon" href="logo192.png" />
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
  <title>Title</title>
  <style>
    body {
      margin: 0;
    }

    .loader-container {
      width: 100vw;
      height: 100vh;
      display: flex;
      overflow: hidden;
    }

    .loader {
      margin: auto;
      border: 5px dotted #dadada;
      border-top: 5px solid #3498db;
      border-radius: 50%;
      width: 100px;
      height: 100px;
      -webkit-animation: spin 2s linear infinite;
      animation: spin 2s linear infinite;
    }

    @-webkit-keyframes spin {
      0% {
        -webkit-transform: rotate(0deg);
      }

      100% {
        -webkit-transform: rotate(360deg);
      }
    }

    @keyframes spin {
      0% {
        transform: rotate(0deg);
      }

      100% {
        transform: rotate(360deg);
      }
    }

  </style>
</head>

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root">
    <div class="loader-container">
      <div class="loader"></div>
    </div>
  </div>
</body>

</html>

Vous pouvez jouer avec HTMLet CSSfaire ressembler à votre exemple.

Ahmed Kamal
la source
1

La question la plus importante est: qu'entendez-vous par «chargement»? Si vous parlez de l'élément physique en cours de montage, certaines des premières réponses ici sont excellentes. Cependant, si la première chose que fait votre application est de vérifier l'authentification, ce que vous chargez réellement, ce sont les données du backend, que l'utilisateur ait transmis un cookie qui les qualifie d'utilisateur autorisé ou non autorisé.

Ceci est basé sur redux, mais vous pouvez facilement le changer en modèle d'état de réaction simple.

créateur d'action:

export const getTodos = () => {
  return async dispatch => {
    let res;
    try {
      res = await axios.get('/todos/get');

      dispatch({
        type: AUTH,
        auth: true
      });
      dispatch({
        type: GET_TODOS,
        todos: res.data.todos
      });
    } catch (e) {
    } finally {
      dispatch({
        type: LOADING,
        loading: false
      });
    }
  };
};

La dernière partie signifie que l'utilisateur est authentifié ou non, l'écran de chargement disparaît après la réception d'une réponse.

Voici à quoi pourrait ressembler un composant qui le charge:

class App extends Component {
  renderLayout() {
    const {
      loading,
      auth,
      username,
      error,
      handleSidebarClick,
      handleCloseModal
    } = this.props;
    if (loading) {
      return <Loading />;
    }
    return (
      ...
    );
  }

  ...

  componentDidMount() {
    this.props.getTodos();
  }

...

  render() {
    return this.renderLayout();
 }

}

Si state.loading est véridique, nous verrons toujours un écran de chargement. Sur componentDidMount, nous appelons notre fonction getTodos, qui est un créateur d'action qui rend state.loading faux lorsque nous obtenons une réponse (ce qui peut être une erreur). Notre composant est mis à jour, les appels sont à nouveau rendus, et cette fois, il n'y a pas d'écran de chargement à cause de l'instruction if.

user3605834
la source
1

Le démarrage de l'application react est basé sur le téléchargement du bundle principal. L'application React ne démarre qu'après le téléchargement du bundle principal dans le navigateur. Cela est même vrai en cas d'architecture de chargement paresseux. Mais le fait est que nous ne pouvons pas indiquer exactement le nom des bundles. Parce que webpack ajoutera une valeur de hachage à la fin de chaque bundle au moment où vous exécuterez la commande 'npm run build'. Bien sûr, nous pouvons éviter cela en modifiant les paramètres de hachage, mais cela affectera sérieusement le problème des données de cache dans le navigateur. Les navigateurs peuvent ne pas accepter la nouvelle version en raison du même nom de bundle. . nous avons besoin d'une approche webpack + js + CSS pour gérer cette situation.

changez le public / index.html comme ci-dessous

<!DOCTYPE html>
<html lang="en" xml:lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=3.0, shrink-to-fit=no">
  <meta name="theme-color" content="#000000">
  <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
  <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
  <style>
 .percentage {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 150px;
      height: 150px;
      border: 1px solid #ccc;
      background-color: #f3f3f3;
      -webkit-transform: translate(-50%, -50%);
          -ms-transform: translate(-50%, -50%);
              transform: translate(-50%, -50%);
      border: 1.1em solid rgba(0, 0, 0, 0.2);
      border-radius: 50%;
      overflow: hidden;
      display: -webkit-box;
      display: -ms-flexbox;
      display: flex;
      -webkit-box-pack: center;
          -ms-flex-pack: center;
              justify-content: center;
      -webkit-box-align: center;
          -ms-flex-align: center;
              align-items: center;
    }

    .innerpercentage {
      font-size: 20px;
    }
  </style>
  <script>
    function showPercentage(value) {
      document.getElementById('percentage').innerHTML = (value * 100).toFixed() + "%";
    }
    var req = new XMLHttpRequest();
    req.addEventListener("progress", function (event) {
      if (event.lengthComputable) {
        var percentComplete = event.loaded / event.total;
        showPercentage(percentComplete)
        // ...
      } else {
        document.getElementById('percentage').innerHTML = "Loading..";
      }
    }, false);

    // load responseText into a new script element
    req.addEventListener("load", function (event) {
      var e = event.target;
      var s = document.createElement("script");
      s.innerHTML = e.responseText;
      document.documentElement.appendChild(s);
      document.getElementById('parentDiv').style.display = 'none';

    }, false);

    var bundleName = "<%= htmlWebpackPlugin.files.chunks.main.entry %>";
    req.open("GET", bundleName);
    req.send();

  </script>
  <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->

  <title>App Name</title>
  <link href="<%= htmlWebpackPlugin.files.chunks.main.css[0] %>" rel="stylesheet">
</head>

<body>
  <noscript>
    You need to enable JavaScript to run this app.
  </noscript>
  <div id="parentDiv" class="percentage">
    <div id="percentage" class="innerpercentage">loading</div>
  </div>
  <div id="root"></div>
  <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
</body>

</html>

Dans la configuration de votre webpack de production, modifiez l'option HtmlWebpackPlugin ci-dessous

 new HtmlWebpackPlugin({
          inject: false,
...

Vous devrez peut-être utiliser la commande «eject» pour obtenir le fichier de configuration. le dernier webpack peut avoir la possibilité de configurer le HtmlWebpackPlugin sans éjecter le projet. entrez la description de l'image ici

Anoop Chillayi Kochappu
la source
1

J'ai également utilisé la réponse de @Ori Drori et j'ai réussi à la faire fonctionner. Au fur et à mesure que votre code React grandit, les bundles compilés que le navigateur client devra télécharger lors du premier accès le feront également. Cela pose un problème d'expérience utilisateur si vous ne le gérez pas bien.

Ce que j'ai ajouté à la réponse @Ori était d'ajouter et d'exécuter la fonction onload dans l'attribut index.html onload de la balise body, de sorte que le chargeur disparaisse une fois que tout a été complètement chargé dans la navigation, voir l'extrait ci-dessous:

<html>
  <head>
     <style>
       .loader:empty {
          position: absolute;
          top: calc(50% - 4em);
          left: calc(50% - 4em);
          width: 6em;
          height: 6em;
          border: 1.1em solid rgba(0, 0, 0, 0.2);
          border-left: 1.1em solid #000000;
          border-radius: 50%;
          animation: load8 1.1s infinite linear;
        }
        @keyframes load8 {
          0% {
           transform: rotate(0deg);
          }
          100% {
           transform: rotate(360deg);
          }
        }
     </style>
     <script>
       function onLoad() {
         var loader = document.getElementById("cpay_loader");loader.className = "";}
     </script>
   </head>
   <body onload="onLoad();">
     more html here.....
   </body>
</html>
Joseph Tabajjwa
la source
1

Qu'en est-il de l'utilisation de Pace

Utilisez cette adresse de lien ici.

https://github.hubspot.com/pace/docs/welcome/

1.Sur leur site Web, sélectionnez le style que vous souhaitez et collez-le dans index.css

2. aller à cdnjs Copiez le lien pour Pace Js et ajoutez à votre script des balises dans public / index.html

3.Il détecte automatiquement les charges Web et affiche le rythme dans le navigateur Top.

Vous pouvez également modifier la hauteur et l'animation dans le css.

roqkabel
la source
Génial et peut être intégré en un rien de temps.
UzumakiL