mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Extract layout image request into separate file. Do not block the document load event.
This commit is contained in:
parent
0d2ec852ac
commit
b363371339
4 changed files with 92 additions and 72 deletions
|
@ -116,6 +116,13 @@ impl DocumentLoader {
|
||||||
request: RequestInit,
|
request: RequestInit,
|
||||||
fetch_target: IpcSender<FetchResponseMsg>) {
|
fetch_target: IpcSender<FetchResponseMsg>) {
|
||||||
self.add_blocking_load(load);
|
self.add_blocking_load(load);
|
||||||
|
self.fetch_async_background(request, fetch_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initiate a new fetch that does not block the document load event.
|
||||||
|
pub fn fetch_async_background(&mut self,
|
||||||
|
request: RequestInit,
|
||||||
|
fetch_target: IpcSender<FetchResponseMsg>) {
|
||||||
self.resource_threads.sender().send(CoreResourceMsg::Fetch(request, fetch_target)).unwrap();
|
self.resource_threads.sender().send(CoreResourceMsg::Fetch(request, fetch_target)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use app_units::Au;
|
||||||
use bluetooth_traits::BluetoothRequest;
|
use bluetooth_traits::BluetoothRequest;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
|
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
|
||||||
use document_loader::LoadType;
|
|
||||||
use dom::bindings::cell::DOMRefCell;
|
use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
|
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
|
||||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||||
|
@ -43,7 +42,7 @@ use dom::location::Location;
|
||||||
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
|
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
|
||||||
use dom::messageevent::MessageEvent;
|
use dom::messageevent::MessageEvent;
|
||||||
use dom::navigator::Navigator;
|
use dom::navigator::Navigator;
|
||||||
use dom::node::{Node, from_untrusted_node_address, window_from_node, document_from_node, NodeDamage};
|
use dom::node::{Node, from_untrusted_node_address, window_from_node, NodeDamage};
|
||||||
use dom::performance::Performance;
|
use dom::performance::Performance;
|
||||||
use dom::promise::Promise;
|
use dom::promise::Promise;
|
||||||
use dom::screen::Screen;
|
use dom::screen::Screen;
|
||||||
|
@ -58,14 +57,12 @@ use js::jsapi::{HandleObject, HandleValue, JSAutoCompartment, JSContext};
|
||||||
use js::jsapi::{JS_GC, JS_GetRuntime};
|
use js::jsapi::{JS_GC, JS_GetRuntime};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::Runtime;
|
use js::rust::Runtime;
|
||||||
|
use layout_image::fetch_image_for_layout;
|
||||||
use msg::constellation_msg::{FrameType, PipelineId};
|
use msg::constellation_msg::{FrameType, PipelineId};
|
||||||
use net_traits::{FetchResponseMsg, NetworkError};
|
use net_traits::{ResourceThreads, ReferrerPolicy};
|
||||||
use net_traits::{ResourceThreads, ReferrerPolicy, FetchResponseListener, FetchMetadata};
|
|
||||||
use net_traits::image_cache_thread::{ImageResponder, ImageResponse};
|
use net_traits::image_cache_thread::{ImageResponder, ImageResponse};
|
||||||
use net_traits::image_cache_thread::{PendingImageResponse, ImageCacheThread, PendingImageId};
|
use net_traits::image_cache_thread::{PendingImageResponse, ImageCacheThread, PendingImageId};
|
||||||
use net_traits::request::{Type as RequestType, RequestInit as FetchRequestInit};
|
|
||||||
use net_traits::storage_thread::StorageType;
|
use net_traits::storage_thread::StorageType;
|
||||||
use network_listener::{NetworkListener, PreInvoke};
|
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use open;
|
use open;
|
||||||
use profile_traits::mem::ProfilerChan as MemProfilerChan;
|
use profile_traits::mem::ProfilerChan as MemProfilerChan;
|
||||||
|
@ -1894,69 +1891,3 @@ impl Runnable for PostMessageHandler {
|
||||||
message.handle());
|
message.handle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LayoutImageContext {
|
|
||||||
node: Trusted<Node>,
|
|
||||||
id: PendingImageId,
|
|
||||||
url: ServoUrl,
|
|
||||||
cache: ImageCacheThread,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FetchResponseListener for LayoutImageContext {
|
|
||||||
fn process_request_body(&mut self) {}
|
|
||||||
fn process_request_eof(&mut self) {}
|
|
||||||
fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
|
|
||||||
self.cache.notify_pending_response(
|
|
||||||
self.id,
|
|
||||||
FetchResponseMsg::ProcessResponse(metadata));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process_response_chunk(&mut self, payload: Vec<u8>) {
|
|
||||||
self.cache.notify_pending_response(
|
|
||||||
self.id,
|
|
||||||
FetchResponseMsg::ProcessResponseChunk(payload));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process_response_eof(&mut self, response: Result<(), NetworkError>) {
|
|
||||||
let node = self.node.root();
|
|
||||||
let document = document_from_node(&*node);
|
|
||||||
self.cache.notify_pending_response(self.id,
|
|
||||||
FetchResponseMsg::ProcessResponseEOF(response));
|
|
||||||
document.finish_load(LoadType::Image(self.url.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PreInvoke for LayoutImageContext {}
|
|
||||||
|
|
||||||
fn fetch_image_for_layout(url: ServoUrl, node: &Node, id: PendingImageId, cache: ImageCacheThread) {
|
|
||||||
let context = Arc::new(Mutex::new(LayoutImageContext {
|
|
||||||
node: Trusted::new(node),
|
|
||||||
id: id,
|
|
||||||
url: url.clone(),
|
|
||||||
cache: cache,
|
|
||||||
}));
|
|
||||||
|
|
||||||
let document = document_from_node(node);
|
|
||||||
let window = window_from_node(node);
|
|
||||||
|
|
||||||
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
|
||||||
let listener = NetworkListener {
|
|
||||||
context: context,
|
|
||||||
task_source: window.networking_task_source(),
|
|
||||||
wrapper: Some(window.get_runnable_wrapper()),
|
|
||||||
};
|
|
||||||
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
|
||||||
listener.notify_fetch(message.to().unwrap());
|
|
||||||
});
|
|
||||||
|
|
||||||
let request = FetchRequestInit {
|
|
||||||
url: url.clone(),
|
|
||||||
origin: document.url().clone(),
|
|
||||||
type_: RequestType::Image,
|
|
||||||
pipeline_id: Some(document.global().pipeline_id()),
|
|
||||||
.. FetchRequestInit::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
//XXXjdm should not block load event
|
|
||||||
document.fetch_async(LoadType::Image(url), request, action_sender);
|
|
||||||
}
|
|
||||||
|
|
81
components/script/layout_image.rs
Normal file
81
components/script/layout_image.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Infrastructure to initiate network requests for images needed by the layout
|
||||||
|
//! thread. The script thread needs to be responsible for them because there's
|
||||||
|
//! no guarantee that the responsible nodes will still exist in the future if the
|
||||||
|
//! layout thread holds on to them during asynchronous operations.
|
||||||
|
|
||||||
|
use dom::bindings::reflector::DomObject;
|
||||||
|
use dom::node::{Node, document_from_node};
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use ipc_channel::router::ROUTER;
|
||||||
|
use net_traits::{FetchResponseMsg, FetchResponseListener, FetchMetadata, NetworkError};
|
||||||
|
use net_traits::image_cache_thread::{ImageCacheThread, PendingImageId};
|
||||||
|
use net_traits::request::{Type as RequestType, RequestInit as FetchRequestInit};
|
||||||
|
use network_listener::{NetworkListener, PreInvoke};
|
||||||
|
use servo_url::ServoUrl;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
struct LayoutImageContext {
|
||||||
|
id: PendingImageId,
|
||||||
|
cache: ImageCacheThread,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FetchResponseListener for LayoutImageContext {
|
||||||
|
fn process_request_body(&mut self) {}
|
||||||
|
fn process_request_eof(&mut self) {}
|
||||||
|
fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) {
|
||||||
|
self.cache.notify_pending_response(
|
||||||
|
self.id,
|
||||||
|
FetchResponseMsg::ProcessResponse(metadata));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_response_chunk(&mut self, payload: Vec<u8>) {
|
||||||
|
self.cache.notify_pending_response(
|
||||||
|
self.id,
|
||||||
|
FetchResponseMsg::ProcessResponseChunk(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_response_eof(&mut self, response: Result<(), NetworkError>) {
|
||||||
|
self.cache.notify_pending_response(self.id,
|
||||||
|
FetchResponseMsg::ProcessResponseEOF(response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PreInvoke for LayoutImageContext {}
|
||||||
|
|
||||||
|
pub fn fetch_image_for_layout(url: ServoUrl,
|
||||||
|
node: &Node,
|
||||||
|
id: PendingImageId,
|
||||||
|
cache: ImageCacheThread) {
|
||||||
|
let context = Arc::new(Mutex::new(LayoutImageContext {
|
||||||
|
id: id,
|
||||||
|
cache: cache,
|
||||||
|
}));
|
||||||
|
|
||||||
|
let document = document_from_node(node);
|
||||||
|
let window = document.window();
|
||||||
|
|
||||||
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
|
let listener = NetworkListener {
|
||||||
|
context: context,
|
||||||
|
task_source: window.networking_task_source(),
|
||||||
|
wrapper: Some(window.get_runnable_wrapper()),
|
||||||
|
};
|
||||||
|
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||||
|
listener.notify_fetch(message.to().unwrap());
|
||||||
|
});
|
||||||
|
|
||||||
|
let request = FetchRequestInit {
|
||||||
|
url: url,
|
||||||
|
origin: document.url().clone(),
|
||||||
|
type_: RequestType::Image,
|
||||||
|
pipeline_id: Some(document.global().pipeline_id()),
|
||||||
|
.. FetchRequestInit::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Layout image loads do not delay the document load event.
|
||||||
|
document.mut_loader().fetch_async_background(request, action_sender);
|
||||||
|
}
|
|
@ -110,6 +110,7 @@ pub mod document_loader;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod dom;
|
mod dom;
|
||||||
pub mod fetch;
|
pub mod fetch;
|
||||||
|
mod layout_image;
|
||||||
pub mod layout_wrapper;
|
pub mod layout_wrapper;
|
||||||
mod mem;
|
mod mem;
|
||||||
mod microtask;
|
mod microtask;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue