This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 63488 - [matching] Noticable delays when editing long HTML
Summary: [matching] Noticable delays when editing long HTML
Status: RESOLVED FIXED
Alias: None
Product: web
Classification: Unclassified
Component: HTML Editor (show other bugs)
Version: 5.x
Hardware: PC Windows XP
: P3 blocker (vote)
Assignee: Marek Fukala
URL:
Keywords: PERFORMANCE
Depends on:
Blocks:
 
Reported: 2005-09-01 09:55 UTC by Jiri Kovalsky
Modified: 2009-05-18 10:47 UTC (History)
8 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
HTML file reproducing the performance problem. (119.49 KB, text/html)
2005-09-01 09:56 UTC, Jiri Kovalsky
Details
Briefly tested diff of ExtCaret.java implementing RP.Task. (5.81 KB, application/octet-stream)
2006-09-08 09:37 UTC, Miloslav Metelka
Details
Profiling results (root methods HTML.tagName() and HTML.resolve()) (39.37 KB, application/octet-stream)
2007-06-29 10:54 UTC, Tomasz Slota
Details
The problem #2 fix attempt source patch (2.59 KB, text/plain)
2007-06-29 15:06 UTC, Marek Fukala
Details
Profiling results after applying the patch (8.02 KB, application/octet-stream)
2007-06-29 16:07 UTC, Tomasz Slota
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jiri Kovalsky 2005-09-01 09:55:48 UTC
Development build #200508311800 of NetBeans 4.2
Windows XP, JDK 1.5.0_05 build #02

Description:
============
User must be extra patient when editing long XML based files. There is a certain
usecase described below causing editor to hang for some time every two seconds
and CPU consumption reaches ~100%.

Steps to reproduce:
===================
1. Create new sample web application project.
2. Save attached HTML in the project and open it.
3. At last line 772 type </ and press & hold e.g. A key.
4. You should observe significant delays after a while occuring after every ~2
seconds.
Comment 1 Jiri Kovalsky 2005-09-01 09:56:53 UTC
Created attachment 24442 [details]
HTML file reproducing the performance problem.
Comment 2 Jiri Kovalsky 2005-09-01 09:58:28 UTC
This is performance degradation issue.
Comment 3 Marek Fukala 2005-09-01 10:31:18 UTC
As I have mentioned in Issue #55541, I cannot improve the find matching block
mechanism much. The problem is caused by the missing end tag. If you write a tag
then after each keystroke a matching tag is searched. Because of there isn't any
matching endtag the entire document is searched which is time consuming
especially for big files. 

What I can do is to filter out some of these keystrokes if they come very
quickly.  So the find of the matching block will be called for example after
500ms delay when no new keystroke comes. 

As soon as we have and implementation of DocumentModelProvider for HTML tags I
can rewrite the matching to be based on the model. Then there will be no delays
at all since I always know exact locations of all the tags.
Comment 4 Marek Fukala 2005-11-30 14:37:36 UTC
Currently the SyntaxSupport.findMatchingBlock(...) is called synchronously from
EDT on each keystroke and hence cause performance problems when the call takes
longer time (HTML/JSP/XML - see described usecase). 

I am attaching a simple patch for editor/lib module which causes the SS.fmb()
method to be called asynchronously after an amount of time (the same behaviour
as when you change the carret offset in the editor). I am reassigning the issue
to Mila Metelka for review of the patch (I am not sure whether the synchronous
call is necessary by another part of editor code - from the user perspective
everything works the same as before in java, htmls, ...). 

If the patch is OK please integrate or reassign back to me. Thanks.
Comment 5 Petr Jiricka 2006-08-16 14:25:27 UTC
I don't see any patch. Mila, do you know exactly what's the requested improvement?

Tomasz or Marek, do you know whether the behavior has changed in any way in
NetBeans 5.5? Thanks.
Comment 6 Miloslav Metelka 2006-08-17 11:07:29 UTC
I understand the logic of not doing the complex computation synchronously.
However IMHO just the re-posting later into event queue would not help as there
would be the same amount of work to be performed.

I've looked again into ExtCaret implementation and originally there was a timer
for matching the braces with 100ms timeout but later there was a
matchBraceUpdateSync added for key typed events. If XML would override the
ExtCaret in the following way:

    public void requestMatchBraceUpdateSync() {
        matchBraceUpdateSync = false;
    }

