1. 시작하기 전에
모듈식 Firebase JS SDK는 기존 JS SDK를 다시 작성한 것으로, 다음 주요 버전으로 출시될 예정입니다. 이를 통해 개발자는 Firebase JS SDK에서 사용하지 않는 코드를 제외하여 더 작은 번들을 만들고 성능을 개선할 수 있습니다.
모듈식 JS SDK에서 가장 눈에 띄는 차이점은 이제 모든 것을 포함하는 단일 firebase 네임스페이스가 아닌 가져올 수 있는 자유 부동 함수로 기능이 구성된다는 점입니다. 이 새로운 코드 구성 방식을 통해 트리 셰이킹이 가능하며, 현재 v8 Firebase JS SDK를 사용하는 앱을 새로운 모듈식 앱으로 업그레이드하는 방법을 알아봅니다.
원활한 업그레이드 프로세스를 제공하기 위해 호환성 패키지 세트가 제공됩니다. 이 Codelab에서는 호환성 패키지를 사용하여 앱을 조금씩 포팅하는 방법을 알아봅니다.
빌드할 항목
이 Codelab에서는 v8 JS SDK를 사용하는 기존 주식 관심목록 웹 앱을 새로운 모듈식 JS SDK로 세 단계에 걸쳐 점진적으로 이전합니다.
- 호환성 패키지를 사용하도록 앱 업그레이드
- 호환성 패키지에서 모듈식 API로 앱을 조금씩 업그레이드
- Firestore SDK의 경량 구현인 Firestore Lite를 사용하여 앱의 성능을 더욱 개선합니다.

이 Codelab에서는 Firebase SDK 업그레이드에 중점을 둡니다. 다른 개념과 코드 블록은 자세히 설명하지 않고 그냥 넘어가겠습니다. 다만, 필요할 때 복사해서 붙여넣을 수 있도록 제공은 됩니다.
필요한 사항
2. 설정
코드 가져오기
이 프로젝트에 필요한 모든 것은 Git 저장소에 있습니다. 시작하려면 코드를 가져와 선호하는 개발 환경에서 열어야 합니다.
명령줄에서 코드랩의 GitHub 저장소를 클론합니다.
git clone https://github.com/FirebaseExtended/codelab-modular-sdk.git
또는 git이 설치되어 있지 않은 경우 저장소를 ZIP 파일로 다운로드하고 다운로드한 ZIP 파일의 압축을 풀면 됩니다.
앱 가져오기
- IDE를 사용하여
codelab-modular-sdk디렉터리를 열거나 가져옵니다. npm install을 실행하여 앱을 로컬에서 빌드하고 실행하는 데 필요한 종속 항목을 설치합니다.npm run build를 실행하여 앱을 빌드합니다.npm run serve를 실행하여 웹 서버를 시작합니다.- 브라우저 탭을 열고 http://localhost:8080으로 이동합니다.

3. 기준 설정
시작하기
시작점은 이 Codelab을 위해 설계된 주식 관심목록 앱입니다. 이 Codelab의 개념을 보여주기 위해 코드를 단순화했으며 오류 처리는 거의 없습니다. 프로덕션 앱에서 이 코드를 재사용하려면 오류를 처리하고 모든 코드를 완전히 테스트해야 합니다.
앱에서 모든 것이 작동하는지 확인합니다.
- 오른쪽 상단의 로그인 버튼을 사용하여 익명으로 로그인합니다.
- 로그인한 후 추가 버튼을 클릭하고, 글자를 입력하고, 아래에 표시되는 검색 결과 행을 클릭하여 'NFLX', 'SBUX', 'T'를 관심 목록에 검색하여 추가합니다.
- 행 끝에 있는 x를 클릭하여 관심 목록에서 주식을 삭제합니다.
- 주가 실시간 업데이트를 확인합니다.
- Chrome DevTools를 열고 네트워크 탭으로 이동하여 캐시 사용 중지 및 큰 요청 행 사용을 선택합니다. 캐시 사용 중지를 사용하면 새로고침 후 항상 최신 변경사항을 가져오고 큰 요청 행 사용을 사용하면 행에 리소스의 전송된 크기와 리소스 크기가 모두 표시됩니다. 이 Codelab에서는 주로
main.js의 크기에 관심이 있습니다.

