반응-DOM이 렌더링되는 동안 로딩 화면이 표시됩니까?


150

Google Adsense 애플리케이션 페이지의 예입니다. 메인 페이지 이전에 표시된 로딩 화면이 나타납니다.

여기에 이미지 설명을 입력하십시오

React와 동일한 작업을 수행하는 방법을 모르겠습니다 .React 구성 요소로 렌더링 된 로딩 화면을 만들면 DOM이 렌더링 될 때까지 기다려야하기 때문에 페이지가로드되는 동안 표시되지 않기 때문입니다.

업데이트 :

스크린 로더를 넣고 index.htmlReact componentDidMount()수명주기 방법으로 제거하여 접근 방식의 예를 만들었습니다 .

반응 로딩 화면 .


일반 js로 표시하려는 내용을 표시 한 다음 반응이 마운트되면 DOM에서 숨기거나 제거하십시오. 반응 코드에서 숨기면됩니다.
FurkanO

이것은 단순히 훌륭합니다! 감사합니다.
Arman Karimi

답변:


100

로드 아이콘을 html 파일 (예 : index.html)에 배치하면 html 파일이로드 된 후 바로 아이콘을 볼 수 있습니다.

앱이 로딩을 마치면 라이프 사이클 후크에서 로딩 아이콘을 제거 할 수 componentDidMount있습니다.


11
루트 구성 요소를 해당 아이콘의 상위 노드에 마운트하면 수동으로 제거 할 필요가 없습니다. React는 마운트 노드의 자식을 정리하고 새로 렌더링 된 DOM을 대신 배치합니다.
rishat

6
아이콘을 React 앱의 루트 노드 안에 넣지 않습니다. 아이콘이 제게 맞지 않습니다
kkkkkkk

171

목표

html 페이지가 렌더링되면 스피너를 즉시 표시하고 (React가로드되는 동안) React가 준비되면 숨 깁니다.

스피너는 순수한 HTML / CSS (React 도메인 외부)로 렌더링되므로 React는 표시 / 숨김 프로세스를 직접 제어하지 않아야하며 구현은 React에 투명해야합니다.

해결 방법 1-: 비상 의사 클래스

반응을 DOM 컨테이너에 렌더링하기 때문에 <div id="app"></div>해당 컨테이너에 스피너를 추가 할 수 있으며 반응이로드되어 렌더링되면 스피너가 사라집니다.

React ReactDOM.render()가 호출 되는 즉시 컨테이너의 내용을 대체하므로 반응 루트 내에 DOM 요소 (예 : div)를 추가 할 수 없습니다 . 렌더링하더라도 null내용은 여전히 ​​주석으로 대체됩니다 <!-- react-empty: 1 -->. 즉, 주요 구성 요소가 마운트되는 동안 로더를 표시하려는 경우 데이터가로드되지만 실제로 아무것도 렌더링 <div id="app"><div class="loader"></div></div>되지 않으면 컨테이너 ( 예 :) 내부에 배치 된 로더 마크 업 이 작동하지 않습니다.

해결 방법은 스피너 클래스를 반응 컨테이너에 추가하고 :empty의사 클래스를 사용하는 것 입니다. 컨테이너에 아무것도 렌더링되지 않는 한 스피너가 표시됩니다 (코멘트는 포함되지 않음). 반응이 주석 이외의 것을 렌더링하자마자 로더가 사라집니다.

실시 예 1

이 예에서는 null준비 될 때까지 렌더링되는 구성 요소를 볼 수 있습니다 . 컨테이너도 로더입니다- <div id="app" class="app"></div>그리고 로더의 클래스는 그것이 작동하는 경우에만 작동합니다 :empty(코드 주석 참조).

실시 예 2

:empty의사 클래스를 사용하여 선택기를 표시하거나 숨기는 변형 은 스피너를 앱 컨테이너의 형제 요소로 설정하고 인접한 형제 조합기 ( +)를 사용하여 컨테이너가 비어있는 동안 표시하는 것입니다 .


해결 방법 2- 스피너 "핸들러"를 소품으로 전달

, 스피 표시 상태를 통해보다 세밀하게 제어 할 수 있습니다 두 가지 기능을 만들려면 showSpinner하고 hideSpinner, 소품을 통해 루트 컨테이너로 전달합니다. 함수는 DOM을 조작하거나 스피너를 제어하는 ​​데 필요한 모든 작업을 수행 할 수 있습니다. 이런 식으로 React는 "외부 세계"를 인식하지 못하고 DOM을 직접 제어 할 필요가 없습니다. 테스트 할 기능을 쉽게 교체하거나 로직을 변경해야하는 경우 React 트리의 다른 구성 요소로 전달할 수 있습니다.

