-
Notifications
You must be signed in to change notification settings - Fork 155
Design Doc: Flush Head Early
Megha Mohabey, 2012-02-29
Improve the time to first byte and time to render by flushing the head section of the html document early. The head section has various processing information like scripts, styles etc and flushing it early will allow the browser to fetch and parse the head elements early.
-
Stuffing subresources of the document in the head section so that the browser preloads those. The Flush Subresources Early rewriter aims to do that.
-
Determining the static and dynamic parts of the page and flushing accordingly. Above the fold (Blink) rewriters already address that but require some configuration.
The exact UI of this rewriter can be decided later. However, this rewriter is aimed to be auto ON. Also, this rewriter will be disabled if Above the fold rewriter is enabled or any other rewriter is enabled which can get negatively impacted.
- When an html request comes, lookup the property cache keyed by url.
- If the optimized head is cached and stable then flush it immediately without waiting for a response from the origin server.
- If the origin server responds before receiving a response from property cache, then do not use the response from property cache.
- Else cache the optimized head in property cache keyed by url from the response generated for this request.
- If the optimized head is cached and stable then flush it immediately without waiting for a response from the origin server.
- From the optimized response generated for the request, check whether the property cache entry matches with the response. 3. If it is a match do nothing. 4. Else 2. send a js to reload. 3. update the property cache with new value.
There are various ways in which we can handle head section mismatch
Con:
- Browser will end up requesting and executing similar content/resources twice.
- May cause some pages to break.
- Double execution of java scripts.
Pro:
- Reduces the amount of redundant information which is requested and executed twice by the browser.
Con:
- May cause some pages to break.
- Elements which are order sensitive need to be sent again.
-
Set a cookie to disable flush_head_early_rewriter and reload. Or send a redirect with flush_head_early_rewriter disabled in query parameter.
-
When the pss server receives this request, it will unset the cookie and not apply the rewriter for this request
Pro:
- we don't serve broken pages
Con:
- Extra RTT for the html page.
3. If the script nodes have changed then do reload.
4. else
1. delete all the elements in the old head except the script nodes and the nodes added by the scripts.
2. send the new head after removing the script nodes.
Pro:
- Double applying of javascript can be dangerous and this avoids that case.
Con:
- If the scripts are modifying some of the head elements then this may still result in broken pages.
Instrument the speed gains and stability of the rewriter before implementing. Use "reload/redirect" option for handling head section mismatch.
(and requirements from property cache)
- Headers also need to be flushed early which might have cookies.
- Handle this similar to Blink.
- How to preview this filter as this may not show any gains till the property cache has fully warmed up/ become stable.
- Also property cache "stability" metric has to be sufficiently robust to detect outlier changes.
- If the head section varies with every request, it may cause very high writes for cache. The property cache will need to have a feature to declare a key as uncacheable for some time if say last n cases were not a match.
Below are some implementation details for my reference.
(need to expand this)
- Add a cohort in property cache for FlushHeadEarly.
- When a request comes
- Check if there is an existing entry for this url in property cache.
- If its there and if it is stable then flush section
- remember that head flush is made for this request.
- Check if there is an existing entry for this url in property cache.
- FlushHeadEarlyRewriter
- It will be a post render filter and extend HtmlWriterFilter.
- If the cached head was already flushed for this request, it will inhibit flushing till its sees and keep all the storing the bytes seen in a string.
- When its sees then it will check if it is a match with the entry in property cache.
- If match then nothing to flush. Subsequent bytes are flushed correctly.
- Else,
- if the response headers do not have any VARY other than Accept-Encoding add this entry to the property cache.