Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Huge delay for accesibility of tide's functionality #1472

Open
kreedz opened this Issue Jun 1, 2018 · 8 comments

Comments

Projects
None yet
4 participants
@kreedz
Copy link

kreedz commented Jun 1, 2018

I have tested this issue on my working project with more than 5000 ts and tsx files. And so huge (30-90 seconds) delay noticed only there. Unfortunately I can't share that project.
Also I have tested this issue on http://github.com/Microsoft/vscode project. There something like 3000 ts files. And delay is smaller - something like 10 seconds.

Packages that installed

They specified below in my init.el config:

  • add-node-modules-path
  • tide
  • web-mode

Steps to reproduce

  • Open emacs. Before you open the file make sure that tslint is installed locally or globally. For local tslint you will need add-node-modules-path package (you can find it below in my init.el file).
  • Then for the first time open a ts file (e.g. vscode/src/vs/base/browser/ui/progressbar/progressbar.ts) and wait until tsserver will do his init stuff.
  • Place pointer on imported variable (e.g. on TPromise here import { TPromise, ValueCallback } from 'vs/base/common/winjs.base';). Wait some time until that variable will be highlighted (it's tide-hl-mode). So now you can jump to definition by M-.. Try to do that.
  • Jump back by M-,.
  • Immediately place pointer at some imported variable.
  • Now here I'm expecting that variable will be highlighted and it's will be possible to jump to definition.
    But what is happening instead: variable doesn't highlighted and you can't jump to definition, you have to wait something like 30-90 (or ~10 seconds on vscode project) seconds until do that.

The issue will not occur again in the same file when it happens once.

Same issue happens when I write something like 'asdasd' in the new line and then place pointer at imported variable.
Also experiencing that when open another file from same project and place pointer on imported variable.

This issue happens both on linux and windows machines.
But on linux I'm getting next message when placing pointer on variable and when that variable doesn't highlighted:
Error from syntax checker typescript-tslint: Bad string format: "doesn't start with "'!" [4 times]`
But on windows machine that message doesn't show.

Outputs and init config from linux

flycheck-verify-setup:

emacs --version: 25.3.1
Flycheck version: 32snapshot (package: 20180527.918)

flycheck-verify:
Syntax checkers for buffer accessibilityHelp.ts in typescript-mode:

  typescript-tide
    - may enable:        yes
    - predicate:         t
    - Typescript server: running
    - Tide mode:         enabled

  typescript-tslint
    - may enable:         yes
    - executable:         Found at /home/kreedz/work/js/vscode/node_modules/.bin/tslint
    - configuration file: Found at "/home/kreedz/work/js/vscode/tslint.json"

Flycheck Mode is enabled.  Use M-x universal-argument C-c ! x to
enable disabled checkers.

init.el:

(setq custom-file (substitute-in-file-name "$HOME/.emacs.d/custom.el"))
(load custom-file)

;; turn off menu, scroll, tool bars
(if (display-graphic-p)
    (progn
      (tool-bar-mode -1)
      (scroll-bar-mode -1)
      (menu-bar-mode -1)))

;; list the packages you want
(setq package-list
      '(add-node-modules-path
        tide
        web-mode))

;; list the repositories containing them
(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
                         ("marmalade" . "https://marmalade-repo.org/packages/")
                         ("melpa" . "https://melpa.org/packages/")))

;; activate all the packages (in particular autoloads)
(package-initialize)

;; fetch the list of packages available 
(unless package-archive-contents
  (package-refresh-contents))

;; install the missing packages
(dolist (package package-list)
  (unless (package-installed-p package)
    (package-install package)))

;; this for prevent tsserver from triggering when temp files appears in project
;; turn off lock files
(setq create-lockfiles nil)
;; placing all files in one directory
(setq backup-directory-alist
      `((".*" ., temporary-file-directory)))
(setq auto-save-file-name-transforms
      `((".*", temporary-file-directory t)))

