mingg IT

[React] 코드 스플리팅 예시(class, 함수, loadable) 본문

FrontEnd

[React] 코드 스플리팅 예시(class, 함수, loadable)

mingg123 2022. 2. 1. 23:12

컴포넌트 형 코드 스플릿팅 예시

App.js

import logo from './logo.svg';
import './App.css';
import { Component } from 'react';
class App extends Component {
  state = {
    SplitMe: null,
  };

  handleClick = async () => {
    const loadedModule = await import('./SplitMe');
    this.setState({
      SplitMe: loadedModule.default,
    });
  };
  render() {
    const { SplitMe } = this.state;
    return (
      <div className="App">
        <p onClick={this.handleClick}>Hello React! </p>
        {SplitMe && <SplitMe />}
      </div>
    );
  }
}

export default App;

SplitMe.js

import React from 'react';

const SplitMe = () => {
  return <div>SplitMe</div>;
};

export default SplitMe;

SplitMe_js chunk가 만들어졌음을 알 수 있다.

허나 해당방식은 state를 사용하여 코드 스플릿팅을 해야하기 때문에 조금 불편하다.

이러한 불편함을 개선할 수 있는 것이 React.lazy와 Suspense를 사용하는 것임.

React.lazy

  • 컴포넌트를 렌더링하는 시점에서 비동기적으로 로딩할 수 있게 해 주는 유틸함수.

Suspense

  • 리액트 내장 컴포넌트로서 코드 스플리팅된 컴포넌트를 로딩하도록 발동시킬 수 있고, 로딩이 끝나지 않았을 때 보여 줄 UI를 설정할 수 있음.

React.lazy, Suspense는 서버 사이드 렌더링을 지원하지 않음.

✔️서버 사이드 렌더링 이란?

웹 서비스의 초기 로딩 속도 개선, 캐싱 및 검색 엔진 최적화를 가능하도록 하게 해주는 기술임. 웹 서비스의 초기 렌더링을 서버 쪽에서 처리하기 때문에 사용자는 서버에서 렌더링한 html 결과물을 받아와서 그대로 사용함. 이로 인해 초기 로딩 속도도 개선되고, 검색 엔진에서 크롤링할 때도 문제없음.

함수형 코드 스플릿팅 예시 (lazy, Suspense 사용)

App.js

const SplitMe = React.lazy(() => import('./SplitMe'));
const App = () => {
  const [visible, setVisible] = useState(false);
  const onClick = () => {
    setVisible(true);
  };
  return (
    <div className="App">
      <p onClick={onClick}>Hello React! </p>
      <Suspense fallback={<div>loading...</div>}>
        {visible && <SplitMe />}
      </Suspense>
    </div>
  );
};
export default App;

네트워크 설정을 Slow3G로 설정한 이후 테스트해보면 loading이 뜨는 것을 알 수 있다.

Loadable Components를 이용한 코드 스플리팅

코드 스플리팅을 편하게 하도록 도와주는 라이브러리임. 서브 사이드 렌더링을 지원함.

아주 간단하게 사용법만 알아보도록 하겠음.

yarn add @loadable/component

App.js

import loadable from '@loadable/component';
const SplitMe = loadable(() => import('./SplitMe'), {
  fallback: <div>loading...</div>,
});
const App = () => {
  const [visible, setVisible] = useState(false);
  const onClick = () => {
    setVisible(true);
  };
  const onMouseOver = () => {
    SplitMe.preload();
  };
  return (
    <div className="App">
      <p onClick={onClick} onMouseOver={onMouseOver}>
        Hello React!
      </p>
      {visible && <SplitMe />}
    </div>
  );
};
export default App;

보면 마우스를 올리게되면 해당 이벤트가 발생하여 SplitMe를 렌더링하는 것을 확인할 수 있음. 마찬가지로 fallback을 이용해서 로딩중 일 때 UI를 보여줄 수 있고 loadable을 사용함.

곧 리액트18에선 서버사이드렌더링도 가능하다고 하니 대체되겠지만 18이전 버전에서도 리액트공식문서에는 서버사이드 랜더링 시에는 Loadable Components를 사용하고, 서버사이드렌더링을 할 계획이 없다면 React.lazy, Suspense로 구현하라고 나와있음.

 

Comments