使用方法
- 复制安装命令,在自己的智能体环境安装前先检查源码包。
- 从原始文档核对所需工具、凭据和支持的宿主。
- 说明输入材料与期望交付物,并对照来源检查输出。
npx skills add https://github.com/mattpocock/course-video-manager --skill optimize-loader开始前需了解
- 安装不包含模型订阅、API 额度或访问文件的权限。
- 仓库星数和安装量反映活跃情况,不等于独立质量或安全测试。
按源仓库内容呈现,保留标题、案例、代码、表格、链接以及原文引用的演示图片。
Optimize Loader
Anti-patterns to catch
1. Re-fetching data the caller already has
If a loader fetches a record (e.g. getVideoWithClipsById) and then passes just the ID to a downstream function that re-fetches the same record internally — change the downstream function's signature to accept the already-fetched object.
// BAD — getNextVideoId internally calls getVideoWithClipsById again
const video = yield * db.getVideoWithClipsById(videoId);
const nextId = yield * db.getNextVideoId(videoId);
// GOOD — pass the already-fetched video
const video = yield * db.getVideoWithClipsById(videoId);
const nextId = yield * db.getNextVideoId(video);When refactoring signatures, type the parameter as the minimal shape needed, not the full return type:
// Accept only what the function actually reads
function* (currentVideo: {
id: string;
lesson: {
id: string;
videos: Array<{ id: string; path: string }>;
section: { repoVersion: { repo: { id: string } } };
} | null;
})2. Over-fetching nested relations
If a function only needs IDs and paths for navigation but loads full nested trees including clips, transcripts, etc. — create a slim query variant.
// BAD — loads clips, chapters, thumbnails etc. just to get video IDs
const course = yield * getCourseWithSectionsById(repoId);
// GOOD — dedicated lightweight query
const course = yield * getCourseNavigationData(repoId);Slim query checklist:
columns: { id: true, path: true }— only select needed columns on leaf relationslimit: 1on relations like versions where you only need the latest- Omit
with:for relations you don't traverse (clips, chapters, thumbnails) - Keep
where:filters (e.g.archived = false) andorderByintact
3. Sequential independent queries
If a loader runs multiple independent DB calls sequentially, parallelize with Effect.all:
// BAD — sequential, total time = sum of both
const nextVideoId = yield * db.getNextVideoId(video);
const previousVideoId = yield * db.getPreviousVideoId(video);
// GOOD — parallel, total time = max of both
const [nextVideoId, previousVideoId] =
yield * Effect.all([db.getNextVideoId(video), db.getPreviousVideoId(video)]);Dependency injection pattern
When adding a new query (like getCourseNavigationData) that lives in course operations but is used by video operations:
- Add the query to
db-course-operations.server.tsand export it - Declare the cross-domain dependency in
VideoOperationsService'seffectblock viayield* CourseOperationsService - The Effect Layer system resolves cross-domain dependencies automatically