(eval-after-load 'web-mode
  '(add-hook 'web-mode-hook #'add-node-modules-path))

(eval-after-load 'typescript-mode
  '(add-hook 'typescript-mode-hook #'add-node-modules-path))

;; tide
;; this snippet from tide's repository
(defun setup-tide-mode ()
  (interactive)
  (tide-setup)
  (flycheck-mode +1)
  (tide-hl-identifier-mode +1)
)

(add-hook 'typescript-mode-hook #'setup-tide-mode)

The problem dissapear if remove (flycheck-mode +1) from init.el or if add (setq-default flycheck-disabled-checkers '(typescript-tslint)) to end of init.el file.

@fmdkdd

This comment has been minimized.

Copy link
Member

fmdkdd commented Jun 1, 2018

Thank you for the report. We do care about performance, but we seldom get the chance of stress-testing Flycheck like your project seems to do.

It looks like tslint is the culprit here. I can see that tide sets up tslint as its :next-checker, and that's why disabling tslint is sufficient to make the problem go away.

Although I don't yet understand why tslint taking a long time to report errors would prevent tide from doing its highlighting. When you are waiting for 30-90s, does Emacs respond at all? Can you move your cursor or invoke a command with M-x, or does it hang completely?

I would also be interested to know how long it takes to call tslint directly in the terminal, outside Emacs.

Finally, please share a profiler report by doing M-x profiler-start, reproduce the hang like above, then M-x profiler-report and M-x profiler-report-write-profile. You want a CPU profile report, not a memory one.

cc @Simplify

@kreedz

This comment has been minimized.

Copy link
Author

kreedz commented Jun 1, 2018

@fmdkdd
Everything next I've just tested on Windows machine.

When you are waiting for 30-90s, does Emacs respond at all? Can you move your cursor or invoke a command with M-x, or does it hang completely?

Emacs does respond almost all the time before variable will be highlighted (I can move cursor).
But sometimes last 2-10 seconds of that "waiting" time before variable will be highlighted it can completely freeze, so neither C-g helps nor M-x works. That "sometimes" happens sometimes (hard to reproduce what exactly is cause) when I jump to definition by M-. and immediately jump back by M-, and then placing pointer at imported variable.

I would also be interested to know how long it takes to call tslint directly in the terminal, outside Emacs.

It takes one second if I lint one file by next command:

node_modules/tslint/bin/tslint -c tslint.json  --format json filePath/someFileName.ts

And it takes two minutes if I lint entire project with:

node_modules/tslint/bin/tslint -c tslint.json --format json --project tsconfig.json

If it can help, I've noticed that nodejs process became 30-40% loaded in my "waiting" time.

Finally, please share a profiler report

I've reproduced the hang by typed some random symbols at new line and then moved pointer to imported variable:


[profiler-profile "24.3" cpu #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8 data ([completion-basic-try-completion "#<compiled 0xcf5bef>" completion--some completion--nth-completion completion-try-completion execute-extended-command--shorter execute-extended-command funcall-interactively call-interactively command-execute nil nil nil nil nil nil] 9 [completion-pcm--all-completions completion-pcm--find-all-completions completion-pcm-try-completion "#<compiled 0xcf5bef>" completion--some completion--nth-completion completion-try-completion execute-extended-command--shorter execute-extended-command funcall-interactively call-interactively command-execute nil nil nil nil] 5 [completion-pcm--string->pattern completion-pcm--find-all-completions completion-pcm-try-completion "#<compiled 0x1a3c4bf>" completion--some completion--nth-completion completion-try-completion execute-extended-command--shorter execute-extended-command funcall-interactively call-interactively command-execute nil nil nil nil] 1 ["#<compiled 0x195eca9>" execute-extended-command funcall-interactively call-interactively command-execute nil nil nil nil nil nil nil nil nil nil nil] 1 [Automatic\ GC] 1)) (23313 18627 673849 100000) nil]

Same report in gist

@Simplify

This comment has been minimized.

Copy link
Member

Simplify commented Jun 10, 2018

Hi, sorry about delay, had to find some free time to look at this issue. I was not sure that tslint is the problem here, because that particular file in vscode had no tslint errors or warnings, so parsing of JSON is not the issue. Also, I had no more than 2 seconds delay on that file in vscode project on macOS. Is that 10, 30-90 seconds only on Windows? Or 30 on linux, 90 on windows?

The problem is this commit and it should probably be reverted if @fmdkdd and @cpitclaudel agree. It makes more problems than it solves.

Tide will start tsserver when opening first ts file in project. Tsserver will load temporally files that Flycheck tslint checker makes and unload them when flycheck deletes them. It appears that is not possible to use any additional tide functionality while tsserver loads/unloads files and , and that includes M-. (M-, appears to work always). That is the reason that when you first time open vscode/src/vs/base/browser/ui/progressbar/progressbar.ts that it takes few seconds to be able to jump to definition first time.

When going to definition, flycheck will also check newly opened file, with new temp file created. When you go back with M-,, checking is still active, and until it finishes, you can't jump to another file.

@kreedz In GH-1446 I found this from @fmdkdd and it can be placed into you emacs init files:

(eval-after-load 'flycheck
   '(setcar (memq 'source-inplace (flycheck-checker-get 'typescript-tslint 'command)) 'source-original)) 

That helps a lot and you can use it until PR is reverted. Can you check it out and see if it works for you too?

@fmdkdd

This comment has been minimized.

Copy link
Member

fmdkdd commented Jun 10, 2018

I'm sure @cpitclaudel will be happy about reverting the source-inplace. I'm in favor of it if, as you say, it isn't worth the trouble.

When going to definition, flycheck will also check newly opened file, with new temp file created. When you go back with M-,, checking is still active, and until it finishes, you can't jump to another file.

I don't follow why jumping around with tide would be hindred by flycheck doing its thing.

@cpitclaudel

This comment has been minimized.

Copy link
Member

cpitclaudel commented Jun 10, 2018

I don't follow why jumping around with tide would be hindred by flycheck doing its thing.

Possible explanation: the server is single-threaded, and when it detects a new file in the current folder it likely starts processing it, being unresponsible until it's done with that.

@cpitclaudel

This comment has been minimized.

Copy link
Member

cpitclaudel commented Jun 10, 2018

I'm sure @cpitclaudel will be happy about reverting the source-inplace. I'm in favor of it if, as you say, it isn't worth the trouble.

Do we have a ticket with the tslint people to support stdin?

@Simplify

This comment has been minimized.

Copy link
Member

Simplify commented Jun 10, 2018

Think so, there is also an PR related to stdin (mention in another issue here), but nothing is merged as yet.

@kreedz

This comment has been minimized.

Copy link
Author

kreedz commented Jun 11, 2018

@Simplify

Is that 10, 30-90 seconds only on Windows? Or 30 on linux, 90 on windows?

10 seconds I have on windows and 15 seconds on linux with vscode project.
Something like 1 minute I have on windows and 90s on linux with my working project.

I think it's because my computer with linux much weaker than another computer with windows.

Can you check it out and see if it works for you too?

It's much better, thank you, just tested on my weak linux machine on both projects and there is no delay for variable highlighting after jumping to definition forward and back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.