request waterfalls? 뭐징? (Next.js 공식문서 정리)

park.js·2024년 8월 29일
0

FrontEnd Develop log

목록 보기
23/37
post-thumbnail


공식문서 보기

사진 설명

  • Sequential (순차적):
    • 이 부분은 요청이 순차적으로 처리되는 방식이다. 첫 번째 함수(fetchRevenue)가 완료된 후에야 두 번째 함수(fetchLatestInvoices)가 실행되며, 두 번째 함수가 완료된 후에야 세 번째 함수(fetchCardData)가 실행된다.
    • 이렇게 순차적으로 실행되면, 전체 작업이 완료되기까지 시간이 더 오래 걸린다. 각 함수가 완료될 때까지 다음 함수가 시작되지 않기 때문이다.
  • Parallel (병렬적):
    • 이 부분은 모든 함수가 동시에 실행되는 방식을 보여준다. fetchRevenue, fetchLatestInvoices, fetchCardData가 동시에 실행되므로, 모든 작업이 병렬로 처리된다.
    • 병렬로 실행되면, 전체 작업이 더 빨리 완료된다. 각 함수가 독립적으로 실행되기 때문에, 다른 함수의 완료를 기다릴 필요가 없다.

결론

  • Sequential 방식은 각 작업이 이전 작업에 의존해야 할 때 유용하지만, 시간이 더 오래 걸릴 수 있다.
  • Parallel 방식은 독립적인 작업을 동시에 처리하여 성능을 최적화할 수 있다.

따라서, 병렬로 실행 가능한 작업들은 병렬로 처리하는 것이 성능 향상에 도움이 된다. 다만, 어떤 경우에는 순차적 처리가 필요한 상황도 있을 수 있다(예: 이전 작업의 결과가 다음 작업에 필요한 경우).

공식문서에 의하면 병렬실행도 구멍이 있고 또 그 구멍을 막는 방법이 있다. 쉽고 얕게 알아보자

병렬 데이터 페칭(Parallel Data Fetching)과 성능 최적화

병렬 데이터 페칭은 웹 애플리케이션에서 성능을 최적화하는 중요한 기법이다. 데이터를 순차적으로 요청하면 첫 번째 요청이 완료된 후에야 두 번째 요청이 시작되기 때문에, 전체 데이터 로딩 시간이 길어질 수 있다. 이를 방지하고자, 병렬로 데이터를 요청하는 방식을 사용하면 모든 요청이 동시에 시작되어 전체 로딩 시간을 단축할 수 있다.

Promise.all()을 활용한 병렬 데이터 페칭

JavaScript에서는 Promise.all()과 같은 내장 메서드를 사용해 여러 비동기 작업을 병렬로 실행할 수 있다. 예를 들어, 아래 코드에서는 세 가지 데이터베이스 쿼리를 동시에 실행하여, 각각의 쿼리 결과를 빠르게 받아올 수 있다:

export async function fetchCardData() {
  try {
    const invoiceCountPromise = sql`SELECT COUNT(*) FROM invoices`;
    const customerCountPromise = sql`SELECT COUNT(*) FROM customers`;
    const invoiceStatusPromise = sql`SELECT
         SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) AS "paid",
         SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS "pending"
         FROM invoices`;

    const data = await Promise.all([
      invoiceCountPromise,
      customerCountPromise,
      invoiceStatusPromise,
    ]);
    // ...
  }
}

이 방법을 사용하면 세 개의 쿼리가 각각의 처리 속도와 관계없이 동시에 실행되므로, 전체 데이터 로딩 시간을 줄일 수 있다.

Promise.all()의 단점과 대안

Promise.all()은 모든 프라미스가 완료될 때까지 대기한다. 즉, 하나의 요청이 지연되거나 실패하면 전체 요청 결과가 지연되거나 실패할 수 있다. 이러한 문제를 해결하기 위해 Promise.allSettled()를 사용할 수 있다. Promise.allSettled()는 모든 프라미스가 완료될 때까지 기다리되, 각각의 프라미스 결과를 별도로 처리한다. 이렇게 하면 하나의 요청이 실패하더라도 다른 요청은 정상적으로 처리되어 결과를 얻을 수 있다.

const results = await Promise.allSettled([
  invoiceCountPromise,
  customerCountPromise,
  invoiceStatusPromise,
]);

이 패턴은 다양한 상황에서 유용하다. 특히 네트워크 상태가 불안정하거나, 각 요청의 중요도가 다를 때 유용하다.

결론

병렬 데이터 페칭은 웹 애플리케이션 성능 최적화에 큰 도움을 준다. Promise.all()을 사용해 모든 데이터를 동시에 요청함으로써 성능을 극대화할 수 있으며, 필요에 따라 Promise.allSettled()를 사용해 보다 유연하게 오류를 처리할 수 있다.

profile
참 되게 살자

0개의 댓글