我在做vscode extension开发过程中,在代码里写了一个时间间隔为10ms的setInterval,将插件上架后,有时候(并不是每次)运行插件时,这个插件内的那个定时器执行的时间间隔并不是10ms左右,这里我用stats做的监测,单帧耗时稳定在996ms-1009ms,初步确定最小间隔被设置在1000ms左右。我的代码如下,目前可以确定的是函数check1并不会占用太多资源,平均耗时在10ms以内。
...
const logic = () => {
check1()
}
logic()
mainInterval = setInterval(() => {
logic()
}, 10)
...
当然,我也尝试使用setTimeout代替setInterval,如下所示,但是最后效果也是一样的。
...
const logic = () => {
check1()
}
logic()
mainInterval = setTimeout(logic, 10)
...
值得注意的是,我的代码中,同时使用着requestAnimationFrame,在定时器时间间隔出现异常的时候,requestAnimationFrame运行是正常的,页面平均每帧16.66ms,动画是流畅的。
整套程序在web端能够正常运行,并未出现定时器异常情况。
我这边有考虑是否是插件占用CPU或者内存过高,但在vscode内部的流程资源管理器和开发人员工具的Performance及Memory栏,观察到各项指标均未出现异常。也就是在启动插件后,异常和正常现象发生时,内存和CPU没有明细变化,占用率也很低。
在开发扩展程序的过程中,我使用了webview作为核心技术,不太清楚异常是否涉及iframe的相关内容。关键代码如下:
...
// init webview panel
if (panel) {
panel.reveal(vscode.ViewColumn.Active);
} else {
panel = vscode.window.createWebviewPanel(
'test',
'Test',
vscode.ViewColumn.One,
{
enableScripts: true, // 启用JS,默认禁用
retainContextWhenHidden: true, // webview被隐藏时保持状态,避免被重置
}
);
// And get the special URI to use with the webview
panel.webview.html = getWebViewContent(context, 'src/webview/dist/index.html', panel)
// Panel dispose
panel.onDidDispose(
() => {
panel = null
},
null,
context.subscriptions
);
}
...
...
function getWebViewContent(context, templatePath, panel) {
const resourcePath = path.join(context.extensionPath, templatePath);
const dirPath = path.dirname(resourcePath);
let htmlIndexPath = fs.readFileSync(resourcePath, 'utf-8');
const html = htmlIndexPath.replace(/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g, (m, $1, $2) => {
const absLocalPath = path.resolve(dirPath, $2);
const webviewUri = panel.webview.asWebviewUri(vscode.Uri.file(absLocalPath));
const replaceHref = $1 + webviewUri.toString() + '"';
return replaceHref;
});
return html;
}
...