Skip to content

improve template interpolation features performance when no changes to the file #2642

@jasonlyu123

Description

@jasonlyu123
  • I have searched through existing issues

Feature Request

Hi, First of all, thanks for the great works you guys put into it. The template interpolation feature really makes the developer experience way better and it's a good boost to productivity. But the performance is really not very good sometimes. I would like to help out and make it better.

I'll focus on the performance of template interpolation features performance when no changes to the file in this issue. That is features like hover, completion resolve, go to definition, and find references. Especially the second request. I have done some investigation using my local clone version. Here's what I found out and think can make the performance better:

The problems

vueInfoService.getInfo

return this.vueFileInfo.get(getFileFsPath(doc.uri));

This method is very demanding it often took more than 500ms on my machine. Besides the performance of this method, what strange to me is that the vueFileInfo map here seems like a kind of cache but it'll always get updated when getInfo is called. Furthermore, the stored info doesn't get removed when the document is closed or deleted in the file system, so it's a sort of memory leak. I think we could remove the map here.

const defaultExportType = checker.getTypeAtLocation(defaultExportNode);

The most demanding part of vueInfoService.getInfo seems to be this line. Analyzing the type afterward isn't that demanding. I notice typescript does cache the type checker result here. When typescript cache the type it runs significantly faster. So the problem is mainly on why typescript won't use the cached version. Once that's resolved. Most of the features that use this method might have a good boost in performance.

Auto import, on the other hand, the implementation makes the script version mismatch on every resolve request. Thus typescript would always analyze it again. We probably need to find another way to improve it. I wonder if we can make the mockDoc here different than the actual script doc.

serviceHost.updateCurrentVirtualVueTextDocument

if (isVirtualVueTemplateFile(fileFsPath)) {

The version of the virtual vue file bumps whenever the function is called. This makes typescript analyze the type again. It seems to also affect the language service the script section used. And it seems to be the main problem of the interpolation performance. Once I commented out the version bump, most of the feature is way faster. I think we can use the version of TextDocument to avoid bumping when not necessary. But always update ChildComponentsInfo in case the dependent component is updated.

TL;DR

From my understanding/investigation, the main problem is that the version of the virtual vue file in the ServciceHost bumps every time. I think we should use the TextDoucment.version to check if we should bump the version. So that typescript won't do the type analysis again. And the vueFileInfo map in the vueInfoService doesn't get used and seems like it can be removed.

Feel free to point out what I missed or what I understand incorrectly. I can help to implement what I mention above. But I think it would be better to have an issue to discuss it first.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions