一键导入
firestore-query-optimization
대시보드·리스트 페이지의 Firestore 쿼리 자체 최적화 — 복합 인덱스, 페이지네이션, 캐싱으로 읽기(Reads) 횟수와 응답 속도를 개선하는 패턴 가이드. 화면이 느리거나 Reads가 많을 때 참고.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
대시보드·리스트 페이지의 Firestore 쿼리 자체 최적화 — 복합 인덱스, 페이지네이션, 캐싱으로 읽기(Reads) 횟수와 응답 속도를 개선하는 패턴 가이드. 화면이 느리거나 Reads가 많을 때 참고.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
프로젝트 구조와 네이밍 컨벤션에 맞게 새 React 컴포넌트를 추가하는 가이드
PDF(인쇄 레이아웃) 및 Excel(xlsx 동적 로딩) 파일 내보내기 구현 및 갱신 패턴 가이드
Gemini 3.1 Flash Lite API를 사용한 계기판 OCR 및 증빙 서류 AI 판별 연동 패턴 가이드
Sentry에 잡힌 환경/브라우저/외부 의존성 발 노이즈 에러를 필터링한다. 사용자가 "Sentry 노이즈", "Sentry 에러 필터", "이 에러 무시", "Sentry에 자꾸 뜨는 X 막아줘" 등을 요청할 때 발동한다.
React 단위 테스트(Vitest) 및 E2E 테스트(Playwright) 작성 컨벤션과 Mocking 가이드
Cloud Functions, 프론트엔드 빌드 및 배포 시 발생하는 다양한 오류(Node 버전, 의존성 충돌, 소스맵)의 해결 패턴을 모아둔 가이드.
| name | firestore-query-optimization |
| description | 대시보드·리스트 페이지의 Firestore 쿼리 자체 최적화 — 복합 인덱스, 페이지네이션, 캐싱으로 읽기(Reads) 횟수와 응답 속도를 개선하는 패턴 가이드. 화면이 느리거나 Reads가 많을 때 참고. |
Firebase Firestore 문서 읽기(Reads) 건수에 따라 비용과 응답 속도가 크게 좌우됩니다. 데이터가 쌓일수록 성능 이슈가 발생할 수 있으므로, 새로운 데이터를 쿼리하거나 기존 조회를 수정할 때 다음 가이드를 따르세요.
클라이언트 측에서 모든 데이터를 불러온 후 JavaScript filter()를 사용하는 것은 절대 금지됩니다. (Firebase Read 비용 폭증의 원인)
항상 Firestore 쿼리 레벨에서 데이터를 좁혀야 합니다.
❌ Bad (Before)
// 전체 데이터를 다 가져온 후 최근 1주일 데이터만 필터링 -> 모든 문서 읽음
const snap = await getDocs(collection(db, 'reservations'));
const activeReservations = snap.docs.filter(doc => doc.data().date >= oneWeekAgo);
✅ Good (After)
// 서버 측에서 1주일치만 질의하여 가져옴
const q = query(
collection(db, 'reservations'),
where('date', '>=', oneWeekAgoStr),
where('date', '<=', todayStr)
);
const snap = await getDocs(q);
전체 내역 조회가 필요한 관리자 대시보드라 할지라도 최대 조회 기간(예: 최근 6개월, 혹은 특정 회계 연도)을 강제하여야 합니다. 무한정 커버리지를 가진 쿼리는 작성하지 마십시오.
여러 개의 문서(예: 동일 날짜의 반복 예약)를 다루거나 관련 문서를 동시에 수정/삭제할 경우 Promise.all + 개별 다수 호출을 피하고, writeBatch를 사용하여 원자성과 네트워크 통신 최적화를 도모합니다.
import { writeBatch, doc } from 'firebase/firestore';
import { db } from '../firebase';
export async function deleteReservations(ids: string[]) {
const batch = writeBatch(db);
ids.forEach(id => {
const docRef = doc(db, 'reservations', id);
batch.delete(docRef);
});
// 한 번의 네트워크 요청으로 모두 처리 (비용/속도 이점)
await batch.commit();
}
조회수 등 집계 목적의 데이터는 원본 문서를 다 읽게 하지 마세요.
computeDashboardStats.ts와 같이 Cloud Function이나 배치 로직에서 주기적으로 통계를 계산하여 단일 문서(예: stats/{orgId})에 캐싱하고, 클라이언트는 통계 문서를 1회 Read만 하도록 설계해야 합니다.