perf: optimize app startup and background lifecycles

This commit is contained in:
inman
2026-08-19 00:56:15 +08:00
parent 31332f6d76
commit 927e13349b
121 changed files with 4359 additions and 1400 deletions

View File

@@ -76,7 +76,8 @@ class PublishPreflightFault extends Error {
this.name = 'PublishPreflightFault';
}
}
const ENABLED_DOMAINS = ['Runtime.enable', 'Log.enable', 'Network.enable', 'Page.enable'] as const;
const DIAGNOSTIC_DOMAINS = ['Runtime.enable', 'Log.enable', 'Network.enable', 'Page.enable'] as const;
const DIAGNOSTIC_DISABLE_DOMAINS = ['Page.disable', 'Network.disable', 'Log.disable', 'Runtime.disable'] as const;
const STREAM_ISSUING_METHODS = new Set([
'Fetch.takeResponseBodyAsStream',
'Network.loadNetworkResource',
@@ -95,6 +96,7 @@ interface BrowserRecord {
url: string;
title: string;
visible: boolean;
diagnosticsEnabled: boolean;
bounds: AgentBrowserBounds | null;
error?: {
code: AgentBrowserErrorCode;
@@ -279,6 +281,7 @@ export class AgentBrowserModule {
url: targetUrl,
title: '',
visible: Boolean(bounds) && (input.visible ?? true),
diagnosticsEnabled: false,
bounds,
eventBuffer: new AgentBrowserEventBuffer(),
childSessions: new Set(),
@@ -356,6 +359,14 @@ export class AgentBrowserModule {
});
}
setDiagnostics(input: { projectPath: string; enabled: boolean }): Promise<AgentBrowserSnapshot> {
return this.serialize(async () => {
const record = this.requireRecord(input.projectPath);
await this.configureDiagnostics(record, input.enabled);
return this.snapshot(record);
});
}
navigate(input: AgentBrowserNavigateInput): Promise<AgentBrowserSnapshot> {
return this.serialize(async () => {
const record = this.requireAttached(input.projectPath);
@@ -665,14 +676,16 @@ export class AgentBrowserModule {
record.error = undefined;
if (needsAttach) port.attach(CDP_PROTOCOL_VERSION);
for (const method of ENABLED_DOMAINS) {
await port.sendCommand(method);
}
await port.sendCommand('Target.setAutoAttach', {
autoAttach: true,
waitForDebuggerOnStart: false,
flatten: true,
});
if (record.diagnosticsEnabled) {
for (const method of DIAGNOSTIC_DOMAINS) {
await port.sendCommand(method);
}
}
if (record !== this.record || record.view.webContents.isDestroyed()) {
throw new AgentBrowserFault(
'CLOSED',
@@ -789,12 +802,45 @@ export class AgentBrowserModule {
});
}
private async configureDiagnostics(record: BrowserRecord, enabled: boolean): Promise<void> {
if (record !== this.record || record.view.webContents.isDestroyed()) {
throw new AgentBrowserFault(
'TARGET_GONE',
'开发浏览器页面已关闭。',
true,
record.generation,
);
}
const debuggerPort = record.view.webContents.debugger;
if (enabled) {
if (record.diagnosticsEnabled) return;
for (const method of DIAGNOSTIC_DOMAINS) {
await debuggerPort.sendCommand(method);
}
record.diagnosticsEnabled = true;
return;
}
if (!record.diagnosticsEnabled) return;
for (const method of DIAGNOSTIC_DISABLE_DOMAINS) {
try {
await debuggerPort.sendCommand(method);
} catch {
// The page may have navigated or crashed while diagnostics closed.
}
}
record.diagnosticsEnabled = false;
record.eventBuffer.clear();
this.payloadStore.clear();
this.notifyEventWaiters();
}
private appendEvent(
record: BrowserRecord,
method: string,
params: unknown,
sessionRef?: string,
): void {
if (!record.diagnosticsEnabled) return;
const base = {
generation: record.generation,
timestamp: Date.now(),