Yes, if accessing nodes, then there is a slowdown.
 
The result is what benchmark-run returns.
 
 # func  buff-size  widen                 narrowed                
------------------------------------------------------------------
      1  671 B      (0.22944 2 0.022735)  (0.520645 9 0.1100442)  
     11  7 KiB      (0.23176 3 0.038288)  (0.9340281 9 0.116293   
     31  20 KiB     (0.27746 3 0.039054)  (1.7671007 10 0.134515)
 
Also there were errors when running benchmark in the narrowed buffer:
Error muted by safe_call: (internal--syntax-propertize 1482) signaled (args-out-of-range 1 1872)
Error muted by safe_call: (internal--syntax-propertize 282) signaled (args-out-of-range 1 672)

 
Recipe:
1. emacs -Q
2. paste the code to the buffer
3. M-x python-ts-mode
4. put the cursor in the place of |
 
5. M-x eval-expression
   (require 'benchmark)
   (benchmark-run 200 (progn (insert "v")  (insert "=") (insert "f") (insert "(") (insert ")") (treesit-node-at (point)) (insert "\n") (font-lock-ensure) ))
6. M-x undo
 
For benchmark in narrowed state select the body of a function, starting from a documentation string
and M-x narrow-to-region.
 
To increase buffer size copy the whole function:
M-x eval-expression
(dotimes (_ 10) (yank))

 
Code:
class TempC:
    def func_call():
        """documentation
        """
        var1 = 3
        var2 = func(1, temp={'1':1, '2':2},
                    temp1=TempC([1], [3]), ab='83, 8',)
        var3= r'\n str'
        var4 = f'temp {TempC("1"+"3")}|{v + "mon" +v}and {func()}'
 
        |
 
        varb =832
        if varb:
            pass
        elif not varb is not None and varb == 3:
            varb = 38
        else:
            pass
 
        for i in range():
            print(i)
 
        def nested():
            class Nested(Tempc):
                def __init__(self):
                    self._init = True
            return Nested()
        return nested
 
 
 
 
 
 
 
 
30.12.2023, 23:23, "Yuan Fu" <casouri@gmail.com>:


 

 On Dec 30, 2023, at 8:21 AM, Denis Zubarev <dvzubarev@yandex.ru> wrote:
 
 > I pushed a fix and now it shouldn’t crash anymore. However, I’m yet not sure why at some point the buffer was widened. Is there any way to track who called widen?
  Thank you, It doesn't crash anymore.
  > So it seems working in a narrowed buffer would trigger a lot of back-and-fortch reparse. I wonder if it’s worth optimizing for (eg, use two parsers behind the scenes, one for widened buffer and one for narrowed buffer).
  I have performed a quite naive benchmark and haven't seen any significant slow down when inserting text in a narrowed buffer.


Right, when you type, since the only thing that access the parser is font-lock, which always widens the buffer, there’s no unnecessary reparse. If you invoke some function that access the parser while the buffer is narrowed, that’ll trigger a reparse, and the next time font-lock runs, it’ll widen and make the parser reparse the full buffer again.

Yuan