and create the overriden caret in XMLKit.createCaret() then this solution would
imho fix the problem in most effective way.
Comment 7 Petr Jiricka 2006-08-17 12:28:32 UTC
Tomasz, can you please look at this? Thanks.
Comment 8 Tomasz Slota 2006-09-04 10:48:12 UTC
the issue is still reproducible
Comment 9 Tomasz Slota 2006-09-04 14:18:12 UTC
I used the hint from jlahoda to make calls to findMatchingBlock(), asynchronous and it seems to help. 
However a new thread is created each time the caret is moved and the threads work in parallel; when the 
user is typing fast the CPU is blocked.

The solution could be to post the task to a custom RequestProcessor with capacity of one thread, probably 
with some timeout. 
Comment 10 Tomasz Slota 2006-09-04 14:23:14 UTC
sorry, not jlahoda's, but mmetelka's hint
Comment 11 Petr Nejedly 2006-09-04 15:18:24 UTC
Notice that RP.Task is Cancellable.
if you implement the runnable properly, you can easily push the interruption
through the stack back to your code.

Also, don't .post() the runnable, .schedule precreated Task, it would
automatically cancel any pending (not yet running) requests so you won't end up
with 10 of them in the RP queue.

Comment 12 Miloslav Metelka 2006-09-05 09:18:08 UTC
OK, I'll modify ExtCaret to use the RP.Task. tslota do you plan to merge this
fix into 5.5? I'm asking because cancelling of the task will interrupt the
thread which is IMHO a bit sensitive and also the whole computation will now be
done outside of the AWT - anyway I expect that no deadlocks or other problems
should occur with changing this.
Comment 13 Tomasz Slota 2006-09-07 09:42:19 UTC
mmetelka: let's try it on a local build first, if the the improvement is very visible and we don't see any 
issues with it it should go to 'release55'.
Comment 14 Miloslav Metelka 2006-09-08 09:37:45 UTC
Created attachment 33710 [details]
Briefly tested diff of ExtCaret.java implementing RP.Task.
Comment 15 Tomasz Slota 2006-09-11 09:44:02 UTC
Found another sub-problem: there are multiple, concurrent threads of folding manager created when the 
user is typing the closing tag. mfukala is fixing it
Comment 16 Tomasz Slota 2006-09-11 13:01:39 UTC
Fixed. Editing attached HTML still feels somewhat sluggish, but the problem described was solved and 
it is much better now. See also issue 84598.

Change log:

Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java;
/cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v  <--  ExtCaret.java
new revision: 1.39.34.2.2.2; previous revision: 1.39.34.2.2.1
done
Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java;
/cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v  <--  HTMLKit.java
new revision: 1.9.8.2.2.4; previous revision: 1.9.8.2.2.3
done
Comment 17 Andrei Badea 2006-10-11 14:34:43 UTC
The fix will be ported to trunk as part of the merge of release55_dev.
Comment 18 Miloslav Metelka 2006-10-13 14:20:58 UTC
Unfortunately this fix is causing a serious P1 issue #86661 so I have to
rollback it both in release55_dev and release55.
 We may possibly leave it in the trunk for some time to see whether the fix of
#85000 will possibly make any difference to the symptoms of #86661 but
personally I don't think so.
Comment 19 Miloslav Metelka 2006-10-16 13:18:22 UTC
Rollback in release55_dev:
Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java;
/cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v  <--  ExtCaret.java
new revision: 1.39.34.2.2.2.2.1; previous revision: 1.39.34.2.2.2
done
Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java;
/cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v  <-- 
HTMLKit.java
new revision: 1.9.8.2.2.4.2.1; previous revision: 1.9.8.2.2.4


Rollback in release55:
Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java;
/cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v  <--  ExtCaret.java
new revision: 1.39.34.2.2.3; previous revision: 1.39.34.2.2.2
done
Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java;
/cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v  <-- 
HTMLKit.java
new revision: 1.9.8.2.2.5; previous revision: 1.9.8.2.2.4
Comment 20 Miloslav Metelka 2006-10-22 21:50:01 UTC
Rollback in trunk due to possible cause of issue #87598:
Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java;
/cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v  <--  ExtCaret.java
new revision: 1.46; previous revision: 1.45
done
Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java;
/cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v  <-- 
HTMLKit.java
new revision: 1.17; previous revision: 1.16
Comment 21 Tomasz Slota 2007-04-13 14:35:35 UTC
I was hoping this issue could have been fixed by "lexerization" of the HTML editor, unfortunately it seems 
to have gotten worse. Also opening and scrolling attached file feels unacceptably sluggish, it wasn't an 
issue before. Upgrading to P2
Comment 22 Tomasz Slota 2007-06-29 09:23:12 UTC
I've profiled the HTML editor module and figured out that when scrolling more than 90% of CPU time is spent in the HTML.tagName() method
Comment 23 Tomasz Slota 2007-06-29 09:51:15 UTC
While HTML.tagName() is most expensive in the AWT thread, it is also worth to take a look at HTML.resolve(), which is a very expensive method in the Parser 
thread.

