tern icon indicating copy to clipboard operation
tern copied to clipboard

module resolution plugins cause slowdown in brackets in vim for at least YouCompleteMe

Open tonywoode opened this issue 8 years ago • 5 comments
trafficstars

To reproduce

*.tern-config

{
  "plugins": {
    "node_resolve": {},
    "es_modules": {},
    "modules": {}
  }
}
  • Navigate in vim to a moderately-parenthesized statement nested inside an object in any manner of Javascript file e.g.: last line here
 export class DemonstrateSlowParens extends React.Component {

  constructor(props) {
    super(props);
  }

  someMethod(video) {
      loading: true
    }

    (this.props.connectToSomething || connectToSomething)(channel)(video, state => this.setState(state))

}
  • note that each cursor movement inside the parens takes 5-10 seconds
  • this clears up after some time (eg: 4 minutes) but reappears each time the file is navigated away and back
  • I cannot find a solution but to remove one or other from config. As TC39 and Node integrate module management https://medium.com/the-node-js-collection/an-update-on-es6-modules-in-node-js-42c958b890c this will get more troublesome...

tonywoode avatar Jul 11 '17 18:07 tonywoode

I can't reproduce this with just that file snippet. It is likely that the problem is with a dependency of your file that is being analyzed, and by disabling one of these plugins, you disable dependency loading. As such, this is probably not so much about combining the plugins, but about loading a given piece of code. I haven't got enough information to figure out which code.

marijnh avatar Jul 11 '17 20:07 marijnh

sure, so actually I have the cripplingy slow cursor-through-parenthesized-text just with:

.tern-config

{
  "plugins": {
    "node_resolve": {},
    "modules": {}
  }
}

package.json

{
  "main": "test.js",
  "dependencies": {
    "express": "^4.14.1",
    "ramda": "^0.22.1"
  }
}

test.js

const R = require('ramda')
const app = require('express')();
const http = require('http').Server(app);

(or any combination of moderately large node project).

then npm install then vim test.js. Then try and w through from the start to the end of those three lines in under a minute!

In fact even with just one of these dependencies, navigating through its own require statements parens demonstrates the issue for several seconds. (I have a 2015 macbook pro core i7 3.1ghz)

with es6 imports, i receive the same problem with:

.tern-config

{
  "plugins": {
    "node_resolve": {},
    "es_modules": {},
    "modules": {}
  }
}

test2.js

import R from 'ramda'

export default function main(foo, bar){

 return baz
}

(try navigating through the (foo, bar))

BUT I don't receive the issue with test2.js if either node-resolve or es-modules are singly removed from my tern config

I must stress Ramda is merely an example, any moderately large imported codebase causes similar motion-in-brackets sickness

tonywoode avatar Jul 12 '17 06:07 tonywoode

I must stress Ramda is merely an example,

I'm not sure that's the case -- Ramda is known to work poorly with Tern, see #570

marijnh avatar Jul 12 '17 06:07 marijnh

You're right, changing Ramda to React cures the problem in my first example! Thanks for the link to #570

However:

.tern-config

{
  "plugins": {
    "node_resolve": {},
	"modules": {}
  }
}

package.json

{
  "main": "test.js",
  "dependencies": {
    "data.either": "^1.5.0",
    "data.task": "^3.0.0",
    "postal": "^1.0.8"
  }
  
}

test.js

const q = require('data.either')
const r = require('data.task')
const s = require('postal')

has exactly the same order of magnitude of slowdown. ack ramda -ri ~/tester/node_modules/postal (and it seems to be Postal causing the issue there) gives me nothing...

tonywoode avatar Jul 12 '17 07:07 tonywoode

and an es6 module example demonstrating the second issue but without using Ramda:

.tern-config

{
  "plugins": {
    "node_resolve": {},
    "es_modules": {},
    "modules": {}
  }
}

(corresponding package.json)

test2.js

import jsdom from 'jsdom'
import mocha from 'mocha'
import mochawesome from 'mochawesome'
import nyc from 'nyc'
import rx from 'rx'

export class someClass {

  connect(video) {

    (this.props.connectToSomething || connectToSomething)(channel)(video, state => this.setState(state));
  }
  
}

try to w or right-arrow through that last line...same order of magnitude issues as Ramda

the YCM Options I have set:

let g:ycm_auto_trigger = 0
let g:ycm_autoclose_preview_window_after_completion = 1
let g:ycm_autoclose_preview_window_after_insertion = 1

tonywoode avatar Jul 12 '17 09:07 tonywoode