실시 예 1

예 2-후크

이 예에서는 useEffect구성 요소가 마운트 된 후 후크를 사용하여 스피너를 숨 깁니다.


마지막 2 개의 코드 섹션이 어디에 있는지 명확히 할 수 있습니까? 첫 번째는 반응 구성 요소의 자바 스크립트 src 파일에 있으며, 세 번째는 html 템플릿으로 이동하여 해당 js 파일에 의해 렌더링되지만 두 번째는 어디로 이동합니까?
levraininjaneer

1
두 번째는 CSS입니다. 글로벌 CSS를 사용했지만 JS에서 CSS 모듈 또는 CSS를 사용할 수 있습니다. 세 번째는 HTML 파일이며 필요한 경우 스피너 마크 업을 포함 할 수 있습니다 (두 번째 예).
오리 드 로리

성능을 고려할 때 시간 초과가 좋지 않습니다.
dryleaf

4
@dryleaf-setTimeout은 솔루션의 일부가 아닙니다. 컨텐츠를 렌더링하기 전에 비동기 조치 대기를 시뮬레이트합니다.
오리 Drori

나는 비슷한 접근법을 사용합니다. 로더에 필요한 CSS 파일의 캐시를 버스트하는 데 도움이되는 웹 팩에서 아무것도 찾을 수 없습니다. 도울 수 있니?
hamza-jutt '

40

이에 대한 해결 방법은 다음과 같습니다.

렌더링 함수에서 다음과 같이하십시오.

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

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

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

생성자에서 isLoading을 true로, componentDidMount에서 false를 초기화합니다.


하위 컴포넌트에 데이터를로드하기 위해 ajax 메소드를 호출 한 경우 하위 구성 요소 데이터가 채워지기 전에 componentDidMount가 호출되었습니다. 우리는 이런 종류의 문제를 어떻게 극복합니까?
dush88c

2
Mounting Life cyle의 경우 문제가되지 않습니다. 업데이트 수명주기를 위해 무언가를 추가 하시겠습니까?
zakir

모든 페이지 또는 앱 항목에서이 작업을 수행해야합니까
Pedro JR

16

위의 유스 케이스에 대해 드롭 인, 제로 구성 및 제로 종속성 라이브러리를 찾는 사람이 있다면 pace.js ( http://github.hubspot.com/pace/docs/welcome/ )를 사용해보십시오 .

이벤트 (ajax, readyState, history pushstate, js event loop 등)에 자동으로 연결되어 사용자 정의 가능한 로더를 보여줍니다.

리 액트 / 릴레이 프로젝트 (리 액트 라우터, 릴레이 요청을 사용하여 탐색 변경 처리) 와 잘 작동했습니다.


야! 반응과 함께 사용하는 방법을 알려주시겠습니까?
uneet7

스크립트를 첨부하고 public/index.html스타일을 선택하십시오. 이것은 간단하고 놀라운 플러그인입니다. 감사합니다.
PJ3

이 답변이 없으면 페이스를 찾을 수 없었을 것입니다. 포함하기가 쉬웠으며 CSS 마술과 일부 이벤트 첨부 파일을 사용하면 전환 중에 앱을 차단 / 비활성화하고 스피너를 사용자 정의 할 수있었습니다.
invertedSpear

12

React 앱이 방대한 경우 페이지가로드 된 후 앱이 시작되고 실행되는 데 실제로 시간이 걸립니다. 앱의 React 부분을에 마운트한다고 가정 해보십시오 #app. 일반적으로 index.html의이 요소는 단순히 빈 div입니다.

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

대신 페이지로드와 DOM에 대한 초기 React 앱 렌더링 사이에서 더 잘 보이도록 몇 가지 스타일과 이미지를 배치하십시오.

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

페이지가로드되면 index.html의 원래 내용을 즉시 볼 수 있습니다. 곧 React가 렌더링 된 컴포넌트의 전체 계층을이 DOM 노드에 마운트 할 준비가되면 실제 앱이 표시됩니다.

참고 class하지 className. 이것을 html 파일에 넣어야하기 때문입니다.


SSR을 사용하면 페이지가로드 된 후 사용자가 실제 앱을 실제로 볼 수 있기 때문에 작업이 덜 복잡해집니다.


이것은 또한로드가 발생하는 두 곳이 있습니다. 하나는 대규모 앱입니다. 다음은 준비 (다양한 구성 요소 장착)입니다. 따라서 app.render가 대신하고 애니메이션이 재설정 ( 교체) 되기 때문에 깜박임 단계를 수행합니다. 정말 ) . 플래시를 피할 수있는 방법이 있습니까? React는 DOM을 일대일로 비교합니까? 그러나 내가 이해 한 바에 따르면 React는 모든 종류의 개인 데이터를 태그에 추가합니다.
Alexis Wilke