- 시뮬레이션된 제한을 사용하여 다양한 네트워크 조건에서 앱을 로드합니다. 이 Codelab에서는 느린 3G를 사용하여 로드 시간을 측정합니다. 번들 크기가 작을수록 도움이 되기 때문입니다.

이제 앱을 새로운 모듈식 API로 마이그레이션하세요.
4. 호환성 패키지 사용
호환성 패키지를 사용하면 모든 Firebase 코드를 한 번에 변경하지 않고도 새 SDK 버전으로 업그레이드할 수 있습니다. 모듈식 API로 점진적으로 업그레이드할 수 있습니다.
이 단계에서는 Firebase 라이브러리를 v8에서 새 버전으로 업그레이드하고 호환성 패키지를 사용하도록 코드를 변경합니다. 다음 단계에서는 먼저 모듈식 API를 사용하도록 Firebase 인증 코드만 업그레이드한 다음 Firestore 코드를 업그레이드하는 방법을 알아봅니다.
각 단계가 끝나면 중단 없이 앱을 컴파일하고 실행할 수 있어야 하며, 각 제품을 이전할 때 번들 크기가 감소하는 것을 확인할 수 있습니다.
새 SDK 가져오기
package.json에서 종속 항목 섹션을 찾아 다음으로 바꿉니다.
package.json
"dependencies": {
"firebase": "^9.0.0"
}
종속 항목 다시 설치
종속 항목의 버전을 변경했으므로 npm install를 다시 실행하여 종속 항목의 새 버전을 가져와야 합니다.
가져오기 경로 변경하기
호환성 패키지는 하위 모듈 firebase/compat 아래에 노출되므로 가져오기 경로를 다음과 같이 업데이트합니다.
src/firebase.ts파일로 이동- 기존 가져오기를 다음 가져오기로 바꿉니다.
src/firebase.ts
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
앱 작동 확인
npm run build를 실행하여 앱을 다시 빌드합니다.- 브라우저 탭을 열고 http://localhost:8080으로 이동하거나 기존 탭을 새로고침합니다.
- 앱을 사용해 보세요. 모든 것이 계속 작동해야 합니다.
5. 모듈식 API를 사용하도록 인증 업그레이드
Firebase 제품은 어떤 순서로든 업그레이드할 수 있습니다. 이 Codelab에서는 인증 API가 비교적 간단하므로 먼저 인증을 업그레이드하여 기본 개념을 알아봅니다. Firestore 업그레이드는 좀 더 복잡하며, 다음에서 방법을 알아봅니다.
인증 초기화 업데이트
src/firebase.ts파일로 이동- 다음 가져오기를 추가합니다.
src/firebase.ts
import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
import ‘firebase/compat/auth'.삭제export const firebaseAuth = app.auth();를 다음으로 바꿉니다.
src/firebase.ts
export const firebaseAuth = initializeAuth(app, { persistence: [indexedDBLocalPersistence] });
- 파일 끝에 있는
export type User = firebase.User;를 삭제합니다.User은(는) 다음에 변경할src/auth.ts에 직접 내보내집니다.
인증 코드 업데이트
src/auth.ts파일로 이동- 파일 상단에 다음 가져오기를 추가합니다.
src/auth.ts
import {
signInAnonymously,
signOut,
onAuthStateChanged,
User
} from 'firebase/auth';
‘firebase/auth'.에서User를 이미 가져왔으므로import { firebaseAuth, User } from './firebase';에서User삭제- 모듈식 API를 사용하도록 함수 업데이트
앞서 가져오기 문을 업데이트할 때 이미 보셨듯이 버전 9의 패키지는 가져올 수 있는 함수를 중심으로 구성됩니다. 이는 점으로 체인된 네임스페이스 및 서비스 패턴을 기반으로 하는 버전 8 API와 대조됩니다. 빌드 도구가 사용되는 코드와 사용되지 않는 코드를 분석할 수 있으므로 사용되지 않는 코드를 트리 셰이킹할 수 있는 것은 바로 이 새로운 코드 구성입니다.
버전 9에서는 서비스가 함수의 첫 번째 인수로 전달됩니다. 서비스는 Firebase 서비스를 초기화하여 가져오는 객체입니다(예: getAuth() 또는 initializeAuth()에서 반환된 객체). 특정 Firebase 서비스의 상태를 보유하며 함수는 이 상태를 사용하여 작업을 실행합니다. 이 패턴을 적용하여 다음 함수를 구현해 보겠습니다.
src/auth.ts
export function firebaseSignInAnonymously() {
return signInAnonymously(firebaseAuth);
}
export function firebaseSignOut() {
return signOut(firebaseAuth);
}
export function onUserChange(callback: (user: User | null) => void) {
return onAuthStateChanged(firebaseAuth, callback);
}
export { User } from 'firebase/auth';
앱 작동 확인
npm run build를 실행하여 앱을 다시 빌드합니다.- 브라우저 탭을 열고 http://localhost:8080으로 이동하거나 기존 탭을 새로고침합니다.
- 앱을 사용해 보세요. 모든 것이 계속 작동해야 합니다.
번들 크기 확인
- Chrome DevTools를 엽니다.
- 네트워크 탭으로 전환합니다.
- 페이지를 새로고침하여 네트워크 요청을 캡처합니다.
- main.js를 찾아 크기를 확인합니다. 코드 몇 줄만 변경하여 번들 크기를 100KB (gzip으로 압축 시 36KB) 줄였습니다. 이는 약 22% 더 작은 크기입니다. 또한 느린 3G 연결에서 사이트가 0.75초 더 빠르게 로드됩니다.

