LWC component code completion performance lags with large number of custom components

Issue #2479 resolved
Scott Wells repo owner created an issue

A user reported slow code completion for LWC component names in HTML files in a project with a large number of custom components, in this case ~2K. Right now it looks like IC2 is finding all LWC component *.js-meta.xml files for the project using the standard filename index, then enumerating the result and deriving the custom components. That could be made much more efficient by maintaining a file-based index of components based on those same files.

Official response

  • Scott Wells reporter

    For those experiencing this issue, this is a build of 2.3.0.2 with a change to use a custom index for finding files by extension instead of using the filename index behind a simple in-memory cache. It looks good on my side, but that's really just confirming that everything still works and not whether it improves performance in projects with large numbers of LWC components. I'd love to get some feedback on it from those who do have such projects, though.

    You can install this build by downloading (but not extracting) it and using Settings / Preferences | Plugins | Install plugin from disk (under the gear drop-down menu). Allow the IDE to restart and indexing to complete (should be very fast), and then try operations that were previously slower for you to see whether or not there's an improvement. Please let me know either way, and if this build causes issues for you, please let me know about those as well and roll back ot the last released build, 2.3.0.2 by uninstalling the IC2 plugin and installing again from the JetBrains plugin repo.

Comments (18)

  1. Xander Victory

    I also see this with ~170 components, and experiments showed that not relying on the filename index improved it dramatically

  2. Scott Wells reporter

    Thanks for the info, Xander, though I don’t understand “experiments showed that not relying on the filename index improved it dramatically”. What were these experiments?

  3. Scott Wells reporter

    For those experiencing this issue, this is a build of 2.3.0.2 with a change to use a custom index for finding files by extension instead of using the filename index behind a simple in-memory cache. It looks good on my side, but that's really just confirming that everything still works and not whether it improves performance in projects with large numbers of LWC components. I'd love to get some feedback on it from those who do have such projects, though.

    You can install this build by downloading (but not extracting) it and using Settings / Preferences | Plugins | Install plugin from disk (under the gear drop-down menu). Allow the IDE to restart and indexing to complete (should be very fast), and then try operations that were previously slower for you to see whether or not there's an improvement. Please let me know either way, and if this build causes issues for you, please let me know about those as well and roll back ot the last released build, 2.3.0.2 by uninstalling the IC2 plugin and installing again from the JetBrains plugin repo.

  4. Xander Victory

    Thanks for the info, Xander, though I don’t understand “experiments showed that not relying on the filename index improved it dramatically”. What were these experiments?

    I don’t remember exactly what I changed, but modifying the IC jar locally to try to improve LightningWebComponentsTagNameProvider - there was one instance I recall that was calculating the whole data structure of custom LWC, only to use the keys of the map

  5. Xander Victory

    testing with the new build does have better performance, though I’m getting the <template> tag not showing up (I think it was happening previously too)

  6. Scott Wells reporter

    Regarding the <template> tag not showing up in completion lists, I’d noticed that had started happening myself, though independent of this performance change. It seems that standard HTML tags aren’t being listed for completion, though they’re known by the IDE. My guess is that something is telling the completion framework to stop enumerating completions incorrectly or similar. I’ll investigate that.

    Regarding the performance improvements around custom LWC components, are they enough to consider this a proper fix for that performance issue, or are they just a marginal improvement? I can’t tell from your comment whether or not it’s safe to move on from that problem with the current optimization included in the attached build.

  7. Scott Wells reporter

    FYI, I’ve figured out why <template> is not being offered as a code completion (as well as other HTML tags). It happens specifically when trying to add child tags to LWC component tags, and it’s because IC’s implementation of those XML elements is specifying that no children are allowed. I’m pretty sure at one point that meant that any children are allowed, but it does now seem to mean that no children are allowed – other than other LWC components which IC is enumerating itself. I haven’t quite figured out how to tell it that any HTML tag is also allowed, but worst-case scenario, I’ll ping JetBrains and see how that might be accomplished. I’m certainly not the first to need to be able to do that. I’ll try to work that into the next build.

  8. Xander Victory

    It’s an improvement, though I’m still seeing a hotspot in com.illuminatedcloud.intellij.lwc.util.LightningWebComponentsUtil.getCustomComponentAttributes () - I think this is the one where it gets the full details only to use the component name.

    And the cached value just isn’t cached, as no component names/attributes are changing during this process.

    This is running Retype File on a 239 line file.

  9. Scott Wells reporter

    Just to be clear, is that Retype File against the .js file or the .html file? If the .js file, I’d expect that behavior as the .js and .js-meta.xml file are the cache dependencies. If the .html file and the .js file is unchanged during that retype, that would be surprising. There should be one cache read-through and then the attributes for that component should be cached for the remainder of the retype.

  10. Scott Wells reporter

    Well, consider me surprised because there was definitely a caching issue with custom LWC component attributes. The issue wasn't with the cache dependencies but rather with the element on which the cache was stored, specifically the component .js file itself. Evidently the JetBrains JavaScript plugin marks all .js files as dirty when one file changes, presumably to ensure that references are recalculated across files given the dynamic nature of the language. That meant that modifying one file caused the cached attributes for all other files to become stale and require repopulation.

    I'm attaching a build that caches custom component attributes differently. Now I'm seeing cache read-throughs occurring only for .js files that have been modified.

    Xander (and anyone else who wants to help), can you please install this build and see whether it moves the needle or not? Thanks!

  11. Scott Wells reporter

    Okay, great! Thanks for the input and feedback. Please let me know if you see any negative side-effects of these changes, of course. Otherwise they’ll be slated for inclusion in the next official build later this week.

  12. Log in to comment