12011-02-18 Tony Gentilcore <tonyg@chromium.org>
2
3 Reviewed by NOBODY (OOPS!).
4
5 Let the parser yield for layout before running scripts
6 https://bugs.webkit.org/show_bug.cgi?id=54355
7
8 Prior to this patch, the parser would yield to perform a layout/paint before running a
9 script only if the script or a stylesheet blocking the script is not loaded yet. Since we
10 don't preload scan into the body while parsing the head, typically we'll block on a script
11 early in the body that causes us to yield to do the first paint within a reasonable time.
12
13 However, I'm planning to change the PreloadScanner to scan into the body from the head.
14 That significantly improves overall load time, but would hurt first paint time because
15 fewer scripts would be blocked during parsing and thus wouldn't yield.
16
17 This change causes us to yield before running scripts if we haven't painted yet (regardless
18 of whether or not the script is loaded). In addition to allowing the above mentioned
19 PreloadScanner change to be implemented without regressing first paint time, this also
20 improves first paint time by itself.
21
22 I tested Alexa's top 45 websites using Web Page Replay to control the content and simulate
23 bandwidth. This patch improved average first paint time by 1% over an unlimited connection,
24 6% over a 1Mbps connection and 11% over a 5Mbps connection. There was no statistically
25 signifcant change in page load time.
26
27 Within the pages tested, 33 had no statistically significant change in time to first paint,
28 12 improved, and none regressed. Of the improved, some of the standouts from the 1Mbps set
29 are: 20% on youtube, 37% on wiki, 27% on ebay, 13% on cnn, 16% on espn, 74% on sohu.
30
31 * html/parser/HTMLDocumentParser.cpp:
32 (WebCore::HTMLDocumentParser::canTakeNextToken): This is the new yield point.
33 (WebCore::HTMLDocumentParser::pumpTokenizer): Remove ASSERT that we are not paused. isPaused
34 means that we are waiting for a script. Bug 54574 changed pumpTokenizer() so that it does
35 the right thing whether we are just before a token or waiting for a script. Now that we may
36 yield before a token or before a script, this may be called while paused.
37 * html/parser/HTMLParserScheduler.cpp:
38 (WebCore::isLayoutTimerActive): Added a FIXME because r52919 changed minimumLayoutDelay()
39 to return m_extraLayoutDelay instead of 0 as a minimum. So checking !minimumLayoutDelay()
40 no longer works. The fix is to change it to check minimumLayoutDelay() ==
41 m_extraLayoutDelay. But this is all the more reason to move this method onto Document. I'll
42 do this in a follow up.
43 (WebCore::HTMLParserScheduler::checkForYieldBeforeScript): Added.
44 * html/parser/HTMLParserScheduler.h:
45 (WebCore::HTMLParserScheduler::checkForYieldBeforeToken):
46 * page/FrameView.h:
47 (WebCore::FrameView::hasEverPainted): Added.
48