6. 모듈식 API를 사용하도록 Firebase 앱 및 Firestore 업그레이드
Firebase 초기화 업데이트
src/firebase.ts.파일로 이동import firebase from ‘firebase/compat/app';를 다음으로 바꿉니다.
src/firebase.ts
import { initializeApp } from 'firebase/app';
const app = firebase.initializeApp({...});를 다음으로 바꿉니다.
src/firebase.ts
const app = initializeApp({
apiKey: "AIzaSyBnRKitQGBX0u8k4COtDTILYxCJuMf7xzE",
authDomain: "exchange-rates-adcf6.firebaseapp.com",
databaseURL: "https://exchange-rates-adcf6.firebaseio.com",
projectId: "exchange-rates-adcf6",
storageBucket: "exchange-rates-adcf6.firebasestorage.app",
messagingSenderId: "875614679042",
appId: "1:875614679042:web:5813c3e70a33e91ba0371b"
});
Firestore 초기화 업데이트
- 같은 파일
src/firebase.ts,에서import 'firebase/compat/firestore';을 다음으로 바꿉니다.
src/firebase.ts
import { getFirestore } from 'firebase/firestore';
export const firestore = app.firestore();를 다음으로 바꿉니다.
src/firebase.ts
export const firestore = getFirestore();
- '
export const firestore = ...' 뒤의 모든 줄 삭제
가져오기 업데이트
src/services.ts.파일 열기- import에서
FirestoreFieldPath,FirestoreFieldValue,QuerySnapshot를 삭제합니다. 이제'./firebase'의 가져오기가 다음과 같이 표시됩니다.
src/services.ts
import { firestore } from './firebase';
- 파일 상단에서 사용할 함수와 유형을 가져옵니다.
**src/services.ts**
import {
collection,
getDocs,
doc,
setDoc,
arrayUnion,
arrayRemove,
onSnapshot,
query,
where,
documentId,
QuerySnapshot
} from 'firebase/firestore';
search() 업데이트
- 모든 티커가 포함된 컬렉션에 대한 참조를 만듭니다.
src/services.ts
const tickersCollRef = collection(firestore, 'current');
getDocs()를 사용하여 컬렉션의 모든 문서를 가져옵니다.
src/services.ts
const tickers = await getDocs(tickersCollRef);
완성된 코드는 search()을 참고하세요.
addToWatchList() 업데이트
doc()를 사용하여 사용자의 관심 목록에 대한 문서 참조를 만든 다음 setDoc()와 arrayUnion()를 사용하여 티커를 추가합니다.
src/services.ts
export function addToWatchList(ticker: string, user: User) {
const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
return setDoc(watchlistRef, {
tickers: arrayUnion(ticker)
}, { merge: true });
}
deleteFromWatchList() 업데이트
마찬가지로 arrayRemove()와 함께 setDoc()를 사용하여 사용자의 관심 목록에서 티커를 삭제합니다.
src/services.ts
export function deleteFromWatchList(ticker: string, user: User) {
const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
return setDoc(watchlistRef, {
tickers: arrayRemove(ticker)
}, { merge: true });
}
subscribeToTickerChanges() 업데이트
doc()를 사용하여 먼저 사용자의 관심 목록에 대한 문서 참조를 만든 다음onSnapshot()를 사용하여 관심 목록 변경사항을 수신 대기합니다.
src/services.ts
const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const unsubscribe = onSnapshot(watchlistRef, snapshot => {
/* subscribe to ticker price changes */
});
- 관심 목록에 티커가 있으면
query()를 사용하여 가격을 가져오는 쿼리를 만들고onSnapshot()를 사용하여 가격 변동을 수신 대기합니다.
src/services.ts
const priceQuery = query(
collection(firestore, 'current'),
where(documentId(), 'in', tickers)
);
unsubscribePrevTickerChanges = onSnapshot(priceQuery, snapshot => {
if (firstload) {
performance && performance.measure("initial-data-load");
firstload = false;
logPerformance();
}
const stocks = formatSDKStocks(snapshot);
callback(stocks);
});
전체 구현은 subscribeToTickerChanges()를 참고하세요.
subscribeToAllTickerChanges() 업데이트
먼저 collection()를 사용하여 모든 티커의 가격을 포함하는 컬렉션에 대한 참조를 만든 다음 onSnapshot()를 사용하여 가격 변경을 수신합니다.
src/services.ts
export function subscribeToAllTickerChanges(callback: TickerChangesCallBack) {
const tickersCollRef = collection(firestore, 'current');
return onSnapshot(tickersCollRef, snapshot => {
if (firstload) {
performance && performance.measure("initial-data-load");
firstload = false;
logPerformance();
}
const stocks = formatSDKStocks(snapshot);
callback(stocks);
});
}
앱 작동 확인
npm run build를 실행하여 앱을 다시 빌드합니다.- 브라우저 탭을 열고 http://localhost:8080으로 이동하거나 기존 탭을 새로고침합니다.
- 앱을 사용해 보세요. 모든 것이 계속 작동해야 합니다.
번들 크기 확인
- Chrome DevTools를 엽니다.
- 네트워크 탭으로 전환합니다.
- 페이지를 새로고침하여 네트워크 요청을 캡처합니다.
main.js를 찾아 크기를 확인합니다. 다시 원래 번들 크기와 비교해 보세요. 번들 크기가 200KB 이상 (gzip으로 압축 시 63.8KB) 줄어들었으며, 이는 50% 더 작아진 것으로 로드 시간이 1.3초 더 빨라집니다.

7. Firestore Lite를 사용하여 초기 페이지 렌더링 속도 향상
Firestore Lite란 무엇인가요?
Firestore SDK는 복잡한 캐싱, 실시간 스트리밍, 영구 스토리지, 멀티 탭 오프라인 동기화, 재시도, 낙관적 동시 실행 등 다양한 기능을 제공하므로 크기가 상당히 큽니다. 하지만 고급 기능이 필요 없이 데이터를 한 번만 가져오고 싶을 수도 있습니다. 이러한 경우를 위해 Firestore는 간단하고 가벼운 솔루션인 새로운 패키지 Firestore Lite를 만들었습니다.
Firestore Lite의 유용한 사용 사례 중 하나는 초기 페이지 렌더링의 성능을 최적화하는 것입니다. 이 경우 사용자가 로그인했는지 여부만 알면 되고 Firestore에서 일부 데이터를 읽어 표시하면 됩니다.
이 단계에서는 Firestore Lite를 사용하여 번들 크기를 줄여 초기 페이지 렌더링 속도를 높인 다음 기본 Firestore SDK를 동적으로 로드하여 실시간 업데이트를 구독하는 방법을 알아봅니다.
코드를 리팩터링하여 다음을 수행합니다.
- 실시간 서비스를 별도의 파일로 이동하여 동적 가져오기를 사용하여 동적으로 로드할 수 있습니다.
- Firestore Lite를 사용하여 관심 목록과 주가를 가져오는 새 함수를 만듭니다.
- 새 Firestore Lite 함수를 사용하여 데이터를 가져와 초기 페이지를 렌더링한 다음 실시간 서비스를 동적으로 로드하여 실시간 업데이트를 수신합니다.
실시간 서비스를 새 파일로 이동하기
src/services.realtime.ts.라는 새 파일을 만듭니다.subscribeToTickerChanges()및subscribeToAllTickerChanges()함수를src/services.ts에서 새 파일로 이동합니다.- 새 파일 상단에 필요한 가져오기를 추가합니다.
여기에서 몇 가지 변경사항을 적용해야 합니다.
- 먼저 함수에서 사용할 파일 상단의 기본 Firestore SDK에서 Firestore 인스턴스를 만듭니다. 여기서는
firebase.ts에서 Firestore 인스턴스를 가져올 수 없습니다. 몇 단계 후에 이를 Firestore Lite 인스턴스로 변경할 예정이기 때문입니다. 이 인스턴스는 초기 페이지 렌더링에만 사용됩니다. - 두 번째로
firstload변수와 이 변수로 보호되는 if 블록을 삭제합니다. 이러한 기능은 다음 단계에서 만들 새 함수로 이동됩니다.
src/services.realtime.ts
import { User } from './auth'
import { TickerChange } from './models';
import { collection, doc, onSnapshot, query, where, documentId, getFirestore } from 'firebase/firestore';
import { formatSDKStocks } from './services';
const firestore = getFirestore();
type TickerChangesCallBack = (changes: TickerChange[]) => void
export function subscribeToTickerChanges(user: User, callback: TickerChangesCallBack) {
let unsubscribePrevTickerChanges: () => void;
// Subscribe to watchlist changes. We will get an update whenever a ticker is added/deleted to the watchlist
const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const unsubscribe = onSnapshot(watchlistRef, snapshot => {
const doc = snapshot.data();
const tickers = doc ? doc.tickers : [];
if (unsubscribePrevTickerChanges) {
unsubscribePrevTickerChanges();
}
if (tickers.length === 0) {
callback([]);
} else {
// Query to get current price for tickers in the watchlist
const priceQuery = query(
collection(firestore, 'current'),
where(documentId(), 'in', tickers)
);
// Subscribe to price changes for tickers in the watchlist
unsubscribePrevTickerChanges = onSnapshot(priceQuery, snapshot => {
const stocks = formatSDKStocks(snapshot);
callback(stocks);
});
}
});
return () => {
if (unsubscribePrevTickerChanges) {
unsubscribePrevTickerChanges();
}
unsubscribe();
};
}
export function subscribeToAllTickerChanges(callback: TickerChangesCallBack) {
const tickersCollRef = collection(firestore, 'current');
return onSnapshot(tickersCollRef, snapshot => {
const stocks = formatSDKStocks(snapshot);
callback(stocks);
});
}
Firestore lite를 사용하여 데이터 가져오기
src/services.ts.열기- 가져오기 경로를
‘firebase/firestore'에서‘firebase/firestore/lite',로 변경하고getDoc를 추가하고 가져오기 목록에서onSnapshot를 삭제합니다.:
src/services.ts
import {
collection,
getDocs,
doc,
setDoc,
arrayUnion,
arrayRemove,
// onSnapshot, // firestore lite doesn't support realtime updates
query,
where,
documentId,
QuerySnapshot,
getDoc // add this import
} from 'firebase/firestore/lite';
- Firestore Lite를 사용하여 초기 페이지 렌더링에 필요한 데이터를 가져오는 함수를 추가합니다.
src/services.ts
export async function getTickerChanges(tickers: string[]): Promise<TickerChange[]> {
if (tickers.length === 0) {
return [];
}
const priceQuery = query(
collection(firestore, 'current'),
where(documentId(), 'in', tickers)
);
const snapshot = await getDocs(priceQuery);
performance && performance.measure("initial-data-load");
logPerformance();
return formatSDKStocks(snapshot);
}
export async function getTickers(user: User): Promise<string[]> {
const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const data = (await getDoc(watchlistRef)).data();
return data ? data.tickers : [];
}
export async function getAllTickerChanges(): Promise<TickerChange[]> {
const tickersCollRef = collection(firestore, 'current');
const snapshot = await getDocs(tickersCollRef);
performance && performance.measure("initial-data-load");
logPerformance();
return formatSDKStocks(snapshot);
}
src/firebase.ts를 열고 가져오기 경로를‘firebase/firestore'에서‘firebase/firestore/lite':로 변경합니다.
src/firebase.ts
import { getFirestore } from 'firebase/firestore/lite';
모두 연결하기
src/main.ts.열기- 새로 만든 함수는 초기 페이지 렌더링을 위해 데이터를 가져와야 하며 앱 상태를 관리하기 위한 몇 가지 도우미 함수도 필요합니다. 이제 가져오기를 업데이트합니다.
src/main.ts
import { renderLoginPage, renderUserPage } from './renderer';
import { getAllTickerChanges, getTickerChanges, getTickers } from './services';
import { onUserChange } from './auth';
import { getState, setRealtimeServicesLoaded, setUser } from './state';
import './styles.scss';
- 파일 상단에서 동적 가져오기를 사용하여
src/services.realtime를 로드합니다. 변수loadRealtimeService는 코드가 로드되면 실시간 서비스로 확인되는 약속입니다. 나중에 이를 사용하여 실시간 업데이트를 구독합니다.
src/main.ts
const loadRealtimeService = import('./services.realtime');
loadRealtimeService.then(() => {
setRealtimeServicesLoaded(true);
});
- 함수 본문에서
await을 사용할 수 있도록onUserChange()의 콜백을async함수로 변경합니다.
src/main.ts
onUserChange(async user => {
// callback body
});
- 이제 이전 단계에서 만든 새 함수를 사용하여 초기 페이지 렌더링을 위해 데이터를 가져옵니다.
onUserChange() 콜백에서 사용자가 로그인한 if 조건을 찾아 if 문 내부에 코드를 복사하여 붙여넣습니다.
src/main.ts
onUserChange(async user => {
// LEAVE THE EXISTING CODE UNCHANGED HERE
...
if (user) {
// REPLACE THESE LINES
// user page
setUser(user);
// show loading screen in 500ms
const timeoutId = setTimeout(() => {
renderUserPage(user, {
loading: true,
tableData: []
});
}, 500);
// get data once if realtime services haven't been loaded
if (!getState().realtimeServicesLoaded) {
const tickers = await getTickers(user);
const tickerData = await getTickerChanges(tickers);
clearTimeout(timeoutId);
renderUserPage(user, { tableData: tickerData });
}
// subscribe to realtime updates once realtime services are loaded
loadRealtimeService.then(({ subscribeToTickerChanges }) => {
unsubscribeTickerChanges = subscribeToTickerChanges(user, stockData => {
clearTimeout(timeoutId);
renderUserPage(user, { tableData: stockData })
});
});
} else {
// DON'T EDIT THIS PART, YET
}
}
- 사용자가 로그인하지 않은 else 블록에서 Firestore Lite를 사용하여 모든 주식의 가격 정보를 가져오고 페이지를 렌더링한 다음 실시간 서비스가 로드되면 가격 변경사항을 수신 대기합니다.
src/main.ts
if (user) {
// DON'T EDIT THIS PART, WHICH WE JUST CHANGED ABOVE
...
} else {
// REPLACE THESE LINES
// login page
setUser(null);
// show loading screen in 500ms
const timeoutId = setTimeout(() => {
renderLoginPage('Landing page', {
loading: true,
tableData: []
});
}, 500);
// get data once if realtime services haven't been loaded
if (!getState().realtimeServicesLoaded) {
const tickerData = await getAllTickerChanges();
clearTimeout(timeoutId);
renderLoginPage('Landing page', { tableData: tickerData });
}
// subscribe to realtime updates once realtime services are loaded
loadRealtimeService.then(({ subscribeToAllTickerChanges }) => {
unsubscribeAllTickerChanges = subscribeToAllTickerChanges(stockData => {
clearTimeout(timeoutId);
renderLoginPage('Landing page', { tableData: stockData })
});
});
}
완성된 코드는 src/main.ts를 참고하세요.
앱 작동 확인
npm run build를 실행하여 앱을 다시 빌드합니다.- 브라우저 탭을 열고 http://localhost:8080으로 이동하거나 기존 탭을 새로고침합니다.
번들 크기 확인
- Chrome Devtools를 엽니다.
- 네트워크 탭으로 전환합니다.
- 페이지를 새로고침하여 네트워크 요청 캡처
main.js를 찾아 크기를 확인합니다.- 이제 115KB (gzip으로 압축 시 34.5KB)에 불과합니다. 이는 원래 번들 크기인 446KB(gzip으로 압축 시 138KB)보다 75% 더 작은 크기입니다. 그 결과 3G 연결에서 사이트가 2초 이상 빠르게 로드되어 성능과 사용자 환경이 크게 개선되었습니다.

8. 축하합니다
축하합니다. 앱을 업그레이드하여 더 작고 빠르게 만들었습니다.
호환성 패키지를 사용하여 앱을 조금씩 업그레이드하고 Firestore Lite를 사용하여 초기 페이지 렌더링을 가속화한 다음 기본 Firestore를 동적으로 로드하여 가격 변경사항을 스트리밍했습니다.
이 Codelab을 진행하면서 번들 크기를 줄이고 로드 시간을 개선했습니다.
main.js | 리소스 크기 (kb) | gzip 압축 크기 (kb) | 로드 시간 (초) (느린 3G 이상) |
v8 | 446 | 138 | 4.92 |
v9 호환성 | 429 | 124 | 4.65 |
v9 전용 모듈식 인증 | 348 | 102 | 4.2 |
v9 완전 모듈식 | 244 | 74.6 | 3.66 |
v9 완전 모듈식 + Firestore Lite | 117 | 34.9 | 2.88 |

이제 v8 Firebase JS SDK를 사용하는 웹 앱을 새로운 모듈식 JS SDK를 사용하도록 업그레이드하는 데 필요한 주요 단계를 알게 되었습니다.