Closed
Bug 1361274
Opened 8 years ago
Closed 8 years ago
querySelectorAll should not call nsIDocument::FlushPendingLinkUpdates
Categories
(Core :: DOM: Core & HTML, defect)
Tracking
()
Tracking | Status | |
---|---|---|
firefox55 | --- | fixed |
People
(Reporter: smaug, Assigned: bzbarsky)
References
Details
Attachments
(1 file, 2 obsolete files)
10.28 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
-nsINode::QuerySelectorAll(nsAString const&, mozilla::ErrorResult&) 87.7% 1.8%
| +moz_xmalloc 1.8% 0.0%
| -nsCSSRuleProcessor::SelectorListMatches() 10.5% 0.0%
| | SelectorMatches( 3.5% 3.5%
| | +SelectorMatchesTree() 7.0% 3.5%
| -nsIDocument::FlushPendingLinkUpdates() 73.7% 0.0%
| | -mozilla::dom::Link::LinkState() const 71.9% 1.8%
| | | +PLDHashTable::Add(void const*) 1.8% 0.0%
| | | -mozilla::dom::HTMLAnchorElement::GetHrefURI() const 56.1% 0.0%
| | | | nsCOMPtr_base::begin_assignment() 1.8% 1.8%
| | | | -nsGenericHTMLElement::GetHrefURIForAnchors() const 54.4% 0.0%
| | | | | mozilla::net::nsStandardURL::Release() 1.8% 1.8%
| | | | | -nsGenericHTMLElement::GetURIAttr(nsIAtom*, nsIAtom*, nsIURI**) const 52.6% 1.8%
| | | | | | +NS_NewURI(nsIURI**, nsAString const&, char const*, nsIURI*, nsIIOService*) 33.3% 0.0%
| | | | | | +nsIContent::GetBaseURI(bool) const 14.0% 7.0%
| | | | | | nsIDocument::GetBaseURI(bool) const 3.5% 3.5%
| | | +mozilla::places::History::RegisterVisitedCallback(nsIURI*, mozilla::dom::Link*) 12.3% 1.8%
| | nsDocument::AddStyleRelevantLink(mozilla::dom::Link*) 1.7% 1.7%
Reporter | ||
Updated•8 years ago
|
Whiteboard: [qf]
![]() |
Assignee | |
Comment 1•8 years ago
|
||
Is the testcase basically inserting a bunch of links, then doing a querySelectoAll, then repeating that in a loop or something?
In any case, speeding up FlushPendingLinkUpdates is not trivial, because it has to do real work: get the attribute, parse the URI, etc, etc.
But why are we calling it from querySelectorAll at all? The only point of FlushPendingLinkUpdates, I believe, is so we can tell apart :link and :visited. But querySelectorAll treats all links as unvisited anyway. It's possible the current setup was created before we stopped matching :visited in querySelectorAll.
![]() |
Assignee | |
Updated•8 years ago
|
Summary: nsIDocument::FlushPendingLinkUpdates is rather slow → querySelectorAll should not call nsIDocument::FlushPendingLinkUpdates
![]() |
Assignee | |
Comment 2•8 years ago
|
||
Attachment #8863983 -
Flags: review?(bugs)
![]() |
Assignee | |
Updated•8 years ago
|
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Comment 3•8 years ago
|
||
Comment on attachment 8863983 [details] [diff] [review]
There's no need to update link :visited state when doing querySelectorAll, since querySelectorAll ignores that state anyway
>+ // TreeMatchContext constructor is to not call it all the time furing various
s/furing/during/
Reporter | ||
Comment 4•8 years ago
|
||
Comment on attachment 8863983 [details] [diff] [review]
There's no need to update link :visited state when doing querySelectorAll, since querySelectorAll ignores that state anyway
s/furing/during/
I guess change to nsComputedDOMStyle::UpdateCurrentStyleSources is ok, since
we don't flush link states anyhow before layout/style flushes.
And ElementRestyler::Restyle, nsCSSFrameConstructor::ResolveStyleContext etc. do link flushing.
But don't we need link flushing for :link to work?
I don't understand eNeverMatchVisited. That seems to be for the private browsing flag control.
Isn't eRelevantLinkUnvisited the key thing here? Am I confused here now?
Attachment #8863983 -
Flags: review?(bugs)
![]() |
Assignee | |
Comment 5•8 years ago
|
||
> I guess change to nsComputedDOMStyle::UpdateCurrentStyleSources is ok
Right, because computed style never depends on :visited state: it always pretends the link only matched the :link rules.
> But don't we need link flushing for :link to work?
I don't believe we do. Here's why, using HTMLAnchorElement as an example.
When it's first created, it calls the Link() constructor, which sets mLinkState to eLinkState_NotLink. At his point neither NS_EVENT_STATE_VISITED nor NS_EVENT_STATE_UNVISITED is set, which means neither :link nor :visited is set, which is correct.
If the "href" attribute is now set (and in fact any time it's modified or removed), we will call Link::ResetLinkState (from HTMLAnchorElement::SetAttr/UnsetAttr). ResetLinkState will always set mLinkState to defaultState, which is either eLinkState_Unvisited if we have an href attr or eLinkState_NotLink if we do not. It will also make the relevant UpdateState/UpdateLinkState calls on the element to set NS_EVENT_STATE_UNVISITED on it. So once the "href" attribute has been set, we'll be in NS_EVENT_STATE_UNVISITED and match :link. The only thing we're waiting on FlishPendingLinkStates for at that point is maybe switching us to NS_EVENT_STATE_VISITED.
This didn't use to be the case back when <a href="something not parseable as URI"> was not considered to match :link, which is why the current setup is perhaps more complicated than it should be...
> I don't understand eNeverMatchVisited.
Ah, good catch. This stuff could really use better documentation, which I will add. But the summary is that eNeverMatchVisited is a promise that mVisitedHandling will _always_ be eRelevantLinkUnvisited for this TreeMatchContext. And yes, eRelevantLinkUnvisited is the real key here.
Reporter | ||
Comment 6•8 years ago
|
||
Aha, didn't think (Un)SetAttr + ResetLinkState.
![]() |
Assignee | |
Comment 7•8 years ago
|
||
![]() |
Assignee | |
Updated•8 years ago
|
Attachment #8863983 -
Attachment is obsolete: true
![]() |
Assignee | |
Comment 8•8 years ago
|
||
![]() |
Assignee | |
Updated•8 years ago
|
Attachment #8864130 -
Attachment is obsolete: true
Reporter | ||
Comment 9•8 years ago
|
||
Comment on attachment 8864134 [details] [diff] [review]
With better comments and commit message
eNeverMatchVisited is still odd beast given how it just controls whether pb flag is checked.
Attachment #8864134 -
Flags: review+
Comment 10•8 years ago
|
||
Pushed by bzbarsky@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/06d436f9330d
There's no need to update link :visited state when doing querySelectorAll, since querySelectorAll ignores that state anyway. r=smaug
Comment 11•8 years ago
|
||
bugherder |
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
status-firefox55:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
Updated•3 years ago
|
Performance Impact: --- → ?
Whiteboard: [qf]
You need to log in
before you can comment on or make changes to this bug.
Description
•