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 parallel CSS parsing #20721
Comments
|
I'm interested in trying my hand at this, but I may be biting off more than I can handle. Would anyone be available for potential mentoring? |
|
I can try if you don't mind a bit of lag in potentially replying to questions in Servo issues (I get a lot of GitHub Servo and don't check so often, as it can be seen). But you can always catch me on irc ( |
|
@emilio Awesome, thank you! I'll contact you in a bit! |
|
@emilio Here's what I have so far. If the parsing of a stylesheet were moved off the script thread, we'd need a way to tell its document to fetch imported sheets on the event-loop. I can see that Gecko dispatches the import sheet load to the main thread, but it seems to me that this introduces a lot of complexity in Servo. Please correct me if I'm wrong and this is not in fact difficult to accomplish. I hope I'll have time to work on this on the weekend. @highfive assign me please. |
|
Hey @mandreyel! Thanks for your interest in working on this issue. It's now assigned to you! |
|
In order to initiate an action on a script thread from another thread, all that is necessary is:
Then the new variant needs to contain all of the data necessary to perform the action - that might be a PipelineId, which can be used to obtain a document, and a list of stylesheet URLs that need to be fetched. |
|
@jdm Ohhhh, that makes my life so much simpler! Thanks |
I don't think this is needed. This is needed in Gecko because import rules need to create C++'s What's the particularly complex part about it? I'd prefer if both Gecko and Servo were consistent on the approach, I don't particularly mind changing Gecko but that means carrying the offset in the source where the rest of the rules should start, and having a partial rule-list and so on which is not amazing. |
|
@emilio Apologies, I should have edited my post to say that the second paragraph is no longer relevant since jdm's suggestion revealed the first idea is in fact pretty straight forward to implement. |
|
Apologies, was swamped with shipping code at work, but I cooked up something on the weekend... It's mostly done, I think, but unfortunately import sheets are applied out-of-order. This is the specific test case that's failing:
Does Servo have some mechanisms in place to ensure correct stylesheet load order (since import sheet loads are already partly async)? |
|
So, fwiw that test is racy (shouldn't be using setTimeout to wait for network events). But yes, the Looks like with your changes we're not applying any of both? (if the first stylesheet was applying it'd show red instead of In any case, you should probably open a PR already so you can run the tests on automation instead of your machine, even if it's still a WIP :) |
|
@emilio Thanks for the info. I think the problem may have been that I verified the Ok, I'll open a PR in a moment :) |
[WIP] Implement parallel CSS parsing <!-- Please describe your changes on the following line: --> Opening for discussion. The basic idea is to spawn a parser thread on a global thread-pool (like in Gecko) with an `AsyncStylesheetLoader` (instead of the previous `StylesheetLoader`), used when encountering an `@import` rule to send a task to script thread from the parser thread, which simply instantiates an async fetch on the corresponding document. After the parsing is done, another task is sent to script thread to do the post-parsing steps, like setting the parsed stylesheet on its link element (if applicable), firing the load event, etc. A problem was that verifying the request generation id before parsing (still on the script thread) introduced a race condition, so I moved that to the post-parse task run on the script thread. This (seems to have) solved the race condition, but it differs in semantics from the sync parsing in that it's now no longer checked before doing the parsing, but after, which incurs an unnecessary parse overhead if the sheet is not applicable (I think). Also, there seems to be an occasional time-out in one of the CSS tests, and the code needs some cleaning up. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #20721 (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because existing CSS tests should cover them. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22478) <!-- Reviewable:end -->
|
Oh I had not read that comment. Yeah the request_generation_id check needs to be on script and after parsing. Glad that fixed it :) |
[WIP] Implement parallel CSS parsing <!-- Please describe your changes on the following line: --> Opening for discussion. The basic idea is to spawn a parser thread on a global thread-pool (like in Gecko) with an `ThreadSafeStylesheetLoader` (instead of the previous `StylesheetLoader`), used when encountering an `@import` rule to send a task to script thread from the parser thread, which simply instantiates an async fetch on the corresponding document. After the parsing is done, another task is sent to script thread to do the post-parsing steps, like setting the parsed stylesheet on its link element (if applicable), firing the load event, etc. A problem was that verifying the request generation id before parsing (still on the script thread) introduced a race condition, so I moved that to the post-parse task run on the script thread. This (seems to have) solved the race condition, but it differs in semantics from the sync parsing in that it's now no longer checked before doing the parsing, but after, which incurs an unnecessary parse overhead if the sheet is not applicable (I think). Also, there seems to be an occasional time-out in one of the CSS tests, and the code needs some cleaning up. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #20721 (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because existing CSS tests should cover them. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22478) <!-- Reviewable:end -->
[WIP] Implement parallel CSS parsing <!-- Please describe your changes on the following line: --> Opening for discussion. The basic idea is to spawn a parser thread on a global thread-pool (like in Gecko) with an `ThreadSafeStylesheetLoader` (instead of the previous `StylesheetLoader`), used when encountering an `@import` rule to send a task to script thread from the parser thread, which simply instantiates an async fetch on the corresponding document. After the parsing is done, another task is sent to script thread to do the post-parsing steps, like setting the parsed stylesheet on its link element (if applicable), firing the load event, etc. A problem was that verifying the request generation id before parsing (still on the script thread) introduced a race condition, so I moved that to the post-parse task run on the script thread. This (seems to have) solved the race condition, but it differs in semantics from the sync parsing in that it's now no longer checked before doing the parsing, but after, which incurs an unnecessary parse overhead if the sheet is not applicable (I think). Also, there seems to be an occasional time-out in one of the CSS tests, and the code needs some cleaning up. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #20721 (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because existing CSS tests should cover them. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22478) <!-- Reviewable:end -->
[WIP] Implement parallel CSS parsing <!-- Please describe your changes on the following line: --> Opening for discussion. The basic idea is to spawn a parser thread on a global thread-pool (like in Gecko) with an `ThreadSafeStylesheetLoader` (instead of the previous `StylesheetLoader`), used when encountering an `@import` rule to send a task to script thread from the parser thread, which simply instantiates an async fetch on the corresponding document. After the parsing is done, another task is sent to script thread to do the post-parsing steps, like setting the parsed stylesheet on its link element (if applicable), firing the load event, etc. A problem was that verifying the request generation id before parsing (still on the script thread) introduced a race condition, so I moved that to the post-parse task run on the script thread. This (seems to have) solved the race condition, but it differs in semantics from the sync parsing in that it's now no longer checked before doing the parsing, but after, which incurs an unnecessary parse overhead if the sheet is not applicable (I think). Also, there seems to be an occasional time-out in one of the CSS tests, and the code needs some cleaning up. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #20721 (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [X] These changes do not require tests because existing CSS tests should cover them. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22478) <!-- Reviewable:end -->
Firefox did this in https://bugzilla.mozilla.org/show_bug.cgi?id=1346988 and https://bugzilla.mozilla.org/show_bug.cgi?id=1455115; we should look into doing the same for Servo.