mooz / js2-mode

Improved JavaScript editing mode for GNU Emacs
GNU General Public License v3.0
1.33k stars 186 forks source link

js2-mode very slow with large files #163

Open ghost opened 9 years ago

ghost commented 9 years ago

js2-mode very slow with large files compared with js-mode or js3-mode, the same file run much fast in js3-mode,

when write function test(){} exist one delay of 3 or 4 second before appear () and others 3 second before appear {}

I thought it was 'js2-mode-show-parse-errors or js2-mode-show-strict-warnings' but disabling and still slow.

I have byte-compile js2-mode (I install from package emacs)

dgutov commented 9 years ago

Can you give an example file?

tamzinblake commented 9 years ago

I'm extremely skeptical that there is a case where js3-mode is faster than js2-mode.

ghost commented 9 years ago

the file with the problem is private but send a file with the same amount of lines.

the original file is slower than test.js but test.js can see a delay compared to js3-mode

http://pastebin.com/S1AgmCvQ

dgutov commented 9 years ago

Indeed, I also see the difference. This test file takes about 500ms to parse in js2-mode, and about 200ms in js3-mode.

It could be a bug on either side (I don't know yet), but probably is a result of the latest changes in the js2-mode parser, which made token stream rewindable, among other things (to support parsing arrow functions). It my testing on open source libs like jQuery, the resulting slowdown was around 20-30%, but I guess there are pathological cases, and this could be one of them.

tamzinblake commented 9 years ago

Is the js2-mode parser still following Rhino? Has Rhino updated in the same way such that you could see if the same slowdown happens in different versions of Rhino? If so it's a Rhino issue and you can have them fix it.

dgutov commented 9 years ago

Nope, it's trying to follow SpiderMonkey directly. Rhino still doesn't support arrow functions (there's a pull request for that, but it's feature-incomplete) and other new ES6 syntax.

Even if it did, parsing probably doesn't constitute the same kind of bottleneck in C++ and Java that we have here in ELisp. So even a 100% regression would be less of a deal if it was required for an important feature.

kevinushey commented 9 years ago

I'm finding something similar -- the insertion time for closing brackets (e.g. ), }, ]) is very slow in large files. In my case, I am trying to edit vim.js, which is a large-ish file (~6k lines) but it appears insertion of closing brackets anywhere in the document causes Emacs to hang for 2-3 seconds.

dgutov commented 9 years ago

@kevinushey Is that with bare Emacs configuration?

vim.js takes 1.6 to parse here, but paren insertion, where I tried it, doesn't take nearly as much (still gives a small pause, though).

kevinushey commented 9 years ago

Sorry to perform some necromancy here...

It looks like the thing that was causing me grief was really the syntax / error checking; Emacs is essentially frozen while (what I assume is) js2-mode checks for warnings / errors.

A 'fix' for me is to delay syntax checking a little bit more:

(setq js2-idle-timer-delay 2)

This ensures (at least for me) any syntax checking js2 wants to do will occur while I really am 'idle' and so the pauses become less perceptible. However, each parse does indeed take some time (~2 seconds).

(I should add -- the syntax / error / 'no symbol names x in scope' checker is incredibly useful and has saved me untold hours of grief; but I wonder if there's other configuration available that could speed this up. Thanks for all the awesome work on js2-mode!)

dgutov commented 9 years ago

It looks like the thing that was causing me grief was really the syntax / error checking

It's the parser. It performs error checking as well.

but I wonder if there's other configuration available that could speed this up

Try (setq blink-matching-paren nil), maybe?

stormpat commented 8 years ago

Hi!

First of thanks for js2-mode, its amazing and i use it daily.

I have too noticed mayor slowdowns when dealing with large .js files (> 2000-3000 lines) and sometimes my Emacs is almost unusable. So bumping this issue for any updates/solutions for dealing with larger files?

vietor commented 5 years ago

Always slow in large file

In my case (window-nt), i was found a solution:

(setq inhibit-compacting-font-caches t)
Y0ngg4n commented 1 month ago

Sorry for doing necro again here but i started the profiler and tried to figure out what is going on. I can say. My Emacs is really unusable with large files. The workaround from @kevinushey helped a little bit. Here is the profiler output of pressing o for making a new line in evil-mode then hitting escape and pressing o again multiple times. Sometimes this new-line operation takes 2 seconds.

                                                                 73,537,184  77% - ...
                                                                 73,481,920  76%  - js2-parse-named-prop
                                                                 73,481,920  76%   - let
                                                                 73,481,920  76%    - cond
                                                                 73,481,920  76%     - let
                                                                 73,481,920  76%      - js2-parse-plain-property
                                                                 73,481,920  76%       - let*
                                                                 73,481,920  76%        - cond
                                                                 73,481,920  76%         - if
                                                                 73,481,920  76%          - progn
                                                                 73,481,920  76%           - setq
                                                                 73,481,920  76%            - js2-parse-assign-expr
                                                                 73,481,920  76%             - let
                                                                 73,250,736  76%              - if
                                                                 73,250,736  76%               - progn
                                                                 73,250,736  76%                - setq
                                                                 73,249,680  76%                 - js2-parse-cond-expr
                                                                 73,249,680  76%                  - let
                                                                 73,249,680  76%                   - js2-parse-nullish-coalescing-expr
                                                                 73,249,680  76%                    - let
                                                                 73,249,680  76%                     - js2-parse-or-expr
                                                                 73,249,680  76%                      - let
                                                                 72,993,072  76%                       - js2-parse-and-expr
                                                                 72,992,016  76%                        - let
                                                                 72,575,952  76%                         - js2-parse-bit-or-expr
                                                                 72,572,784  76%                          - let
                                                                 71,890,608  75%                           - js2-parse-bit-xor-expr
                                                                 71,741,712  75%                            - let
                                                                 71,024,688  74%                             - js2-parse-bit-and-expr
                                                                 70,899,024  74%                              - let
                                                                 70,197,840  73%                               - js2-parse-eq-expr
                                                                 69,951,792  73%                                - let
                                                                 43,915,361  45%                                 - js2-parse-rel-expr
                                                                 43,505,633  45%                                  - let
                                                                 42,291,553  44%                                   - js2-parse-shift-expr
                                                                 41,887,105  43%                                    - let
                                                                 41,488,993  43%                                     - js2-parse-add-expr
                                                                 41,050,753  42%                                      - let
                                                                 36,379,009  38%                                       + while
                                                                  4,671,744   4%                                       + js2-parse-mul-expr
                                                                    398,112   0%                                     + while
                                                                  1,214,080   1%                                   + while
                                                                 26,036,431  27%                                 + while
                                                                    701,184   0%                               + while
                                                                    717,024   0%                             + while
                                                                    682,176   0%                           + while
                                                                    416,064   0%                         + if
                                                                    256,608   0%                       + if
                                                                      1,056   0%                 + js2-get-token
                                                                    231,184   0%              + js2-get-token
                                                                     35,320   0%  + #<lambda 0x192a5a71453b9ba1>
                                                                      8,552   0%  + lsp--request-cleanup-hooks
                                                                      2,584   0%  + #<lambda 0x192a5a7145388de1>
                                                                      2,584   0%  + #<lambda 0x192a5a714538aba1>
                                                                      2,584   0%  + #<lambda 0x192a5a71453bd721>
                                                                      2,584   0%  + #<lambda 0x192a5a71453bbde1>
                                                                      1,056   0%  + lsp-diagnostics--flycheck-report
                                                                 12,560,172  13% + command-execute
                                                                  6,733,099   7% + redisplay_internal (C function)
                                                                  1,501,531   1% + #<lambda 0x1efa86b8a8b2a7a1>
                                                                    425,544   0% + lsp-ui-doc--make-request
                                                                    379,565   0% + timer-event-handler
                                                                    191,948   0% + evil-normal-post-command
                                                                     38,912   0% + evil-escape-pre-command-hook
                                                                     38,432   0% + winner-save-old-configurations
                                                                     29,328   0% + emojify-update-visible-emojis-background-after-command
                                                                     18,400   0% + lsp-ui-sideline
                                                                      8,768   0% + lsp--post-command
                                                                      6,800   0% + gcmh-register-idle-gc
                                                                      2,160   0%   flycheck-maybe-display-error-at-point-soon
                                                                      1,056   0% + yas--post-command-handler
                                                                         88   0%   mouse--click-1-maybe-follows-link
dgutov commented 1 month ago

@Y0ngg4n That's pretty much unavoidable given the current implementation method.

But since you're using lsp-mode, you can try switching to js-ts-mode instead. The value-add from js2-mode should mostly be covered by LSP features (though probably not entirely).

Y0ngg4n commented 1 month ago

@dgutov thank you