document.write() chunks of HTML are fed to the preload scanner so all of the resources in it can be discovered and started loading without waiting for the parser to parse each one of them.
If the preload scanner has already triggered an image load from something it discovered in the body then the any scripts discovered in chunks of document.write() html will be treated as late-body scripts.
A trivial case is attached where an external script (docwrite.js) writes 100 script tags in a loop:
for (var i = 1; i <= 100; i++) {
document.write('<scr' + 'ipt src="written.js?i=' + i + '"></scr' + 'ipt>\n')
}
Using a trivial HTML example:
<html>
<head>
<script src="docwrite.js"></script>
</head>
<body>
<img src="image.png">
Loaded
</body>
</html>
Both pages are hosted here for testing: http://test.patrickmeenan.com/docwrite/
If the img tag is present, the scripts written into the head of the page will be requested with Medium priority but if the image isn't in the markup the scripts will be fetched with High priority (correct).
To make matters worse, when loaded as Medium priority, the scripts will only load one-at-a-time because Chrome is still in the layout-blocking phase of loading.
This is because the preload scanner running on the HTML already discovered the image which is used as the separator for "early" and "late" scripts. When the HTML snippet that includes the 100 tags is appended to the document and run through a new preload scanner they are treated as late-body scripts.
WebPageTest test with image in the page (loading one at a time):
http://www.webpagetest.org/result/170420_7N_5ec652efc3cbb82e7bbcf42e4c135e8c/1/details/#waterfall_view_step1
WebPageTest test with no image in the page (loading six at a time):
http://www.webpagetest.org/result/170420_YW_cdfd5cfbc15d1a5b1215d8149b4175b9/1/details/#waterfall_view_step1
|
Deleted:
docwrite.zip
1.3 KB
|
Comment 1 by pmeenan@chromium.org
, Apr 20 2017