Closed
Bug 146373
Opened 23 years ago
Closed 18 years ago
100% CPU while JavaScript modifies page (loooong wait)
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
RESOLVED
INCOMPLETE
People
(Reporter: virkkila, Unassigned)
References
()
Details
(Keywords: perf)
Attachments
(2 files, 1 obsolete file)
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0rc2) Gecko/20020510
BuildID: 2002051009
If I surf to the url posted above, there is a list of classes, and you can
toggle wich you want to look at by clicking on of the checkboxes on or off.
Doing this will however freeze the entire browser (and mail if it's open). It
will eventually un-freeze (melt?) and start working as usual, but I had to wait
at least 30s for this to happen. The window is not updating nor recieving any
events (typical freeze).
The fact that nothing gets updated (no painting is done etc.) will leave you
thinking your browser froze for good, and you are more likely to kill the
process and start mozilla up again than to actually wait for it to "start
working again".
Reproducible: Always
Steps to Reproduce:
1.Surf to http://www.go-mono.com/class-status-corlib.html
2.Click on "Missing" checkbox
3.Try using the browser, moving it around, having a window over it.
Actual Results: The window contents are empty, or not redrawn. It will not
respond to anything. It is basically frozen/it hangs (for a while).
Expected Results: The browser should remain responsive, do the painting, and
maybe the statusbar should say Processing javascript, please wait, which should
be interrupted it by clicking stop.
Comment 1•23 years ago
|
||
Confirming bug with Mozilla trunk binary 2002061707 on WinNT.
OS: Linux ---> All. My CPU is pinned at 100% for a good 10 seconds
when I click on the "Missing" checkbox. In IE6, only 4 seconds;
Note: NN4.7 chokes badly on loading this site; don't try it!
The culprit: this page contains many <div> elements which may contain
many other <div> elements, which contain others... They all get updated
on the checkbox click, by a function which calls itself recursively
to walk the tree of <divs>. I have indicated the recursion below:
function viewAll (elt, dictTypes)
{
var fView = false;
var rgImages = getChildrenByTagName (elt, 'IMG');
var cImages = rgImages.length;
for (var iImage = 0; iImage < cImages; iImage++)
{
var strImage = trimSrc (rgImages [iImage].src);
if (dictTypes [strImage])
{
fView = true;
break;
}
}
var rgElts = getChildrenByTagName (elt, 'DIV');
var cElts = rgElts.length;
if (cElts != 0)
{
var iElt;
for (iElt = 0; iElt < cElts; iElt ++)
fView |= viewAll (rgElts [iElt], dictTypes); <<<<<<<<<<<<<<< RECURSION
}
elt.style.display = fView ? '' : 'none';
return fView;
}
I do not know if the performance problem is the fault of the JS Engine
not handling the recursion well, or is due to the DOM access that occurs
during each call. In the JS Debugger, I saw the recursion go 5 levels deep !!!
I'm going to guess DOM and reassign there; please reassign back
if this is incorrect and we have a pure JS Engine performance issue -
Assignee: rogerl → jst
Component: JavaScript Engine → DOM Level 0
Keywords: perf
OS: Linux → All
QA Contact: pschwartau → desale
Summary: Javascript freezes program while it's modifying page (loooong wait) → 100% CPU while JavaScript modifies page (loooong wait)
Updated•23 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment 2•23 years ago
|
||
Here is some profiling data from the Mozilla JS Debugger. I loaded
the site, turned on profiling, and clicked the "Missing" checkbox.
The first function called from the click handler is selectMissing(),
and we see it took 12.5 seconds to complete.
We can also see the 5 levels of recursion attained by the viewAll()
function. But the bulk of the time is taken up within this function
by calls to the function getChildrenByTagName(). We see that a total
of 9.96 seconds out of the 12.5 seconds is spent doing that:
clickHandler() calls 1, total 0ms, min 0ms, max 0ms,
avg 0ms
selectMissing() calls 1, total 12500ms, min 12500ms, max 12500ms,
avg 12500ms
toggleFilter() calls 1, total 12500ms, min 12500ms, max 12500ms,
avg 12500ms
filterTree() calls 1, total 12485ms, min 12485ms, max 12485ms,
avg 12485ms
viewAll() calls 1606 (depth 5), total 12469ms, min 12469ms,
max 12469ms, avg 7.76ms
trimSrc() calls 4176, total 520ms, min 0ms, max 16ms,
avg 0.12ms
getChildrenByTagName() calls 3212, total 9961ms, min 16ms, max 94ms,
avg 3.1ms
Here it is:
function getChildrenByTagName (elt, strTag)
{
strTag = strTag.toLowerCase ();
var rgChildren = new Array ();
var eltChild = elt.firstChild;
while (eltChild)
{
if (eltChild.tagName && eltChild.tagName.toLowerCase() == strTag)
rgChildren.push (eltChild);
eltChild = eltChild.nextSibling;
}
return rgChildren;
}
So it seems to boil down to this. What is taking all the time?
Is it the JS Engine functionality, or the DOM property access
on |elt.firstChild|, |eltChild.tagName|, |eltChild.nextSibling|?
Comment 3•23 years ago
|
||
I believe jst will tell you that it is the firstChild/nextSibling accesses which
are much slower than accessing them via the childNodes array.
Comment 4•23 years ago
|
||
Bob's right, but there's more to this perf problem than the way the DOM tree is
traversed...
Comment 5•23 years ago
|
||
quantified on win2k.
Seems thread syncronize waste a lot time?
Comment 6•23 years ago
|
||
We only care about what happens on the main thread in cases like this (in 99+%
of them at least) so when running Quantify, please filter out everything that
doesn't run on the main thread. That'll get rid of all the thread
synchronisation fluff that some of the necko threads spend lots of time in and
better show what gecko really does.
Comment 7•23 years ago
|
||
Only quantify the main thread,
the topest cpu eaters are:
js_Invoke()/js_Interpret()/js_InternalInvoke()/js_GetProperty() 99%
nsCOMPtr_base::assign_from_helper() 46%
nsCOMPtr_base::~nsCOMPtr_base() 19%
XPTC_InvokeByIndex() 13%
Attachment #91217 -
Attachment is obsolete: true
Comment 8•23 years ago
|
||
From that data...
F+D % Calls F % Function
100.00 0 0.00 .main_0.
98.79 129306 0.07 js_Invoke
98.79 175 0.13 js_Interpret
98.77 89973 0.02 js_InternalInvoke
98.71 5 0.00 JS_CallFunctionValue
89.85 216078 0.10 js_GetProperty
45.53 2199747 28.60 nsCOMPtr_base::assign_from_helper(...)
19.15 4617587 8.34 nsCOMPtr_base::~nsCOMPtr_base(void)
12.80 60170 5.75 XPTC_InvokeByIndex
9.46 1012759 0.04 JS_RemoveRootRT
9.43 1012759 0.09 js_RemoveRoot
9.10 2210473 7.10 PR_Lock
7.74 1012663 0.04 JS_AddNamedRootRT
7.70 1012749 0.12 js_AddRootRT
7.37 2210473 5.89 PR_Unlock
6.01 20112 0.01 js_SetProperty
2.64 136606 1.02 malloc
2.44 2250698 0.55 JS_DHashTableOperate
2.26 5011630 2.26 TlsGetValue
2.15 183801 2.15 HeapAlloc
2.13 113022 0.01 JS_malloc
1.79 1083203 0.09 JS_DHashTableRawRemove
1.70 2174572 1.70 nsQueryInterface::nsQueryInterface(nsQueryInterface const&)
1.70 1105530 1.70 memset
1.70 1083203 0.04 JS_DHashClearEntryStub
1.48 95923 0.16 nsHashtable::Get(nsHashKey *)
1.46 267755 0.09 js_LookupProperty
1.44 9 0.00 JS_MaybeGC
1.44 5 0.03 js_GC
1.44 5 0.00 js_ForceGC
1.44 5 0.00 JS_GC
1.40 43042 0.02 js_NewObject
1.25 8188 0.69 nsStaticCaseInsensitiveNameTable::Lookup(nsACString const&)
1.12 2174572 1.12 nsQueryInterface::nsQueryInterface(nsISupports *,UINT *)
1.09 103246 0.02 js_AllocGCThing
1.05 29832 0.00 js_ValueToObject
1.05 29832 0.00 js_ValueToNonNullObject
1.04 29832 0.00 js_StringToObject
1.01 46743 0.48 new(UINT)
... nothing really interesting there, we execute a *lot* of JS, and that's where
we spend most of the time, the fact that we spend a lot of time in the nsCOMPtr
destructor and constructor (indirectly) suggests that this data was gathered
using a 1.0 branch build, right? A trunk build should not spend nearly as much
time in the nsCOMPtr code while executing JS...
Comment 9•23 years ago
|
||
Yes, you are right. I am using a 1.0 release. I do not know what happen
in xpcom of trunk.
I will to gather data from trunk then.
Comment 10•23 years ago
|
||
I have quantified trunk on solaris 8. It seems there is no particular
hot point. The cpu time is distributed among a lot of functions.
This is the quantified result. All 0.00% stuff is removed in the list.
Comment 12•19 years ago
|
||
The url is not there anymore.
Comment 13•18 years ago
|
||
Duplicate of bug 112858 – simple but lengthy Javascript document.write loop hangs the complete browser.
Comment 14•18 years ago
|
||
comment 8 and the end of comment 9 suggest, I think, that trunk either had no problem, or at least no obvious room for improvement. Reporter comments "cause was due to slow dom updating/walking, rather than a document.write. However since there is no testcase, and no useful data, ..."
so I'm closing incomplete
Status: NEW → RESOLVED
Closed: 18 years ago
Resolution: --- → INCOMPLETE
You need to log in
before you can comment on or make changes to this bug.
Description
•