mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +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,
|
||||
fetch_target: IpcSender<FetchResponseMsg>) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use app_units::Au;
|
|||
use bluetooth_traits::BluetoothRequest;
|
||||
use cssparser::Parser;
|
||||
use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarkerType};
|
||||
use document_loader::LoadType;
|
||||
use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, DocumentReadyState};
|
||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||
|
@ -43,7 +42,7 @@ use dom::location::Location;
|
|||
use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec};
|
||||
use dom::messageevent::MessageEvent;
|
||||
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::promise::Promise;
|
||||
use dom::screen::Screen;
|
||||
|
@ -58,14 +57,12 @@ use js::jsapi::{HandleObject, HandleValue, JSAutoCompartment, JSContext};
|
|||
use js::jsapi::{JS_GC, JS_GetRuntime};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::Runtime;
|
||||
use layout_image::fetch_image_for_layout;
|
||||
use msg::constellation_msg::{FrameType, PipelineId};
|
||||
use net_traits::{FetchResponseMsg, NetworkError};
|
||||
use net_traits::{ResourceThreads, ReferrerPolicy, FetchResponseListener, FetchMetadata};
|
||||
use net_traits::{ResourceThreads, ReferrerPolicy};
|
||||
use net_traits::image_cache_thread::{ImageResponder, ImageResponse};
|
||||
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 network_listener::{NetworkListener, PreInvoke};
|
||||
use num_traits::ToPrimitive;
|
||||
use open;
|
||||
use profile_traits::mem::ProfilerChan as MemProfilerChan;
|
||||
|
@ -1894,69 +1891,3 @@ impl Runnable for PostMessageHandler {
|
|||
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]
|
||||
mod dom;
|
||||
pub mod fetch;
|
||||
mod layout_image;
|
||||
pub mod layout_wrapper;
|
||||
mod mem;
|
||||
mod microtask;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue