Reviewers:
CL:
https://codereview.chromium.org/2172613002/Message:
lizeb, mattcary, pasko: FYI this is what I'm experimenting with for prefetching
on the renderer side.
Description:
NoStatePrefetch early prototype
The background HTML parser collects the URLs to preload and
sends them to the HTMLDocumentParser.
The HTMLDocumentParser makes the actual requests, and drops
everything else on the floor, preventing the actual
construction and execution of the page.
Uses the PageVisibilityState to control this behavior.
Base URL:
https://chromium.googlesource.com/chromium/src.git@masterAffected files (+23, -1 lines):
M third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
Index: third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
index 7908a5d662ad1803203fed61efc3a9c9597b5b0d..2e6feabc100063ac8055497b35f64622fc31df0e 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -296,10 +296,14 @@ void HTMLDocumentParser::notifyPendingParsedChunks()
if (!isParsing())
return;
+ bool isPrefetch =
+ document()->pageVisibilityState() == PageVisibilityStatePrerender;
+
// ApplicationCache needs to be initialized before issuing preloads.
// We suspend preload until HTMLHTMLElement is inserted and
// ApplicationCache is initialized.
- if (!document()->documentElement()) {
+ // Prefetching never initializes AppCache: is this a problem?
+ if (!isPrefetch && !document()->documentElement()) {
for (auto& chunk : pendingChunks) {
for (auto& request : chunk->preloads)
m_queuedPreloads.append(std::move(request));
@@ -319,9 +323,14 @@ void HTMLDocumentParser::notifyPendingParsedChunks()
// document.write script evaluation takes place. Preloading these
// scripts is valuable and comparably cheap, while evaluating JS can be
// expensive.
+ printf("------------------------------------------\n");
+ printf("HTMLDocumentParser:\n");
for (auto& chunk : pendingChunks) {
+ for (const auto& request : chunk->preloads)
+ printf("%s\n", request->resourceURL().ascii().data());
m_preloader->takeAndPreload(chunk->preloads);
}
+ printf("------------------------------------------\n");
for (auto& chunk : pendingChunks) {
for (auto& index : chunk->likelyDocumentWriteScriptIndices) {
const CompactHTMLToken& token = chunk->tokens->at(index);
@@ -334,6 +343,19 @@ void HTMLDocumentParser::notifyPendingParsedChunks()
for (auto& chunk : pendingChunks)
m_speculations.append(std::move(chunk));
+ if (isPrefetch) {
+ // Do nothing, but tell the background parser that we processed
+ // everything.
+ while (!m_speculations.isEmpty()) {
+ std::unique_ptr<ParsedChunk> speculation =
+ m_speculations.takeFirst();
+ postTaskToLookaheadParser(
+ Asynchronous, &BackgroundHTMLParser::startedChunkWithCheckpoint,
+ m_backgroundParser, speculation->inputCheckpoint);
+ }
+ return;
+ }
+
if (!isWaitingForScripts() && !isScheduledForResume()) {
if (m_tasksWereSuspended)
m_parserScheduler->forceResumeAfterYield();