microsoft / microsoft/monaco-editor

[Bug] Loading bulk models is causing major delay in intellisense

Open
#3,355 4 comments 0 reactions 1 assignee View on GitHub

Nobody has claimed this yet.

feature-request typescript
Dominant language
JavaScript
Stars
46.8k
Forks
4.1k
Avg merge
17h 58m
Merged PRs (30d)
1

Description

Reproducible in vscode.dev or in VS Code Desktop?
  • Not reproducible in vscode.dev or VS Code Desktop
Reproducible in the monaco editor playground?
Monaco Editor Playground Code
// ========== Example #1: Loading .definition models instead of .ts ======================
monaco.languages.typescript.javascriptDefaults.setEagerModelSync(false);
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(false);

monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: true,
    noSyntaxValidation: true,
    noSuggestionDiagnostics: true
});

monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: true,
    noSyntaxValidation: true,
    noSuggestionDiagnostics: true
});

monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES2016,
    allowNonTsExtensions: true,
    moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
    module: monaco.languages.typescript.ModuleKind.CommonJS,
    noEmit: true,
    typeRoots: ["node_modules/@types"]
});

// Case #1: Load 2000 .d.ts files with each having 1 function declaration
let extraLibs = []
for (let i = 0; i < 2000; i++) {
    extraLibs.push(
        {
        content: `export declare function next${i}() : string`,
        filePath:  monaco.Uri.file(`/node_modules/@types/external${i}/index.d.ts`).toString(true)
        }
    );
}

// Case #2: Load 1 .d.ts file with 2000 function declarations
/*let def = ''
for (let i = 0; i < 2000; i++) {
    def = def.concat(`export declare function next${i}() : string\n`);
}
let extraLibs = []
extraLibs.push(
    {
    content: def,
    filePath:  monaco.Uri.file(`/node_modules/@types/external1/index.d.ts`).toString(true)
    }
);*/

monaco.languages.typescript.typescriptDefaults.setExtraLibs(extraLibs);

extraLibs.forEach((lib) => monaco.editor.createModel(lib.content, "typescript", monaco.Uri.parse(lib.filePath)))


var jsCode = `import * as x from "external1"
const tt : string = x.next1();`;

monaco.editor.create(document.getElementById("container"), {
    model: monaco.editor.createModel(jsCode, "typescript", monaco.Uri.file("main.tsx")),
});



// ========== Example #2: Loading .ts models instead of definitions ======================
/*monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true);
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);

monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: true,
    noSyntaxValidation: true,
    noSuggestionDiagnostics: true
});

monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
    noSemanticValidation: true,
    noSyntaxValidation: true,
    noSuggestionDiagnostics: true
});

editor = monaco.editor.create(
    document.getElementById('container'),
    {
        minimap: { enabled: true },
        scrollBeyondLastLine: true,
        // model: null,
        language: 'typescript',
        theme: 'vs-dark',
        value: 'function () {}\n\n'
    }
);

// simulate 2000 .ts files
for (var fileIdx = 0; fileIdx < 2000; fileIdx++) {
    for (var fnIdx = 0; fnIdx < 1; fnIdx++) {
        monaco.editor.createModel(`
            function test_${fileIdx}_${fnIdx}() {}
            function fn_${fileIdx}_${fnIdx}() {}
            function foo_${fileIdx}_${fnIdx}() {}
            function bar_${fileIdx}_${fnIdx}() {}
            function out_${fileIdx}_${fnIdx}() {}
            `,
            'typescript'
        );
    }
}*/
Reproduction Steps

Press Ctrl + Space after x. in the playground output (in the 2nd line: const tt : string = x.next1();). Suggestions dialog shows 'Loading...' indicator for 12-15 seconds before showing the eligible candidates.

for (let i = 0; i < 2000; i++) {
    extraLibs.push(
        {
        content: `export declare function next${i}() : string`,
        filePath:  monaco.Uri.file(`/node_modules/@types/external${i}/index.d.ts`).toString(true)
        }
    );
}
Actual (Problematic) Behavior

Adding bulk of definition or ts file models is causing the 'Loading...' indicator for 12-15 seconds for every intellisense request. Not just the initial request.

Expected Behavior

Intellisense requests should complete with in reasonable time which otherwise directly impacts the developer experience

Additional Context

I posted this as a question in Stackoverflow (https://stackoverflow.com/questions/73936684/performant-way-to-load-2000-ts-models-into-monaco-editor-for-intellisense), but the solutions suggested (loading definition files) also didn't worked.

My observation: When I have bulk of files (ex: 2000), then the intellisense is taking longer time. But when I add 200K function declarations to 1 definition file, the perf is very good.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.