12

이것은 루트를ReactDOM.render() 제어 하기 전에 발생 합니다 <div> . 즉, 앱이 해당 시점까지 마운트되지 않았습니다.

따라서 index.html루트 안의 파일에 로더를 추가 할 수 있습니다 <div>. 그리고 React가 인수 할 때까지 화면에 표시됩니다.

가장 적합한 로더 요소 svg를 애니메이션으로 사용할 수 있습니다 .

수명주기 방법에서 제거 할 필요는 없습니다. 아래 GIF에서 볼 수 있듯이 React는 루트 의 모든 하위 요소를 <div>렌더링 된로 대체합니다 <App/>.

CodeSandbox의 예

여기에 이미지 설명을 입력하십시오

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

실행 debugger하기 전에 페이지를 검사하는 데 사용 ReactDOM.render()합니다.

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);

아름답고 우아한 솔루션
Gal Margalit

1
도움이 되서 다행입니다.
cbdeveloper

9

요즘에는 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;

5

componentDidMount에서 시간 초과를 설정해도 작동하지만 내 응용 프로그램에서 메모리 누수 경고를 받았습니다. 이와 같은 것을 시도하십시오.

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;
    }
  }

4

나는 최근에 그 문제를 해결해야했고 해결책이 나에게 잘 어울렸다. 그러나 위의 @Ori Drori 솔루션을 사용해 보았지만 불행히도 제대로 작동하지 않았습니다 (지연이 있었지만 사용법이 마음에 들지 않습니다.setTimeout 기능 ).

이것이 내가 생각해 낸 것입니다.

index.html 파일

내부 head 태그-표시기 스타일 :

<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>

이제body 태그 :

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

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

그런 다음app.js 파일 내 (렌더링 기능에서) 매우 간단한 논리가 제공됩니다 .

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

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

어떻게 작동합니까?

첫 번째 구성 요소 ( app.js대부분의 경우에도 마찬가지로)가 올바르게 마운트되면 속성 spinner이 적용되어 숨겨집니다 hidden.

추가하는 것이 더 중요합니다- !spinner.hasAttribute('hidden')조건 hidden은 모든 구성 요소를 마운트 할 때마다 스피너 에 속성 을 추가하지 못하게 하므로 실제로는 전체 앱이로드 될 때 한 번만 추가됩니다.


4

나는 의존성이 없으며 ReactJS에서 훌륭하게 작동 하는 react-progress-2 npm 패키지를 사용하고 있습니다.

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

설치:

npm install react-progress-2

react-progress-2 / main.css를 프로젝트에 포함하십시오.

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

react-progress-2예를 들어 다음과 같이 상단 구성 요소의 어딘가에 포함 시키십시오.

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>
        );
    }
});

이제 표시기를 표시해야 할 때마다 다음 Progress.show()과 같이 전화하십시오 .

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

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

참고 것을 바랍니다 showhide통화를 적층, 그래서 N-연속 공연 호출 후, 당신은 할 N 숨기기 통화 지표를 숨기거나 사용할 수있는 필요 Progress.hideAll().


4

내 앱에서도 React를 사용하고 있습니다. 요청에 대해서는 axios 인터셉터를 사용하고 있으므로 로더 화면을 만드는 좋은 방법 (예를 보여 주듯이 전체 페이지)은 인터셉터 내부의 본문 (여기서는 사용자 정의 코드가있는 공식 문서의 코드)에 클래스 또는 ID를 추가하는 것입니다.

// 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);
  }); 

그런 다음 CSS에서 의사 요소로 로더를 구현하십시오 (또는 원하는대로 본문이 아닌 다른 요소에 클래스 또는 ID를 추가하십시오)-배경색을 불투명하거나 투명하게 설정할 수 있습니다 ... 예 :

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

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

