We release our tool, Epload (short for emulating page load), that emulates the page load process for folks who are only interested in running network experiments while hoping to preserve authenticity of the page load process. Epload is built on top of WProf. Compared to browsers, Epload provides the following benefits.
Epload works as follows. It first records the dependency graph of a Web page while loading the page using our WProf tool. Then, it converts the logs output from the WProf tool to the dependency graph in the JSON format. Next, Epload replays the dependency graph. It walks through the dependency graph from the first activity, that is loading the root HTML. When it encounters a network activity, it makes request to the corresponding URL; when it encounters a computation activity, it waits for the same amount of time that computation takes (informed by the dependency graph). Every time when it completes an activity, it checks whether it should trigger dependent activities based on whether all activities that a dependent activity depends on are finished. It keeps walking through the dependency graph this way until all activities in the dependency graph have been visited.
Below, we focus on the replaying process of Epload. We provide hundreds of dependency graphs that we recorded (on a 2GHz Mac) to get started with. To record dependency graphs on your own, please refer to the WProf page and read the "Dependency graph" section below.
Epload source code (42.8KB; written based on node.js).
Be sure to download and install node.js before running Epload.
Our code depends on a node.js module, SPDY, which is a SPDY server.
Be sure to install it (npm spdy
) before running Epload.
The Epload code is under epload/emulator/
; the HTTP client is under epload/client_http/
; and the SPDY client is under epload/client_spdy/
which is implemented based on the SPDY/3 spec.
As an experimental tool, the SPDY client does not include the protocol negotiation phase.
To run the code, enter the Epload directory:
$ cd epload/emulatorThen, run the code
$ node run.js [protocol] [dependency graphs]
[protocol]
is either http
or spdy
.
[dependency graphs]
is the directory that stores the dependency graphs of Web page loads.
Epload will sequetially emulates Web page loads of which the dependency graphs are stored in this directory.
To test out Epload on your machine, type node run.js http tests
.
If you are able to see messages like ===== [loaded the i-th page] timestamp
, it means that Epload works correctly.
node run.js spdy tests
won't work, since our test server only enables HTTP, not SPDY. It requires rewriting hosts (to ones on which SPDY is enabled) in *.json files to test SPDY.Epload allows simple configurations to test out domain sharding, prioritization and server push strategies, and hypothetically varied computation.
This is done by configuring the options
variable in file run.js
.
domain_sharding_type
in the options
variable configures the type of domain sharding to use.
0
No domain sharding (a single TCP connection is used to fetch all the objects of a Web page).1
Domain sharding by full domain (one TCP connection per full domain).2
Domain sharding by top-level domain (one TCP connection per top-level domain).priority_type
in the options
variable configures the type of prioritization strategies to use.
0
No prioritization.1
Chrome's prioritization strategy (HTML > JS, CSS > others).2
Our prioritization strategy (Prioritizing by depth in a dependency graph).
When this prioritization strategy is used, the max and min of priority levels need to be configured.
priority_lmax
represents the highest priority (no less than zero); priority_lmin
represents the lowest priority (no more than seven).
priority_lmax
should be no more than priority_lmin
.
server_push_type
in the options
variable configures the type of server push to use.
0
No server push.1
Push everything.2
Push by depth in a dependency graph (used by us).
When this server push strategy is used, server_push_depth
that represents the depth to push needs to be configured.
We find that pushing depth 1 is good in balancing latency and pushed bytes.
3
Push by embedding level (used in mod_spdy).alpha
and beta
in the options
variable configure the length of each computation activity relative to the captured length.
A computation activity (e.g., evaluating a JavaScript) will take alpha
* original_time + beta
amount of time where original_time is the captured time that this activity spent.
alpha : 0.5
, for example, means that CPU speed is doubled.
To get started with Epload, we provide a few dependency graphs that we recorded. Below, we show steps to set up the dependency graphs and experiments.
host
and path
) in the dependency graphs and point them to the path that serves Web objects on the server.
host
and path
are fields of each child of the "objs"
field in the dependency graphs.
node run.js http path_to_graphs/58.com_/
and look for messages like ===== [loaded the i-th page] timestamp
SpdyDebugUseSpdyForNonSslConnections 3
to the spdy.conf
file under Apache's mods-available directory.
If other SPDY server is used, be sure to configure accordingly to use no-ssl SPDY and SPDY/3.
node run.js spdy path_to_graphs/58.com_/
and look for messages like ===== [loaded the i-th page] timestamp
=== [page load time] timestamp
(in milliseconds) messages, or time the run of Epload when initiating Epload using another script.
Here, we show an example of the dependency graph.
In this graph, we have two Web objects with ids r1
and r2
where r1
is the root HTML while r2
is a JavaScript.
Web object r2
is triggered 200 milliseconds after HTML parsing started, and therefore we say that loading r2
depends on parsing r1
.
{ "objs": [ { "id": "r1", "host": "wprof.cs.washington.edu", "path": "/spdy/tool/tests/obj_100K-1.js", "when_comp_start": 1, "download": { "id": "r1_d", "type": "download" }, "comps": [ { "id": "r1_c1", "type": "evalhtml", "time": 500 } ] }, { "id": "r2", "host": "wprof.cs.washington.edu", "path": "/spdy/tool/tests/obj_10K-1.js", "when_comp_start": -1, "download": { "id": "r2_d", "type": "download" }, "comps": [ { "id": "r2_c1", "type": "evaljs", "time": 1000 } ] } ], "deps": [ { "id": "dep1", "a1": "r1_c1", "a2": "r2_d", "time": 200 } ], "start_activity": "r1_d" }
Let's go through the fields in the json file that represents a dependency graph.
objs
Array of Web objects. Each element in the array has the following fields.
id
Id of this Web object.host
Domain of the Web server that hosts this Web object.path
Path on the Web server that this Web object is served.when_comp_start
Indicates when computation starts relative to when this Web object is loaded.
when_comp_start : 1
means that the first computation activity starts after the first chunk of the object is loaded.
when_comp_start : -1
means that the first computation activity starts after the whole object is loaded.
download
Object of the download activity of the Web object.
id
Id of the download activity.type
Type of the download activity. It is always download
here.comps
Array of computation activities of the Web object. Each element in the array has the following fields.
id
Id of the computation activity.type
Type of the computation activity. It represents one of parsing HTML, evaluating JavaScript or CSS.Time
Time in milliseconds that the computation activity takes.deps
Array of dependencies between pairs of Web objects. Each element in the array has the following fields.
id
Id of the dependency. Activity a2
depends on activity a1
.a1
Id of the depended activity.a2
Id of the dependent activity.time
Indicates when a2
can be triggered.
time : -1
means that a2
cannot start until a1
is completed;
otherwise it means that a2
cannot start until time
milliseconds after a1
started.
start_activity
The id of first activity to start with (i.e., downloading the root HTML).Dependency graphs can also be generated from our WProf tool. First, follow the instructions on the WProf page and make sure your Chromium can output WProf logs. Second, send us an email asking for the analysis code to generate dependency graphs from the WProf logs. The analysis code is beta and we will release it in the future.