From f7df8046304cf1ca8f1512d49e34b2255c3a1818 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 20 Jan 2017 15:25:24 +0100 Subject: [PATCH 1/5] Simplify the processing of asap scripts --- components/script/dom/document.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 65f106192bd..604fe0e16a5 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -229,7 +229,7 @@ pub struct Document { /// https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-in-order-as-soon-as-possible asap_in_order_scripts_list: PendingInOrderScriptVec, /// https://html.spec.whatwg.org/multipage/#set-of-scripts-that-will-execute-as-soon-as-possible - asap_scripts_set: DOMRefCell>, + asap_scripts_set: DOMRefCell>>, /// https://html.spec.whatwg.org/multipage/#concept-n-noscript /// True if scripting is enabled for all scripts in this document scripting_enabled: Cell, @@ -1549,7 +1549,7 @@ impl Document { if let LoadType::Script(_) = load { self.process_deferred_scripts(); - self.process_asap_scripts(); + self.process_asap_scripts_in_order(); } if let Some(parser) = self.get_current_parser() { @@ -1601,16 +1601,18 @@ impl Document { } pub fn add_asap_script(&self, script: &HTMLScriptElement) { - self.asap_scripts_set.borrow_mut().push_back(PendingScript::new(script)); + self.asap_scripts_set.borrow_mut().push(JS::from_ref(script)); } /// https://html.spec.whatwg.org/multipage/#the-end step 3. /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d. pub fn asap_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { - let mut scripts = self.asap_scripts_set.borrow_mut(); - let idx = scripts.iter().position(|entry| &*entry.element == element).unwrap(); - scripts.swap(0, idx); - scripts[0].loaded(result); + { + let mut scripts = self.asap_scripts_set.borrow_mut(); + let idx = scripts.iter().position(|entry| &**entry == element).unwrap(); + scripts.swap_remove(idx); + } + element.execute(result); } pub fn push_asap_in_order_script(&self, script: &HTMLScriptElement) { @@ -1625,12 +1627,7 @@ impl Document { self.asap_in_order_scripts_list.loaded(element, result); } - fn process_asap_scripts(&self) { - let pair = self.asap_scripts_set.borrow_mut().front_mut().and_then(PendingScript::take_result); - if let Some((element, result)) = pair { - self.asap_scripts_set.borrow_mut().pop_front(); - element.execute(result); - } + fn process_asap_scripts_in_order(&self) { while let Some((element, result)) = self.asap_in_order_scripts_list.take_next_ready_to_be_executed() { element.execute(result); } From 9912721f06c54163e8acf0cbf1cf18109915927e Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 20 Jan 2017 15:35:22 +0100 Subject: [PATCH 2/5] Simplify processing of asap scripts in order --- components/script/dom/document.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 604fe0e16a5..8e55ad2f6fe 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1549,7 +1549,6 @@ impl Document { if let LoadType::Script(_) = load { self.process_deferred_scripts(); - self.process_asap_scripts_in_order(); } if let Some(parser) = self.get_current_parser() { @@ -1625,9 +1624,6 @@ impl Document { element: &HTMLScriptElement, result: ScriptResult) { self.asap_in_order_scripts_list.loaded(element, result); - } - - fn process_asap_scripts_in_order(&self) { while let Some((element, result)) = self.asap_in_order_scripts_list.take_next_ready_to_be_executed() { element.execute(result); } From 1bf0db5537e200019222d9008611a07126445f89 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 20 Jan 2017 16:03:59 +0100 Subject: [PATCH 3/5] Process deferred scripts less often Only do it from finish_load when a stylesheet finished loading, and from deferred_script_loaded directly. --- components/script/dom/document.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 8e55ad2f6fe..08f08b9a2fb 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1547,7 +1547,7 @@ impl Document { loader.finish_load(&load); } - if let LoadType::Script(_) = load { + if let LoadType::Stylesheet(_) = load { self.process_deferred_scripts(); } @@ -1636,6 +1636,7 @@ impl Document { /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d. pub fn deferred_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { self.deferred_scripts.loaded(element, result); + self.process_deferred_scripts(); } /// https://html.spec.whatwg.org/multipage/#the-end step 3. From abdb390da80883d9ca02258cefcb82b7657a818c Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 20 Jan 2017 16:29:43 +0100 Subject: [PATCH 4/5] Simplify processing of pending parsing-blocking scripts This is done outside of finish_load in a more straightforward way now. --- components/script/dom/document.rs | 46 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 08f08b9a2fb..e0ce7577ade 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1549,26 +1549,7 @@ impl Document { if let LoadType::Stylesheet(_) = load { self.process_deferred_scripts(); - } - - if let Some(parser) = self.get_current_parser() { - let ready_to_be_executed = match self.pending_parsing_blocking_script.borrow_mut().as_mut() { - Some(pending) => { - if self.script_blocking_stylesheets_count.get() > 0 { - return; - } - if let Some(pair) = pending.take_result() { - Some(pair) - } else { - return; - } - }, - None => None, - }; - if let Some((element, result)) = ready_to_be_executed { - *self.pending_parsing_blocking_script.borrow_mut() = None; - parser.resume_with_pending_parsing_blocking_script(&element, result); - } + self.process_pending_parsing_blocking_script(); } if !self.loader.borrow().is_blocked() && !self.loader.borrow().events_inhibited() { @@ -1593,10 +1574,27 @@ impl Document { /// https://html.spec.whatwg.org/multipage/#prepare-a-script step 22.d. pub fn pending_parsing_blocking_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { - let mut blocking_script = self.pending_parsing_blocking_script.borrow_mut(); - let entry = blocking_script.as_mut().unwrap(); - assert!(&*entry.element == element); - entry.loaded(result); + { + let mut blocking_script = self.pending_parsing_blocking_script.borrow_mut(); + let entry = blocking_script.as_mut().unwrap(); + assert!(&*entry.element == element); + entry.loaded(result); + } + self.process_pending_parsing_blocking_script(); + } + + fn process_pending_parsing_blocking_script(&self) { + if self.script_blocking_stylesheets_count.get() > 0 { + return; + } + let pair = self.pending_parsing_blocking_script + .borrow_mut() + .as_mut() + .and_then(PendingScript::take_result); + if let Some((element, result)) = pair { + *self.pending_parsing_blocking_script.borrow_mut() = None; + self.get_current_parser().unwrap().resume_with_pending_parsing_blocking_script(&element, result); + } } pub fn add_asap_script(&self, script: &HTMLScriptElement) { From e9feb2077579b8f8c3bcafb9f4d301175f0fc805 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 20 Jan 2017 16:41:49 +0100 Subject: [PATCH 5/5] Simplify processing of deferred scripts It is now done on-demand when a deferred script finished loading, and when the page source finished loading. --- components/script/dom/document.rs | 14 ++++++++++---- components/script/dom/servoparser/mod.rs | 3 +-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index e0ce7577ade..c1f4d056894 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1547,9 +1547,15 @@ impl Document { loader.finish_load(&load); } - if let LoadType::Stylesheet(_) = load { - self.process_deferred_scripts(); - self.process_pending_parsing_blocking_script(); + match load { + LoadType::Stylesheet(_) => { + self.process_deferred_scripts(); + self.process_pending_parsing_blocking_script(); + }, + LoadType::PageSource(_) => { + self.process_deferred_scripts(); + }, + _ => {}, } if !self.loader.borrow().is_blocked() && !self.loader.borrow().events_inhibited() { @@ -1638,7 +1644,7 @@ impl Document { } /// https://html.spec.whatwg.org/multipage/#the-end step 3. - pub fn process_deferred_scripts(&self) { + fn process_deferred_scripts(&self) { if self.ready_state.get() != DocumentReadyState::Interactive { return; } diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index 30a5c5948a2..b75fd7352c5 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -359,9 +359,8 @@ impl ServoParser { window.reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::FirstLoad); } - // Steps 3-12 are in other castles, namely process_deferred_scripts and finish_load. + // Steps 3-12 are in another castle, namely finish_load. let url = self.tokenizer.borrow().url().clone(); - self.document.process_deferred_scripts(); self.document.finish_load(LoadType::PageSource(url)); } }