자바스크립트 메모이제이션과 성능 최적화: 효율적인 코드 실행의 비밀 🚀
자바스크립트 개발자라면 누구나 성능 최적화에 대해 고민해 본 적이 있을 것입니다. 특히 복잡한 연산이나 반복적인 함수 호출이 필요한 경우, 어떻게 하면 더 빠르고 효율적으로 코드를 실행할 수 있을까요? 이러한 고민의 해답 중 하나가 바로 '메모이제이션(Memoization)'입니다. 🧠💡
메모이제이션은 컴퓨터 프로그래밍에서 사용되는 최적화 기법으로, 이전에 계산한 결과를 저장해두고 동일한 입력이 들어왔을 때 저장된 결과를 반환함으로써 중복 계산을 방지합니다. 이는 특히 재귀 함수나 복잡한 알고리즘에서 큰 효과를 발휘하며, 실행 시간을 대폭 단축시킬 수 있습니다.
이 글에서는 자바스크립트에서의 메모이제이션 구현 방법과 그 장단점, 그리고 실제 적용 사례를 통해 성능 최적화의 세계로 여러분을 안내하고자 합니다. 또한, 재능넷과 같은 플랫폼에서 이러한 기술이 어떻게 활용될 수 있는지에 대해서도 살펴보겠습니다. 자, 그럼 지금부터 자바스크립트 성능 최적화의 핵심 기법인 메모이제이션에 대해 자세히 알아보겠습니다! 🕵️♂️🔍
1. 메모이제이션의 기본 개념 이해하기 📚
메모이제이션은 '기억하다'라는 뜻의 라틴어 'memorandum'에서 유래한 용어로, 컴퓨터 과학에서는 이전에 계산한 결과를 저장해두고 재사용하는 최적화 기법을 의미합니다. 이 기법은 주로 다음과 같은 상황에서 유용하게 사용됩니다:
- 동일한 입력에 대해 항상 같은 결과를 반환하는 순수 함수
- 계산 비용이 높은 함수
- 재귀적으로 호출되는 함수
- 반복적으로 호출되는 함수
메모이제이션의 핵심 아이디어는 간단합니다. 함수의 결과를 캐시(저장소)에 저장해두고, 동일한 인자로 함수가 호출될 때 이 캐시된 결과를 반환하는 것입니다. 이를 통해 중복 계산을 피하고 실행 시간을 단축할 수 있습니다.
예를 들어, 피보나치 수열을 계산하는 함수를 생각해봅시다. 일반적인 재귀 방식으로 구현하면 동일한 값에 대해 중복 계산이 많이 발생합니다. 하지만 메모이제이션을 적용하면 이미 계산한 값을 재사용할 수 있어 성능이 크게 향상됩니다.
다음은 메모이제이션을 적용하지 않은 피보나치 수열 함수입니다:
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
이 함수는 n이 커질수록 실행 시간이 기하급수적으로 증가합니다. 이제 메모이제이션을 적용한 버전을 살펴보겠습니다:
const fibonacci = (function() {
const memo = {};
function f(n) {
if (n in memo) return memo[n];
if (n <= 1) return n;
return memo[n] = f(n - 1) + f(n - 2);
}
return f;
})();
이 버전에서는 계산된 결과를 memo 객체에 저장하고, 이미 계산된 값이 있다면 그 값을 바로 반환합니다. 이를 통해 중복 계산을 피하고 실행 시간을 대폭 단축할 수 있습니다. 🚀
메모이제이션의 장점은 명확합니다:
- 성능 향상: 중복 계산을 피함으로써 실행 시간을 크게 단축할 수 있습니다.
- 리소스 절약: 계산 비용이 높은 작업의 결과를 재사용함으로써 CPU와 메모리 사용을 최적화할 수 있습니다.
- 코드 가독성 향상: 복잡한 로직을 단순화하고 성능을 개선할 수 있어, 전체적인 코드 품질이 향상됩니다.
하지만 모든 기술이 그렇듯 메모이제이션에도 주의해야 할 점이 있습니다:
- 메모리 사용량 증가: 결과를 저장하기 위해 추가적인 메모리가 필요합니다.
- 초기 실행 시간: 캐시를 구축하는 초기에는 오히려 실행 시간이 늘어날 수 있습니다.
- 부적절한 사용: 단순한 연산이나 자주 변경되는 데이터에 대해서는 오히려 성능 저하를 일으킬 수 있습니다.
따라서 메모이제이션을 적용할 때는 항상 해당 함수의 특성과 사용 패턴을 고려해야 합니다. 복잡한 계산이 필요하고, 동일한 입력이 자주 반복되는 경우에 메모이제이션이 가장 효과적입니다. 🎯
재능넷과 같은 플랫폼에서도 메모이제이션은 중요한 역할을 할 수 있습니다. 예를 들어, 사용자의 검색 결과나 추천 알고리즘의 결과를 캐싱하여 반복적인 요청에 대해 빠르게 응답할 수 있습니다. 이는 사용자 경험을 향상시키고 서버 부하를 줄이는 데 도움이 됩니다. 💼🌟
다음 섹션에서는 자바스크립트에서 메모이제이션을 구현하는 다양한 방법과 실제 사용 사례에 대해 더 자세히 알아보겠습니다. 메모이제이션의 세계로 더 깊이 들어가 봅시다! 🚀🔍
2. 자바스크립트에서 메모이제이션 구현하기 💻
자바스크립트에서 메모이제이션을 구현하는 방법은 다양합니다. 가장 기본적인 방법부터 시작해 점점 더 복잡하고 유연한 방법까지 살펴보겠습니다. 각 방법의 장단점과 적용 가능한 상황을 함께 알아보겠습니다.
2.1 클로저를 이용한 기본적인 메모이제이션 🔒
클로저를 이용한 방법은 가장 기본적이면서도 효과적인 메모이제이션 구현 방법입니다. 이 방법은 함수 내부에 캐시를 저장하는 객체를 만들고, 이를 클로저로 감싸 외부에서 접근할 수 없게 만듭니다.
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (key in cache) {
console.log('Fetching from cache');
return cache[key];
} else {
console.log('Calculating result');
const result = fn.apply(this, args);
cache[key] = result;
return result;
}
}
}
// 사용 예시
const expensiveFunction = (a, b) => {
// 복잡한 계산을 시뮬레이션하기 위한 지연
const start = Date.now();
while (Date.now() - start < 1000) {} // 1초 동안 대기
return a + b;
};
const memoizedFunction = memoize(expensiveFunction);
console.log(memoizedFunction(2, 3)); // 계산 수행 (약 1초 소요)
console.log(memoizedFunction(2, 3)); // 캐시에서 즉시 반환
이 방법의 장점은 간단하고 직관적이라는 것입니다. 또한, 클로저를 사용함으로써 캐시를 외부로부터 보호할 수 있습니다. 하지만 모든 인자의 조합에 대해 결과를 저장하기 때문에, 인자의 종류가 많거나 값이 자주 변경되는 경우에는 메모리 사용량이 급격히 증가할 수 있습니다.
2.2 Map 객체를 이용한 메모이제이션 🗺️
ES6에서 도입된 Map 객체를 사용하면 더 효율적인 메모이제이션을 구현할 수 있습니다. Map은 객체와 달리 키로 어떤 타입의 값이든 사용할 수 있어, 문자열로 변환하는 과정이 필요 없습니다.
function memoizeWithMap(fn) {
const cache = new Map();
return function(...args) {
const key = args.toString(); // 또는 더 복잡한 키 생성 로직
if (cache.has(key)) {
console.log('Fetching from cache');
return cache.get(key);
} else {
console.log('Calculating result');
const result = fn.apply(this, args);
cache.set(key, result);
return result;
}
}
}
// 사용 예시
const complexCalculation = (a, b, c) => {
// 복잡한 계산 시뮬레이션
const start = Date.now();
while (Date.now() - start < 1500) {} // 1.5초 동안 대기
return a * b + c;
};
const memoizedComplexCalc = memoizeWithMap(complexCalculation);
console.log(memoizedComplexCalc(2, 3, 4)); // 계산 수행 (약 1.5초 소요)
console.log(memoizedComplexCalc(2, 3, 4)); // 캐시에서 즉시 반환
Map을 사용하면 객체를 키로 사용할 수 있어 더 복잡한 인자 조합에 대해서도 효율적으로 캐싱할 수 있습니다. 또한, Map은 키의 삽입 순서를 기억하므로 필요한 경우 가장 오래된 캐시를 제거하는 등의 관리가 용이합니다.
2.3 데코레이터를 이용한 메모이제이션 🎀
데코레이터 패턴을 사용하면 기존 함수의 동작을 수정하지 않고도 메모이제이션을 적용할 수 있습니다. 이 방법은 특히 클래스 메서드에 메모이제이션을 적용할 때 유용합니다.
function memoize(target, name, descriptor) {
const originalMethod = descriptor.value;
const cache = new Map();
descriptor.value = function(...args) {
const key = args.toString();
if (cache.has(key)) {
console.log('Fetching from cache');
return cache.get(key);
} else {
console.log('Calculating result');
const result = originalMethod.apply(this, args);
cache.set(key, result);
return result;
}
};
return descriptor;
}
class MathOperations {
@memoize
static fibonacci(n) {
if (n <= 1) return n;
return MathOperations.fibonacci(n - 1) + MathOperations.fibonacci(n - 2);
}
}
console.log(MathOperations.fibonacci(40)); // 첫 번째 호출: 계산 수행
console.log(MathOperations.fibonacci(40)); // 두 번째 호출: 캐시에서 즉시 반환
데코레이터를 사용하면 코드의 가독성이 향상되고, 메모이제이션 로직을 함수나 메서드와 분리할 수 있습니다. 하지만 데코레이터는 아직 ECMAScript의 정식 기능이 아니므로, 사용을 위해서는 Babel과 같은 트랜스파일러가 필요할 수 있습니다.
2.4 LRU (Least Recently Used) 캐시를 이용한 메모이제이션 🔄
메모리 사용을 제한하면서도 효율적인 캐싱을 위해 LRU 캐시를 사용할 수 있습니다. LRU 캐시는 가장 오래 사용되지 않은 항목을 제거하여 캐시 크기를 일정하게 유지합니다.
class LRUCache {
constructor(capacity) {
this.capacity = capacity;
this.cache = new Map();
}
get(key) {
if (!this.cache.has(key)) return undefined;
const value = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, value);
return value;
}
put(key, value) {
if (this.cache.has(key)) {
this.cache.delete(key);
} else if (this.cache.size >= this.capacity) {
this.cache.delete(this.cache.keys().next().value);
}
this.cache.set(key, value);
}
}
function memoizeWithLRU(fn, capacity = 100) {
const cache = new LRUCache(capacity);
return function(...args) {
const key = args.toString();
if (cache.get(key) !== undefined) {
console.log('Fetching from cache');
return cache.get(key);
} else {
console.log('Calculating result');
const result = fn.apply(this, args);
cache.put(key, result);
return result;
}
}
}
// 사용 예시
const heavyComputation = (a, b) => {
const start = Date.now();
while (Date.now() - start < 1000) {} // 1초 동안 대기
return a * b;
};
const memoizedHeavyComp = memoizeWithLRU(heavyComputation, 10); // 최대 10개 항목 저장
console.log(memoizedHeavyComp(5, 6)); // 계산 수행 (약 1초 소요)
console.log(memoizedHeavyComp(5, 6)); // 캐시에서 즉시 반환
LRU 캐시를 사용하면 메모리 사용량을 제한하면서도 가장 자주 사용되는 결과를 효율적으로 캐싱할 수 있습니다. 이 방법은 특히 메모리 제약이 있는 환경이나 캐시해야 할 항목이 많은 경우에 유용합니다.
이러한 다양한 메모이제이션 구현 방법들은 각각의 장단점이 있습니다. 프로젝트의 요구사항과 성능 목표에 따라 적절한 방법을 선택하는 것이 중요합니다. 예를 들어, 재능넷과 같은 플랫폼에서는 사용자 검색 결과나 추천 알고리즘의 결과를 캐싱할 때 LRU 캐시를 사용하여 메모리 사용을 최적화하면서도 빠른 응답 시간을 유지할 수 있을 것입니다. 🚀💡
다음 섹션에서는 이러한 메모이제이션 기법들을 실제 프로젝트에 적용할 때 고려해야 할 사항들과 최적의 사용 시나리오에 대해 더 자세히 알아보겠습니다. 메모이제이션의 실전 적용을 통해 여러분의 자바스크립트 코드를 한 단계 더 최적화해 봅시다! 🔧🔍
3. 메모이제이션의 실제 적용 사례와 성능 분석 📊
이론적인 이해를 바탕으로, 이제 메모이제이션을 실제 프로젝트에 적용하는 방법과 그 효과를 살펴보겠습니다. 다양한 시나리오에서 메모이제이션이 어떻게 성능을 향상시키는지, 그리고 어떤 상황에서 주의해야 하는지 알아보겠습니다.
3.1 재귀 함수 최적화: 피보나치 수열 🌀
피보나치 수열은 메모이제이션의 효과를 극명하게 보여주는 대표적인 예시입니다. 먼저 메모이제이션을 적용하지 않은 일반적인 재귀 함수와 메모이제이션을 적용한 함수의 성능을 비교해 보겠습니다.
// 일반적인 재귀 함수
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// 메모이제이션 적용
const memoFibonacci = (function() {
const memo = {};
function f(n) {
if (n in memo) return memo[n];
if (n <= 1) return n;
return memo[n] = f(n - 1) + f(n - 2);
}
return f;
})();
// 성능 테스트
function measurePerformance(fn, arg) {
const start = performance.now();
const result = fn(arg);
const end = performance.now();
console.log(`실행 시간: ${end - start} ms`);
return result;
}
console.log("일반 피보나치:");
measurePerformance(fibonacci, 40);
console.log("메모이제이션 피보나치:");
measurePerformance(memoFibonacci, 40);
이 예시를 실행해보면, 메모이제이션을 적용한 버전이 일반 재귀 버전보다 훨씬 빠르게 실행되는 것을 확인할 수 있습니다. 특히 n이 커질수록 그 차이는 더욱 극명해집니다.
3.2 API 호출 최적화: 데이터 fetching 🌐
웹 애플리케이션에서 API 호출 결과를 메모이제이션하면 불필요한 네트워크 요청을 줄이고 응답 시간을 크게 개선할 수 있습니다. 다음은 API 호출을 메모이제이션하는 간단한 예시입니다.
const memoFetch = (function() {
const cache = new Map();
return async function(url) {
if (cache.has(url)) {
console.log('캐시된 데이터 반환');
return cache.get(url);
}
console.log('API 호출');
const response = await fetch(url);
const data = await response.json();
cache.set(url, data);
return data;
}
})();
// 사용 예시
async function fetchUserData(userId) {
const url = `https://api.example.com/users/${userId}`;
return await memoFetch(url);
}
// 테스트
(async () => {
console.log(await fetchUserData(1)); // API 호출
console.log(await fetchUserData(1)); // 캐시된 데이터 반환
console.log(await fetchUserData(2)); // 새로운 API 호출
})();
이 방식을 사용하면 동일한 URL에 대한 반복적인 요청을 효과적으로 처리할 수 있습니다. 특히 자주 변경되지 않는 데이터를 다루는 경우 매우 유용합니다.
3.3 복잡한 계산 최적화: 소수 판별 🧮
소수 판별과 같은 계산 비용이 높은 작업에 메모이제이션을 적용하면 성능을 크게 향상시킬 수 있습니다.
const isPrime = (function() {
const cache = new Map();
function checkPrime(n) {
if (n < 2) return false;
for (let i = 2; i <= Math.sqrt(n ); i++) {
if (n % i === 0) return false;
}
return true;
}
return function(n) {
if (cache.has(n)) {
console.log('캐시된 결과 반환');
return cache.get(n);
}
console.log('소수 계산');
const result = checkPrime(n);
cache.set(n, result);
return result;
}
})();
// 테스트
console.log(isPrime(1000000007)); // 소수 계산
console.log(isPrime(1000000007)); // 캐시된 결과 반환
console.log(isPrime(1000000009)); // 새로운 소수 계산
이 예시에서는 큰 수에 대한 소수 판별 결과를 캐싱함으로써, 동일한 수에 대한 반복적인 계산을 피할 수 있습니다. 특히 큰 수에 대한 소수 판별은 계산 비용이 높기 때문에, 메모이제이션의 효과가 매우 큽니다.
3.4 실제 프로젝트 적용 사례: 재능넷 플랫폼 🌟
재능넷과 같은 플랫폼에서 메모이제이션을 적용할 수 있는 몇 가지 시나리오를 살펴보겠습니다:
- 사용자 프로필 데이터 캐싱: 자주 접근되는 사용자 프로필 정보를 메모이제이션하여 데이터베이스 쿼리 횟수를 줄일 수 있습니다.
- 검색 결과 캐싱: 인기 있는 검색어에 대한 결과를 일정 시간 동안 캐싱하여 반복적인 검색 요청에 대한 응답 시간을 단축할 수 있습니다.
- 추천 알고리즘 최적화: 사용자별 추천 결과를 계산하고 캐싱하여, 동일한 사용자에 대한 반복적인 추천 요청을 빠르게 처리할 수 있습니다.
예를 들어, 사용자 프로필 데이터 캐싱을 위한 간단한 구현은 다음과 같을 수 있습니다:
const userProfileCache = new Map();
async function getUserProfile(userId) {
if (userProfileCache.has(userId)) {
console.log('캐시된 프로필 반환');
return userProfileCache.get(userId);
}
console.log('데이터베이스에서 프로필 조회');
const profile = await database.fetchUserProfile(userId);
userProfileCache.set(userId, profile);
// 1시간 후 캐시 삭제 (데이터 신선도 유지)
setTimeout(() => userProfileCache.delete(userId), 3600000);
return profile;
}
// 사용 예시
(async () => {
console.log(await getUserProfile(123)); // DB 조회
console.log(await getUserProfile(123)); // 캐시된 데이터 반환
})();
3.5 성능 분석 및 주의사항 ⚠️
메모이제이션을 적용할 때는 다음 사항들을 고려해야 합니다:
- 메모리 사용량: 캐시 크기가 너무 커지면 메모리 문제가 발생할 수 있습니다. LRU 캐시나 주기적인 캐시 정리를 고려하세요.
- 데이터 일관성: 캐시된 데이터가 오래되면 실제 데이터와 불일치할 수 있습니다. 적절한 캐시 무효화 전략이 필요합니다.
- 오버헤드: 간단한 연산의 경우, 메모이제이션 자체의 오버헤드가 더 클 수 있습니다. 복잡한 연산에만 적용하세요.
- 동시성 문제: 멀티스레드 환경에서는 캐시 접근에 대한 동기화를 고려해야 합니다.
성능 분석을 위해서는 다음과 같은 도구와 방법을 사용할 수 있습니다:
- 프로파일링 도구: Chrome DevTools의 Performance 탭을 사용하여 함수 실행 시간을 측정합니다.
- 벤치마킹: 다양한 입력값에 대해 메모이제이션 적용 전후의 실행 시간을 비교합니다.
- 메모리 사용량 모니터링: Node.js의 process.memoryUsage() 또는 브라우저의 Performance Monitor를 사용하여 메모리 사용량을 추적합니다.
메모이제이션은 강력한 최적화 기법이지만, 무분별한 적용은 오히려 성능 저하를 초래할 수 있습니다. 항상 실제 성능 측정을 통해 그 효과를 검증하고, 필요한 경우에만 선별적으로 적용하는 것이 중요합니다.
이러한 실제 적용 사례와 성능 분석을 통해, 메모이제이션이 어떻게 자바스크립트 애플리케이션의 성능을 크게 향상시킬 수 있는지 알 수 있습니다. 재능넷과 같은 복잡한 웹 플랫폼에서는 이러한 최적화 기법이 사용자 경험을 크게 개선하고, 서버 부하를 줄이는 데 중요한 역할을 할 수 있습니다. 🚀💼
다음 섹션에서는 메모이제이션의 고급 기법과 패턴, 그리고 최신 자바스크립트 프레임워크에서의 활용 방법에 대해 더 자세히 알아보겠습니다. 메모이제이션의 세계는 여기서 끝나지 않습니다. 더 깊이 들어가 봅시다! 🔍🌟
4. 고급 메모이제이션 기법과 최신 프레임워크에서의 활용 🚀
지금까지 메모이제이션의 기본 개념과 실제 적용 사례를 살펴보았습니다. 이제 더 고급 기법과 최신 자바스크립트 프레임워크에서 메모이제이션을 어떻게 활용할 수 있는지 알아보겠습니다.
4.1 동적 프로그래밍과 메모이제이션 🧠
동적 프로그래밍은 복잡한 문제를 작은 하위 문제로 나누어 해결하는 알고리즘 설계 기법입니다. 메모이제이션은 동적 프로그래밍의 핵심 요소로, 중복 계산을 피하고 효율성을 높입니다.
예를 들어, 최장 증가 부분 수열(LIS) 문제를 메모이제이션을 활용한 동적 프로그래밍으로 해결해 보겠습니다:
function longestIncreasingSubsequence(arr) {
const memo = new Array(arr.length).fill(1);
let maxLength = 1;
for (let i = 1; i < arr.length; i++) {
for (let j = 0; j < i; j++) {
if (arr[i] > arr[j]) {
memo[i] = Math.max(memo[i], memo[j] + 1);
}
}
maxLength = Math.max(maxLength, memo[i]);
}
return maxLength;
}
console.log(longestIncreasingSubsequence([10, 22, 9, 33, 21, 50, 41, 60, 80])); // 출력: 6
이 예시에서 memo
배열은 각 인덱스까지의 최장 증가 부분 수열의 길이를 저장합니다. 이를 통해 중복 계산을 피하고 효율적으로 문제를 해결할 수 있습니다.
4.2 함수형 프로그래밍에서의 메모이제이션 🧩
함수형 프로그래밍에서 메모이제이션은 순수 함수의 성능을 최적화하는 데 중요한 역할을 합니다. 고차 함수를 사용하여 메모이제이션을 구현할 수 있습니다.
const memoize = (fn) => {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
};
const expensiveCalculation = (n) => {
console.log(`Calculating for ${n}`);
return n * 2;
};
const memoizedCalculation = memoize(expensiveCalculation);
console.log(memoizedCalculation(5)); // 출력: Calculating for 5, 10
console.log(memoizedCalculation(5)); // 출력: 10 (캐시된 결과)
이 접근 방식은 함수의 순수성을 유지하면서도 성능을 최적화할 수 있게 해줍니다.
4.3 React에서의 메모이제이션 ⚛️
React에서는 useMemo
, useCallback
, 그리고 React.memo
를 통해 메모이제이션을 구현할 수 있습니다.
import React, { useMemo, useCallback } from 'react';
function ExpensiveComponent({ data, onItemClick }) {
// 복잡한 계산 결과를 메모이제이션
const processedData = useMemo(() => {
return data.map(item => item * 2);
}, [data]);
// 콜백 함수를 메모이제이션
const handleClick = useCallback((item) => {
console.log('Item clicked:', item);
onItemClick(item);
}, [onItemClick]);
return (
{processedData.map((item, index) => (
- handleClick(item)}>{item}
))}
);
}
// 컴포넌트 자체를 메모이제이션
export default React.memo(ExpensiveComponent);
이러한 React의 메모이제이션 기능들은 불필요한 재렌더링을 방지하고 애플리케이션의 성능을 향상시킵니다.
4.4 Vue.js에서의 메모이제이션 🖖
Vue.js에서는 computed 속성을 통해 자동으로 메모이제이션을 구현할 수 있습니다.
export default {
data() {
return {
items: [1, 2, 3, 4, 5]
}
},
computed: {
doubledItems() {
console.log('Computing doubled items');
return this.items.map(item => item * 2);
}
},
methods: {
addItem() {
this.items.push(this.items.length + 1);
}
}
}
이 예시에서 doubledItems
는 items
가 변경될 때만 재계산됩니다. 이는 Vue.js의 반응성 시스템과 결합하여 효율적인 메모이제이션을 제공합니다.
4.5 서버 사이드 렌더링(SSR)에서의 메모이제이션 🖥️
서버 사이드 렌더링 환경에서도 메모이제이션을 활용하여 성능을 최적화할 수 있습니다. 예를 들어, Next.js에서는 getServerSideProps
의 결과를 캐싱하여 반복적인 요청에 대한 응답 시간을 단축할 수 있습니다.
import { cache } from 'react';
export async function getServerSideProps({ params }) {
const getData = cache(async (id) => {
const res = await fetch(`https://api.example.com/data/${id}`);
return res.json();
});
const data = await getData(params.id);
return { props: { data } };
}
이 방식을 사용하면 동일한 페이지에 대한 반복적인 요청 시 API 호출을 줄이고 응답 속도를 향상시킬 수 있습니다.
4.6 웹 워커에서의 메모이제이션 👷♂️
복잡한 계산을 백그라운드에서 처리하기 위해 웹 워커를 사용할 때도 메모이제이션을 적용할 수 있습니다.