天天看點

vscode 檔案追蹤_vscode源碼分析【三】程式的啟動邏輯,性能問題的追蹤

啟動追蹤

代碼檔案:src\main.js

如果指定了特定的啟動參數:trace

vscode會在啟動之初,執行下面的代碼:

const contentTracing = require('electron').contentTracing;

const traceOptions = {

categoryFilter: args['trace-category-filter'] || '*',

traceOptions: args['trace-options'] || 'record-until-full,enable-sampling'

};

contentTracing.startRecording(traceOptions, () => onReady());

這段代碼的主要目的是:從Chromium的内容子產品收集跟蹤資料,以查找性能瓶頸和程式執行緩慢的操作。

注意,這個操作隻能在app.ready事件觸發之後才能執行; startRecoding會異步請求所有子程序開始執行追蹤操作;

一旦所有子程序都确認了主程序的請求,主程序就會執行startRecoding的回調方法;

結束追蹤

在視窗成功啟動之後,vscode結束了性能問題的追蹤(如果30秒視窗還沒啟動,那麼也會結束性能問題的追蹤)

代碼檔案:vs\code\electron-main\app.ts(在上一篇博文中,啟動第一個視窗,也是在這裡執行的)

const windows = appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor, electronIpcServer, sharedProcessClient));

stopTracingEventually方法的代碼為:

private stopTracingEventually(windows: ICodeWindow[]): void {

this.logService.info(`Tracing: waiting for windows to get ready...`);

let recordingStopped = false;

const stopRecording = (timeout: boolean) => {

if (recordingStopped) {

return;

}

recordingStopped = true; // only once

contentTracing.stopRecording(join(homedir(), `${product.applicationName}-${Math.random().toString(16).slice(-4)}.trace.txt`), path => {

if (!timeout) {

if (this.windowsMainService) {

this.windowsMainService.showMessageBox({

type: 'info',

message: localize('trace.message', "Successfully created trace."),

detail: localize('trace.detail', "Please create an issue and manually attach the following file:\n{0}", path),

buttons: [localize('trace.ok', "Ok")]

}, this.windowsMainService.getLastActiveWindow());

}

} else {

this.logService.info(`Tracing: data recorded (after 30s timeout) to ${path}`);

}

});

};

// Wait up to 30s before creating the trace anyways

const timeoutHandle = setTimeout(() => stopRecording(true), 30000);

// Wait for all windows to get ready and stop tracing then

Promise.all(windows.map(window => window.ready())).then(() => {

clearTimeout(timeoutHandle);

stopRecording(false);

});

}

子程序會緩存跟蹤資料,一般不會把跟蹤資料發送給主程序(避免發送資料再造成性能消耗),

是以,結束跟蹤也是主程序異步地要求所有子程序持久化跟蹤資料的。

跟蹤結束後,會執行stopRecording的回調函數。

在這裡會顯示一個提示框,提示使用者性能追蹤的結果;(如果超了30秒,那麼就隻記日志了)