引用您的问题:
我尝试为每个文件创建一个 Monaco 实例,但是在大约 30 个实例时会变得非常缓慢。
您的问题的解决方案
正如您所提到的,性能很低下。这是因为您的服务器或客户端没有足够的内存。您需要为服务器或客户端添加更多内存以获得更好的性能。因为我没有足够的信息,所以我无法确定是服务器还是客户端的问题。但是这种方法是不高效的。
引用您的问题:
IStandaloneDiffEditor 在名称中有“standalone”一词的原因是什么?是否有其他更有效的方法来创建多个 diff 编辑器?
这与此无关。在维基百科中,我找到了“standalone”一词的含义:
独立软件可以指:
- 可以离线工作的计算机软件,即无需网络连接即可运行。
- 不是一些捆绑软件的一部分的软件。
- 作为单独计算机进程运行的程序,而不是现有进程的附加组件。
- 独立程序,不需要操作系统的服务即可运行。
- 便携式应用程序,可以在不需要安装过程的情况下运行。
这意味着“standalone”与单个实例无关,您可以拥有此编辑器的多个实例。但是,您需要在计算机上拥有更多内存才能从此编辑器创建 100 个实例。这不是高效的,因为您的内存中有 100 个大型 JavaScript 对象。
在其他显示更改文件之间的差异的服务中,他们仅使用 DOM 对象或使用 DOM 对象 + 一个大的 JavaScript 对象实例来创建这些对象,而不是额外的 100 个大的 JavaScript 对象实例。
根据这个原则,在这种情况下,您可以使用下面我推荐的解决方案中的代码,并在后台仅创建此差异编辑器的一个实例。然后,您必须将所有 100 个文件依次放入此实例中,并在每种情况下从一个文件复制以下 DOM 对象:
<div class="editor original showUnused" ...
<div class="editor modified showUnused" ...
例如,您可以使用以下代码执行此操作:
var diffPartContainars = document.querySelector('#container').querySelectorAll('.showUnused'),
editorOriginalPartHTML,
editorModifiedPartHTML;
for(var i = diffPartContainars.length; i--;)
{
var obj = diffPartContainars[i],
cln = obj.className;
if(cln.indexOf('editor original') > -1)
{
obj.removeAttribute('style');
editorOriginalPartHTML = obj.outerHTML;
}
if(cln.indexOf('editor modified') > -1)
{
obj.removeAttribute('style');
editorModifiedPartHTML = obj.outerHTML;
}
}
然后您需要从每个editorOriginalPartHTML和editorModifiedPartHTML中删除以下DOM对象:
<div class="invisible scrollbar horizontal" ...
<canvas class="decorationsOverviewRuler" ...
<div class="visible scrollbar vertical" ...
以及您无法使用的所有其他对象。当您将editorOriginalPartHTML和editorModifiedPartHTML添加到DOM时,可以执行此操作。然后,您可以在每个对象周围添加一个div对象,具有适当的宽度,高度和style ="overflow:auto"。还有一件事情可以做:对于这些div对象中的每个对象,您可以添加一个onclick或onmouseover监听器,然后将此div对象视图替换为差异编辑器实例。
在我看来,这只是更有效率的一种方式。祝你好运!
推荐的高效解决方案
快速、舒适且高效的方法是仅有一个此编辑器实例并在单击文件名时加载新源代码,如下所示。
var diffEditor = null;
var filesContent =
{
'SomeJavaScriptFile.js':
{
originalContent: 'alert("heLLo world!")',
modifiedContent: 'alert("hello everyone!")',
type: 'text/javascript'
},
'AnotherJavaScriptFile.js':
{
originalContent: 'function open(str)\n{\n\talert(str)\n}',
modifiedContent: 'function output(value)\n{\n\tconsole.log(value)\n}',
type: 'text/javascript'
}
};
document.querySelector('#files').addEventListener('change', function(e)
{
var fileName = this.options[this.selectedIndex].text,
file = filesContent[fileName];
openInDiffEditor(file);
});
function openInDiffEditor(file)
{
if(!diffEditor)
diffEditor = monaco.editor.createDiffEditor(document.querySelector('#container'));
diffEditor.setModel({
original: monaco.editor.createModel(file.originalContent, file.type),
modified: monaco.editor.createModel(file.modifiedContent, file.type)
});
}
var firstFileName = document.querySelector('#files').options[0].text;
openInDiffEditor(filesContent[firstFileName]);
<p>Please select one file on the left list to see the file differences after changes.</p>
<select id="files" size="3">
<option selected>SomeJavaScriptFile.js</option>
<option>AnotherJavaScriptFile.js</option>
</select>
<div id="container" style="height:100%;"></div>
你需要通过 AJAX 加载文件内容。如果你不知道如何加载,请问我,我会为你编写。
推荐解决方案的截图