내가 현재 만지는 소스에 lazy가 있다!
찾아보면 간단하게 말해서 늦게 컴포넌트 불러와주고, 그래서 코드스플리팅이 가능케 한다. 동적 import를 해준다 라고 나온다. 대강은 느낌이 오는데.. 왜 쓸까? 동적 임포트 왜? 찾아보면 한국 포스팅 자료는 다 퍼포먼스가 좋아진다, 효율이 좋아진다 그런식으로 말하고 넘어가는데.. 아마 글을 쓰는 사람도 확실한 이해는 잘 못하고 넘어가서 그런 내용이 없는 것 같았다(구현 소스 포스팅 해준것만으로 사실 감사하다. 약간의 아쉬움정도). 그래서 why use lazy, 또는 reason to use dynamic import 정도로 구글링 하면 영어로는 괜찮은 문서가 나온다!(이것이 개발자가 영어를 잘해야(독해, 영작) .. 아니 어느정도는 해야 하는 이유!!)
출처 : https://mcapoz.medium.com/how-to-use-react-lazy-6ff434aeed51
번역->
Suspense API를 사용하는 코드 스플리팅을 React.lazy가 해준다.
lazy는 전제조건이 다 충족되지 까지 ui가 랜더링 되는걸 블락하게 해준다! 만약 니가 한 endpoint로 부터 니가 response얻을 때까지 "컴포넌트야 랜더 하지마!!" 라고 원할것이다.
lazy 이전엔 넌 그 뷰에서 모든걸 로드 했어야 했다. 심지어 숨어있는것 까지도.
니가 아래 사이트 만들었다고 생각해봐
오른쪽 카트 누르면 오른쪽 사이드로부터 슬라이드 나오거든.
근데 지금 바로 보면, 우리는 PanelOverlay 컴포넌트를 우리가 /
로드할때 로드 하거든. 하지만 lazy와 함께라면 우리는 카트버튼 클릭 한 후에 그 Panel 컴포넌트를 import 할수 이쒀.
넌 lazy()
랑 react-loadable
이랑 뭐가 다른지 궁금할거야(아니 궁금해야뒈!!)
lazy()
는 니 코드 베이스에서 다른 디펜던시 추가 없이도 코드스플리팅 해줘. 코드 스플리팅을 더 쉽게 해주고 그런점은 개발자가 더 사용하고 싶게끔 해주고, 좀 리액트 앱을 퍼포먼틱하게? 짜임새 있게 만들어주지.
내가 깃헙 api 사용해서 어떻게 너의 앱에서 이게 구현되는지 보여주기 위해 lazy 활용해 코드스플리팅 demo 만들었거든
일어나는 일들은
1. 서치바와 그 앱의 이름들을 로드한다
2. 깃헙의 유저 네임을 찾는다.
3. 내 앱은 깃헙api로부터 데이터를 fetch하고 유저 이름을 랜더링 한다
4. 앱은 동적으로Repos
라는 컴포넌트를 import한다
5. 그 앱이 Repos
컴포넌트가 로드되기를 기다리는 동안 하나의 흐리게 처리된 "fallback" UI를 보여줘
6. The Repos
컴포넌트가 비로서 로드가 돼.
네트워크 탭을 보면 넌 액션의 코드스플리팅 을 볼수 있숴
우리가 코드 스플리팅 사용안할땐, 이미 로드된 2가지 chunks가 있숴
반면, 우리가 코드 스플리팅 사용하면, 초기는 2가지 chunks를 처음에 로드해. 그리고 세번째로 Github username을 검색해.
(그니까 유저 네임 검색한 데이터가 가장 마지막에 온다는 뜻임)
리액트 특징에 관한 큰 부분은 구현하는것이 얼마나 쉬운가 이거든.
트위터에서 @ggrgur이 제공한 구현된 쉬운 예를 한번 보자!
리액트에서 코드스플리팅 구현 위한 3가지 중요한 부분이 있숴.
Suspense
와 lazy
를 React에서 갖고와
import React, { Suspense, lazy } from 'React';
니가 로딩을 다르게 하고 싶은 파일을 동적 importing 처리해
const Deferred = lazy(() => import("./Deferred"))
Suspense
로 그 컴포넌트를 덮고, fallback UI를 셋팅해
<Suspense fallback={<div>FallbackComponent</div>}>
<Deferred {...props} />
</Suspense>
그럼 끝나쒀!
내 Demo(위에 깃헙 불러오는 앱)로부터 핵심을 공유할게
// Import Suspense and lazy from React
import React, { Component, Suspense, lazy } from 'react'
import axios from 'axios'
import styled from 'styled-components'
import { Container, Row, Col } from 'react-grid-system'
import { SearchBar } from './components/SearchBar'
import { SearchInput } from './components/SearchInput'
// Dynamically import the file
// you don't want to load until later
const Repos = lazy(() => import('./Repos'))
class App extends Component {
// Some lifecycle and class methods here
render () {
const { value } = this.state
return (
<Container>
<div className='App'>
// Search Bar Code
{this.state.loading
? <Row>
// Fetching data message
</Row>
: <Row>
<Col sm={12} md={2}>
{this.state.profile
? <h1>{this.state.profile.login}</h1>
: null}
</Col>
<Col sm={12} md={10}>
// Here is where we actually use React.lazy
// We check to make sure the data came back from the API
// Then we wrap the component that's being dynamically
// imported in `<Suspense />` and provide a fallback
// component
{this.state.repos.length > 0
? <Suspense fallback={<Blurred />}>
<Repos repos={this.state.repos} />
</Suspense>
: null}
</Col>
</Row>}
</div>
</Container>
)
}
}
export default App
(그니까 위 소스 설명하자면, gif 그림보면 유저네임 서치하면 일단은 녹색 blur된 사각형 박스가 뜨는게, 저기 )
<Suspense fallback={<Blurred
부분이다. Suspense 컴포넌트는 자식이 완료 되기 전에 Loading같이 먼저 뜨는 컴포넌트를 fallback 프롭스 안에서 받아서 처리해준다!!
자식의 <Repos>
컴포넌트가 lazy 땜에 가장 뒤에 랜더링이 될거고, 그 전엔 <Blurred>
가 뜨게된다.
보통은 코드스플리팅 없어도 그렇게 퍼포먼스 느리지 않을거라 예상? 하지만.. 만약 페이지가 엄청 무겁고 많다, 띄울게 많다 싶으면 필요한 부분은 뭐 클릭해서 띄우는거나, 어디서 갖고 오는거나.. 그런거는 React.lazy를 사용해서 일단은 import 하지 말고,
클릭이벤트나 뭔 이벤트가 들어오면 그때 import 시키면 퍼포먼스가 한결 나아질것이다!! 그래서 사용한다아아아아