การเริ่มต้นระบบและ Initialization
ภาพรวม
กระบวนการเริ่มต้นระบบได้รับการเพิ่มประสิทธิภาพสูงสำหรับ การดำเนินการแบบขนาน และ การตัดโค้ดที่ตาย ผ่าน Feature Flags
วัฎจักรการเริ่มต้นระบบ
ระยะที่ 1: ผลข้างเคียงก่อน Import (0-10ms)
// src/main.tsx (บรรทัด 9-20)
// ผลข้างเคียงเหล่านี้ต้องทำงาน BEFORE imports อื่นๆ ทั้งหมด:
// 1. Profile checkpoint บ่งชี้จุดเข้าใช้งาน
profileCheckpoint('main_tsx_entry');
// 2. เริ่ม subproceses ของ MDM แบบขนาน
startMdmRawRead();
// 3. เริ่มการอ่าน keychain แบบขนาน
startKeychainPrefetch();
การเพิ่มประสิทธิภาพหลัก: การตั้งค่า MDM, Keychain, และ API preconnect ทั้งหมดเริ่มพร้อมกันก่อนที่ imports อื่นๆ อีก ~135ms จะเสร็จสมบูรณ์
ระยะที่ 2: การโหลด Imports (~135ms)
// ระหว่าง imports, โมดูลหนักถูกโหลดแบบ lazy:
const coordinatorModeModule = feature('COORDINATOR_MODE')
? require('./coordinator/coordinatorMode.js')
: null;
const assistantModule = feature('KAIROS')
? require('./assistant/index.js')
: null;
ระยะที่ 3: Hook ก่อน Action (ก่อนคำสั่งแรก)
// src/main.tsx (บรรทัด 907-967)
program.hook('preAction', async thisCommand => {
// รอให้ MDM และ keychain prefetch เสร็จสมบูรณ์
await Promise.all([
ensureMdmSettingsLoaded(),
ensureKeychainPrefetchCompleted()
]);
// เริ่มต้นระบบหลัก
await init();
// ตั้งชื่อ process
process.title = 'claude';
// แนบ logging sinks
const { initSinks } = await import('./utils/sinks.js');
initSinks();
// รัน migrations
runMigrations();
// โหลดการตั้งค่าที่จัดการระยะไกล
void loadRemoteManagedSettings();
void loadPolicyLimits();
});
ฟังก์ชันการเริ่มต้น
การเริ่มต้นหลัก (init())
// src/entrypoints/init.ts
export async function init(): Promise<void> {
// 1. โหลดการตั้งค่า
const settings = getInitialSettings();
// 2. เริ่มต้นบริการ
await initializeServices();
// 3. ตั้งค่าการจัดการสถานะ
createStore();
// 4. ลงทะเบียน handlers สำหรับ cleanup
registerCleanup(() => {
// ตรรกะ cleanup
});
}
การเริ่มต้นบริการ
// บริการถูกเริ่มต้นแบบขนาน
await Promise.all([
initializeApiService(),
initializeMcpService(),
initializeOauthService(),
initializeLspService(),
initializeAnalyticsService()
]);
ระบบ Feature Flags
Feature gates ถูกใช้อย่างกว้างขวางสำหรับการตัดโค้ดที่ตาย:
import { feature } from 'bun:bundle';
// การโหลดโมดูลตามเงื่อนไข
if (feature('COORDINATOR_MODE')) {
const coordinatorModule = require('./coordinator/coordinatorMode.js');
// ใช้ฟังก์ชันของ coordinator
}
if (feature('KAIROS')) {
const assistantModule = require('./assistant/index.js');
// ใช้ฟังก์ชันของ assistant
}
if (feature('DIRECT_CONNECT')) {
// จัดการ URL ของ direct connect
const parsed = parseConnectUrl(ccUrl);
}
Feature Flags หลัก
| Flag | วัตถุประสงค์ |
|---|---|
COORDINATOR_MODE | เปิดใช้งาน coordinator/agent swarms |
KAIROS | เปิดใช้งานโหมด assistant |
DIRECT_CONNECT | เปิดใช้งาน URL ของ direct connect |
SSH_REMOTE | เปิดใช้งานเซสชัน SSH ระยะไกล |
HISTORY_SNIP | เปิดใช้งานการหดประวัติเป็น snip |
UPLOAD_USER_SETTINGS | เปิดใช้งานการซิงค์การตั้งค่า |
ระบบ Migration
Migrations ทำงานใน hook ก่อน action:
// src/main.tsx (บรรทัด 325-352)
const CURRENT_MIGRATION_VERSION = 11;
function runMigrations(): void {
if (getGlobalConfig().migrationVersion !== CURRENT_MIGRATION_VERSION) {
migrateAutoUpdatesToSettings();
migrateBypassPermissionsAcceptedToSettings();
migrateEnableAllProjectMcpServersToSettings();
resetProToOpusDefault();
migrateSonnet1mToSonnet45();
migrateLegacyOpusToCurrent();
migrateSonnet45ToSonnet46();
migrateOpusToOpus1m();
migrateReplBridgeEnabledToRemoteControlAtStartup();
if (feature('TRANSCRIPT_CLASSIFIER')) {
resetAutoModeOptInForDefaultOffer();
}
if ("external" === 'ant') {
migrateFennecToOpus();
}
saveGlobalConfig(prev => ({
...prev,
migrationVersion: CURRENT_MIGRATION_VERSION
}));
}
}
การโหลดล่วงหน้าที่ถูกเลื่อนออกไป
การโหลดล้่วงหน้าที่ไม่วิกฤตทำงานหลังการแสดงผลครั้งแรก:
// src/main.tsx (บรรทัด 388-431)
export function startDeferredPrefetches(): void {
// ข้ามในโหมด bare หรือเมื่อวัดการเริ่มต้นระบบ
if (isBareMode() || process.env.CLAUDE_CODE_EXIT_AFTER_FIRST_RENDER) {
return;
}
// โหลดล่วงหน้าบริบทของผู้ใช้
void initUser();
void getUserContext();
// โหลดล่วงหน้าบริบทของระบบถ้าปลอดภัย
prefetchSystemContextIfSafe();
// โหลดล่วงหน้า URL ของ MCP
void prefetchOfficialMcpUrls();
// เริ่มต้น gates ของ analytics
void initializeAnalyticsGates();
// เริ่มตัวตรวจจับการเปลี่ยนแปลงไฟล์
void settingsChangeDetector.initialize();
if (!isBareMode()) {
void skillChangeDetector.initialize();
}
}
ตัวชี้วัดประสิทธิภาพการเริ่มต้นระบบ
| ระยะ | ระยะเวลา | คำอธิบาย |
|---|---|---|
| ผลข้างเคียงก่อน import | 0-10ms | MDM, Keychain prefetch |
| การโหลด imports | ~135ms | การประเมินโมดูล |
| Hook ก่อน action | ~50ms | การเริ่มต้นบริการ |
| Migrations | ~20ms | การย้ายการตั้งค่า |
| การแสดงผลครั้งแรก | <200ms | เวลาทั้งหมดสู่ UI แรก |
ข้อควรพิจารณาด้านความปลอดภัย
- การเริ่มต้นแบบขนาน: กระบวนการหลายตัวทำงานพร้อมกัน
- Feature Gates: การตัดโค้ดที่ตายลดการใช้หน่วยความจำ
- Lazy Loading: โหลดโมดูลหนักเมื่อต้องการ
- ขอบเขตข้อผิดพลาด: การลดผลกระทบจากข้อผิดพลาดอย่างนุ่มนวล
- โหมด Permission: การเริ่มต้นระบบเคารพการตั้งค่า permission
แนวปฏิบัติที่ดีของการเริ่มต้นระบบ
- การดำเนินการแบบขนาน: MDM, Keychain, API ทั้งหมดเริ่มพร้อมกัน
- Feature Flags: การโหลดโมดูลตามเงื่อนไข
- ระบบ Migration: การอัปเดตการตั้งค่าอัตโนมัติ
- งานที่ถูกระงับ: งานที่ไม่วิกฤตหลังการแสดงผลครั้งแรก
- Handlers สำหรับ Cleanup: การทำความสะอาดทรัพยากรเมื่อออกจากระบบ