The biggest source of load in HTML.tagName() is TokenSequence.movePrevious() - 84%.
Comment 24 Marek Fukala 2007-06-29 10:09:41 UTC
Can you please attach the profiler results? It is not easy to determine what can be wrong without it.
Comment 25 Tomasz Slota 2007-06-29 10:54:26 UTC
Created attachment 44561 [details]
Profiling results (root methods HTML.tagName() and HTML.resolve())
Comment 26 Marek Fukala 2007-06-29 12:58:30 UTC
The first problem is cause by the error checking layer trying to check if an attribute or tag is deprecated. There is a
call for each token and the call is extremely costly. Resolution: a.the method must be fastened + b.the highlight layer
should be cached. Vito,is #b currently implemented? 

The second problem is that after some time when the edited document is modified the Schlieman parser is run and once the
parse is done, an AST evaluator is called. The AST evaluation (HTML.resolve()) is very very slow and creates a huge
number of new objects. The original design of this comes from Hanz, I'll try fix this by myself somehow or to reassign
to him.

Rassigning the issue to myself for now to address the problems.
Comment 27 Marek Fukala 2007-06-29 13:35:30 UTC
#1 fixed

Checking in HTML.java;
/cvs/html/editor/src/org/netbeans/modules/html/editor/HTML.java,v  <--  HTML.java
new revision: 1.8; previous revision: 1.7
done
Comment 28 Marek Fukala 2007-06-29 14:51:11 UTC
resolution of #2 should be based on changing the way how the parse tree is resolved. For those who are not familiar with
the mechanism - the parse tree resolvation creates from the plain parse tree from parser an AST containing hierarchical
information about tags nesting, evaluates which tags are unbalanced, empty etc. During this process the old tree stays
untouched and a new one is created by modifying and cloning its nodes. All nodes, even those which stays untouched in
the new tree, are cloned with all its children. This seems to be superfluous to me, supposing that noone ever changes
the given parse tree, the untouched nodes can be referenced directly IMHO. I'll try to change it this way.
Comment 29 Marek Fukala 2007-06-29 15:05:11 UTC
Tome, could be please so nice and try the attached patch for #2 with the profiler? I do not know what exactly you did in
the editor when creating the cpu data so it will be more precise. Also please update to check fix of #1. Thank you!
Comment 30 Marek Fukala 2007-06-29 15:06:47 UTC
Created attachment 44573 [details]
The problem #2 fix attempt source patch
Comment 31 Tomasz Slota 2007-06-29 16:07:42 UTC
Created attachment 44575 [details]
Profiling results after applying the patch
Comment 32 Tomasz Slota 2007-06-29 16:24:15 UTC
The patch helps a bit, but performance is still unacceptable. It improved greatly when I commented out the HTML.isDeprecatedTag() method.
Comment 33 Marek Fukala 2007-06-29 17:13:37 UTC
I am sorry the previous fix was erroneous, this time it works (I checked it). So update uncomment isDeprecatedTag and
enjoy :-)

Checking in HTML.java;
/cvs/html/editor/src/org/netbeans/modules/html/editor/HTML.java,v  <--  HTML.java
new revision: 1.9; previous revision: 1.8
done

Though the fix should help a lot, there are some more findings:

I tested it a little and find out that the problem is in the missing highlight layer chaching. The HTML.isDT() is called
each time a token is going to repaint. So during scrolling of big html document it leads to large number of calls to
this method without caching. 

Hanz still uses the old DrawLayers instead of the HiglightsLayer which is cached I belive. So either
MyFirst/SecondDrawlayer from Schlieman needs to be cached or HighlightsLayer used.
Comment 34 Tomasz Slota 2007-07-02 12:31:11 UTC
After the last change the overall performance is already acceptable, following agreement with Marek I am leaving the issue open until #2 is also addressed.
Comment 35 Marek Fukala 2007-07-02 13:17:19 UTC
I already commited the fix for #2 in the last commit. So closing this issue as fixed.