본문 바로가기

FrontEnd

[Epic React][Build an Epic React App][Render as you fetch][렌더링 하면서 필요한 데이터 가져오기]

반응형

bookshelf/INSTRUCTIONS.md at exercises/10-render-as-you-fetch · kentcdodds/bookshelf (github.com)

 

GitHub - kentcdodds/bookshelf: Build a ReactJS App workshop

Build a ReactJS App workshop. Contribute to kentcdodds/bookshelf development by creating an account on GitHub.

github.com

렌더링 하면서 필요한 데이터 가져오기


배경


우리 애플리케이션의 성능에 부정적인 영향을 미치는 것은 "폭포 효과"라고 ​​불리는 것입니다. (동시에 다운 못받고 순차적으로 다운로드)
앱이 초기 페이지를 렌더링하기 전에 로드해야 하는 몇 가지 리소스가 있습니다.
이러한 자산을 더 일찍 요청할 수 있을수록 사용자에게 더 빨리 데이터를 표시할 수 있습니다.
Lazy Loading은 사용자가 실제로 필요할 때까지 필요하지 않을 항목을 로드할 필요가 없다는 것을 의미하기 때문에 훌륭합니다.
  • 로드 중인 모든 항목을 살펴보세요.
  • 꼭 필요한 리소스들을 식별합니다.
  • 가능한 한 빨리 로드를 시작하세요.

더 나은 성능을 위해선 nextjs나 gatsby를 쓰는게 좋음

(리액트 렌더링 결과로 완성된 html과 js를 분리해서 보내줌.)

 

사용자가 애플리케이션에 접속하면.

  1. index.html을 가져옴
  2. <script src="...">, ,<link rel="stylesheet" href="...">을 파싱해서 각 리소스를 가져옴
    1. JS를 만다면 자바스크립트를 파싱 및 평가함
코드 스플리팅을 하면 자바스크립트 파싱 및 평가 작업을 줄일 수 있음.
하지만 자바스크립트 실행 단계에서 더 많은 일들을 수행함.
  1. Call into all the modules (in import order)
    1. 여기에서 필요한 데이터들을 가져옴 (리액트 컴포넌트 밖으로 뺌)
  2. Create a bunch of React components
  3. Render those components with ReactDOM.render. At this point, React calls into all of our components to get the react elements
  4. Our components are "mounted" by React and our useEffect callbacks are called
  5. We make a fetch to get the logged in user's information and the AuthProvider displays a spinner while we wait.
    1. 이 부분을 최적화 함.
  6. The user's information comes back successfully, so now we render the Authenticated app (luckily we've pre-fetched that thanks to the webpack magic comment)
  7. We make a fetch to get the user's list items. We show an empty list while we wait.
  8. The list items come back and we render those list items.

 

즉 자바스크립트 실행이 실행되자마자 비동기로 데이터를 가져오게 하면 된다.

예제

bookshelf/auth-context.extra-1.js at exercises/10-render-as-you-fetch · kentcdodds/bookshelf (github.com)

 

GitHub - kentcdodds/bookshelf: Build a ReactJS App workshop

Build a ReactJS App workshop. Contribute to kentcdodds/bookshelf development by creating an account on GitHub.

github.com

아래 코드는 bootstrap API에서 처음 화면에 보여주는 모든 데이터를 다 가져온다.

해당 함수는 리액트 컴포넌트 밖에 위치하며 밖에서 호출됨을 주의한다.

그 다음 해당 데이터가 중복되는 API 별로 캐시를 초기화하고 있다.

해당 함수의 호출 결과는 promise다. 해당 promise는 비동기 훅 내부에서 resolve 해준다.

(react-query의 특징)

async function bootstrapAppData() {
  let user = null

  const token = await auth.getToken()
  if (token) {
    const data = await client('bootstrap', {token})
    queryCache.setQueryData('list-items', data.listItems, {
      staleTime: 5000,
    })
    // Let's also set the books in the query cache as well
    for (const listItem of data.listItems) {
      setQueryDataForBook(listItem.book)
    }
    user = data.user
  }
  return user
}

const appDataPromise = bootstrapAppData()


// Function Component...

bookshelf/hooks.js at 5214872999c04f68e95244057a5bd2eadac09140 · kentcdodds/bookshelf (github.com)

아래 코드는 비동기 처리 훅 내부에서, 위의 프로미스를 reslving

// 비동기 함수 호출 부분에서 프로미스를 resolve한다.
  const run = React.useCallback(
    promise => {
      if (!promise || !promise.then) {
        throw new Error(
          `The argument passed to useAsync().run must be a promise. Maybe a function that's passed isn't returning anything?`,
        )
      }
      safeSetState({status: 'pending'})
      return promise.then(
        data => {
          setData(data)
          return data
        },
        error => {
          setError(error)
          return Promise.reject(error)
        },
      )
    },
    [safeSetState, setData, setError],
  )
반응형