Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upImplement Rule Hash for Selector Matching. #1167
Conversation
+ Add index fields in Rule for parent StyleRule and parent Stylesheet to break ties while cascading. Sorting by (specificity, stylesheet index, rule index) removes the need to use stable sorts.
highfive
commented
Nov 1, 2013
|
Thanks for the pull request, and welcome! The Servo team is excited to review your changes, and you should hear from @jdm (or someone else) soon. |
|
Wow, this looks very cool. Tagging @SimonSapin to dig into it! |
|
So the rule/sheet index fields need to get updated when the CSSOM is modified (sheets are added/removed, rules are added/removed, etc), right? |
|
@bzbarsky
The sheet itself is not being stored in Stylist. So, I don't see how changes in the stylesheet (addition / removal of Rules) are being communicated to Stylist. So, when these modification operations are supported, we can update the indexes accordingly. The indexes only need to be monotonically increasing - they don't have to be continuous. |
|
So inserting a <style> element not at the end of the page is not supported right now? |
|
Right; my real question is how this approach scales to having to reindex. Is the data structure that needs to be reindexed a persistent one, or recreated on CSSOM modifications? |
|
@bzbarsky The data structure that needs to be reindexed (SelectorMap) is persistent. It doesn't have to be recreated. When a new rule is inserted, we will have to update the indexes of the rules which come after it. I think it is a trade-off between having fast selector matching and being able to handle dynamic style quickly. If we could get some representative numbers regarding the frequency and extent of dynamic style modifications, then we could make a better decision. So, please advise as to the best way to move forward in this situation. Also, there is a penalty even in the approach currently used in master branch: Having a stable-sorted list of all rules. This will also have trouble scaling to having to reindex. Example: Stylesheet foo having rules rule1, rule2, rule3 in decreasing order of
We would need to refer to the original list and do extra work to calculate the correct position in the sorted list. |
|
For what it's worth, Gecko completely recreates its RuleHash when you insert rules or sheets (lazily, of course). So chances are, the reindexing operation on insertions should be OK, as long as it's no worse than O(N) in number of sheets/rules. |
|
@bzbarsky Yeah, it will be O(N) in number of rules. So I can implement that when we have dynamic style working. What other changes should I make as of now? |
|
Some general notes that shouldn't necessarily block this from landing:
|
Both the insertion key for rules having a LocalNameSelector and the lookup-key sent in get_all_matching_rules should be ASCII lower case.
|
It's not clear whether it's enough matched rules or what. Just have the profile data, not the breakdown of what the lists look like. But I suspect that the "universal rule" bucket is pretty big on some sites.
Now it's wrong for SVG elements. What you probably want is to add both the lowercased and the non-lowercased (if they're different) versions of the tag name to the hashtable and then make sure during matching itself to use the right one. You should not be doing any lowercasing of element localNames. |
|
@bzbarsky I don't think support for SVG elements is implemented yet.
for LocalNameSelector. Currently, to handle LocalNameSelector, we do
in So, to implement the current functionality and not regress, I need to handle element names and element selectors case-insensitively in SelectorMap. |
|
I just saw this, sorry for the delays in replying. We do not implement CSSOM at all at the moment. Doing so will requires non-trivial refactoring, since the current code does not keep Stylesheet objects around after parsing. However adding a We also do not have any notion of quirks mode / standards mode, HTML / XML elements / documents, or namespaces. I wonder if we should do these before adding many optimizations, as they (in particular dynamic stylesheet changes) may affect the rest in non-trivial ways. |
Yeah :) That's what I was telling him
Ok. I guess it would probably be good to implement the dynamic stylesheet changes before going in for parallelization and other further optimizations, because then it might be non-trivial to modify. As far as Rule Hash goes, I think it is a standard sequential optimization and we would want to support it anyway, so we should probably do dynamic stylesheet changes after this. Your thoughts? |
|
+1. After landing this, we can continue to sequential optimization and prepare further optimization for parallelization |
|
Rule hash is a standard optimization technique that all major web browser engines such as Webkit implement, and I also think that we should have similar technique. Given the incompleteness of Servo, and CSS selector matching still being developed, how about we integrate rule hash first, and then incrementally develop/optimize it as the above mentioned features such as quirks mode, namespaces, dynamic updates, etc are developed rather than waiting for and/or developing all the required features? |
|
The point is, the devil is in the details. The exact way you actually set up the hashtable and how you use it really depends on how you implements those other features. There's no problem with landing this, as long as all the various buggy parts are clearly marked, with issues tracking them getting fixed filed. |
|
Discussed in person and I'm fine with landing this with a few allocation optimizations. |
Also, use stack-allocated vector for fixed-length vector instead of allocating on the heap.
Cleanup the querySelector{,All} tests; r=MikeSmith+jgraham
pradeep90 commentedNov 1, 2013
Sorting by (specificity, stylesheet index, rule index) removes the need to use stable sorts.