3

공용 폴더 에서 index.html 파일 위치를 편집하십시오 . 공용 폴더의 index.html 과 동일한 위치에 이미지를 복사하십시오 . 그런 다음 <div id="root"> </div>태그가 포함 된 index.html 내용의 일부를 아래 주어진 html 코드로 바꿉니다.

<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>

로딩 과정에서 페이지 중간에 로고가 나타납니다. 그런 다음 몇 초 후에 React로 대체됩니다.


2

많은 노력이 필요하지 않습니다. 기본 예는 다음과 같습니다.

<!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>

당신은 함께 놀러 수 HTMLCSS그것은 당신의 예처럼 보이는 있도록.


1

가장 중요한 질문은 '로드'가 무슨 뜻입니까? 실장되는 물리적 요소에 대해 이야기하고 있다면 여기의 첫 번째 대답 중 일부가 훌륭합니다. 그러나 앱에서 가장 먼저 인증을 확인하는 것이라면 실제로로드하는 것은 사용자가 쿠키를 통과했는지 여부에 관계없이 백엔드의 데이터입니다.

이것은 redux를 기반으로하지만 일반 반응 상태 모델로 쉽게 변경할 수 있습니다.

액션 크리에이터 :

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
      });
    }
  };
};

마지막 부분은 사용자의 인증 여부를 의미하며 응답이 수신 된 후 로딩 화면이 사라집니다.

로드하는 구성 요소는 다음과 같습니다.

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();
 }

}

state.loading이 사실이라면 항상 로딩 화면이 나타납니다. componentDidMount에서 getTodos 함수를 호출합니다.이 함수는 응답을받을 때 state.loading을 거짓으로 만드는 액션 생성자입니다 (오류 일 수 있음). 컴포넌트 업데이트, 호출 렌더 다시, 이번에는 if 문으로 인해 로딩 화면이 없습니다.


1

반응 앱의 시작은 기본 번들 다운로드를 기반으로합니다. React 앱은 브라우저에서 기본 번들을 다운로드 한 후에 만 ​​시작됩니다. 게으른 로딩 아키텍처의 경우에도 마찬가지입니다. 그러나 실제로 번들 이름을 정확하게 말할 수는 없습니다. 'npm run build'명령을 실행할 때 webpack은 각 번들의 끝에 해시 값을 추가하기 때문입니다. 물론 해시 설정을 변경하여이를 피할 수 있지만 브라우저의 캐시 데이터 문제에 심각한 영향을 미칩니다. 동일한 번들 이름으로 인해 브라우저가 새 버전을 가져 오지 못할 수 있습니다. . 이 상황을 처리하려면 webpack + js + CSS 접근법이 필요합니다.

아래와 같이 public / index.html을 변경하십시오

<!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>

프로덕션 웹팩 구성에서 HtmlWebpackPlugin 옵션을 아래로 변경하십시오.

 new HtmlWebpackPlugin({
          inject: false,
...

구성 파일을 가져 오려면 'eject'명령을 사용해야 할 수도 있습니다. 최신 웹팩에는 프로젝트를 추출하지 않고 HtmlWebpackPlugin을 구성하는 옵션이있을 수 있습니다. 여기에 이미지 설명을 입력하십시오


1

또한 @Ori Drori의 답변을 사용하여 제대로 작동했습니다. React 코드가 커짐에 따라 클라이언트 브라우저를 처음 액세스 할 때 다운로드하도록 번들이 컴파일됩니다. 제대로 처리하지 않으면 사용자 경험 문제가 발생합니다.

@Ori 답변에 추가 한 것은 body 태그의 onload 속성에서 index.html에 onload 함수를 추가하고 실행하여 모든 것이 찾아보기에 완전히로드 된 후 로더가 사라지게하는 것입니다. 아래 스 니펫을 참조하십시오.

<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>

1

페이스 사용은 어떻습니까

이 링크 주소를 사용하십시오.

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

1. 웹 사이트에서 원하는 스타일을 선택하고 index.css에 붙여 넣습니다.

2. cdnjs로 이동 Pace J에 대한 링크를 복사하고 public / index.html의 스크립트 태그에 추가하십시오.

3. 자동으로 웹로드를 감지하고 브라우저 상단에 페이스를 표시합니다.

CSS에서 높이와 애니메이션을 수정할 수도 있습니다.


대단하고 빠르게 통합 될 수 있습니다.
UzumakiL
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.