SlideShare a Scribd company logo
Implementing Early Hints in Chrome
Viet-Hoang Tran
Université catholique de Louvain
Supervisor: Kazuhiko Yamamoto
IIJ Innovation Institute
200 OK + index.html
GET /style.css
200 OK + /style.css
Motivation
Client Server
GET /
200 OK + index.html
GET /style.css
200 OK + /style.css
Start
rendering
the page
Start
rendering
the page
Client Server
GET /
Early Hints
allows the server to send some headers (hints)
before the full response
Early Hints: How it works
Client Server
GET /
200 OK + index.html
GET /
103 Early Hints
Link: </style.css>; rel=preload
GET /style.css
200 OK + /style.css
Client Server
200 OK + index.html
GET
/style.css
200 OK +
/style.css
Early Hints tells clients which assets they can preload,
when the server is busy to prepare the main response.
Start
rendering
the page
Start
rendering
the page
Pointer to
important assets
What is Early Hints
● An extension to HTTPbis, drafted by Kazuho Oku
● HTTP 103 status code: an Informational Response
HTTP informational response
The 1xx status codes:
103 Early Hints
100 Continue
101 Switching Protocols
102 Processing
These interim messages come before final responses
Do not change the final presentation (rendered page) on clients
App
Server
Scenario 1
Trigger Push on HTTP/2 converter
Scenario:
– Application server is HTTP1
only
– HTTP/2 converter in front of
the app server
By Kazuho Oku, DeNA Co., Ltd.
In IETF 97 proceedings: slides-97-httpbis-sessb-early-hints
GET /
103 Early Hints
Link: /style.css
PUSH
/style.css
200 OK
Proxy
H2-converter
200 OK
Client
HTTP/2 HTTP/1
GET /
Processtherequest
GET /
103 Early Hints
Link: 3p.com/style.css
GET
/style.css
200 OK +/style.css
Client
Origin
Server
200 OK +
index.html
Scenario 2
Trigger preload of 3rd-party assets
● H2 Push does not work with 3rd-party
assets
● With early hints, clients may send early
requests to 3rd-party servers
Adapted from Kazuho Oku, DeNA Co., Ltd.
In IETF 97 proceedings: slides-97-httpbis-sessb-early-hints
3rd-party
Server
www.3p.com
Implementation
● Why Chrome?
– The only popular browser supporting Link preload header
● Current status:
– Chrome just ignores 103 Early Hints
● My initial approach was:
1. Parse the 103 Early Hints response
2. Extract the URI in the Link header
3. Then try to send out the request
But it is not that simple!
Renderer process 1
(for website 1)
Render thread
Chrome Internals Overview
Browser process
I/O thread
ChannelFilter
ResourceDispatcher
WebURLLoader
Resource Dispatcher Host
(master all requests in all renderers)
UI thread (Interacts with user)
RenderFrame
Host
WebKit/Blink
ResourceLoader
RawResource
DocumentLoader
RenderThread
WebContents
IPC
Renderer process 2
(for website 2)
Network Layer
URLRequest
HttpNetworkTransaction
HttpStream
URLRequest URLRequest
IPC
ChannelFilter
WebKit/Blink
I/O thread
Channel
Proxy
RenderFrame
Current Navigation Process
Renderer
Browser
I/O Thread
Initiate
navigation
Start
URL Request
Read
“200 OK” Response
Install
New
Document
Create
Frame
Loader
Start
Preload
Fetch
assets
Renderer ID +
Document info
Save
Assets
Navigation Process: First trial
Renderer
Browser
I/O Thread
Initiate
navigation
Start
URL Request
Read
“103 Early Hints”
Response
Create
Frame
Loader
Start
Preload
Fetch
assets
Renderer ID +
Document info
Save
Assets
● We want to send requests before the main response arrives.
● But the preload requests requires context from the installed document,
which is only available after the main response arrives
Read
“200 OK”
Response
Install
New
Document
Chicken-and-Egg problem
My approach
Need to install and commit the Document object first
Renderer
Browser
I/O Thread
Initiate
navigation
Start
URL Request
Read
“103 Early Hints”
Response
Create
Frame
Loader
Start
Preload
Fetch
assets
Renderer ID +
Document info
Save
Assets
Read
“200 OK”
Response
Install
New
Document
Set up server side
● Nghttpx + mruby script
– Worked, but
– The 103 and 200 responses merged in a single TCP
segment.
● python HTTP server
– By design: send one response per request
– Simple tweaks to make it deliver multiple responses -
separately
Process 103s status
Client Server
GET /
103 Early Hints
Link: </style.css>; rel=preload
GET /style.css
200 OK + /style.css
200 OK + index.html
1) Parse the 103 header, instead
of ignoring it
2) Set up and commit the
Document object
3) Trigger preload request (GET)
for indicated assets
Next step: connect the preloaded
assets with the main response
Implementing Early Hints in Chrome - Approaches and Challenges
Challenge
Chrome was designed to handle only
one response per request
Handle multiple responses
We need to modify several layers to:
1) Resets the states at each layer when the main 200 response
arrives.
2) Make sure it works in 2 cases:
1) the preloaded responses arrives before the main response
2) or they arrives after the main response
This is an architectural change
Layers need to be modified
1) In Browser Process:
– HttpStreamParser for HTTP/1
– SpdyStream and SpdySession for HTTP/2
– HttpNetworkTransaction
– Deferred Stages in ResourceLoader
– HttpCache::Transaction (can ignore by disabling cache)
– URLRequestHttpJob
2) In Renderer Process:
– RenderFrame
– DocumentLoader
Implementation status
✔ Parse the 103 header at network layer (HTTP/1)
✔ Set up and commit the Document object
✔ Trigger preload fetching (GET) for indicated assets
✗ Handle multiple responses
Thank you
References
1. Life of a URL request.
chromium.googlesource.com/chromium/src/+/lkgr/net/docs/life-of-a-url-request.md
2. Early Hints. By Kazuho Oku, DeNA Co., Ltd. In IETF 97 proceedings.
3. Multi-process Resource Loading.
chromium.org/developers/design-documents/multi-process-resource-loading
4. My WIP patches and server scripts are available at:
https://github.com/hoang-tranviet/early-hints-chrome/
Backup slides
Preload vs Server Push
Preload
● Can specify 3rd-party content
e.g.: on CDN
● More fine-grained: can be
specified in HTTP header or in
HTML tag
● usually come along with
datatype
Push
● can’t be used by third-party
hosted content.
● Need speculate (which may be
wrong)
https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf
Preload in Chrome
DocumentLoader::InstallNewDocument
DocumentLoader::DidCommitNavigation
DocumentLoader::DispatchLinkHeaderPreloads
ResourceDispatcher::
OnReceivedResponse
ResourceLoader::
DidReceiveResponse
RawResource::
ResponseReceived
::PreloadIfNeeded
LinkLoader::LoadLinksFromHeader
DocumentLoader::StartPreload
WebURLLoaderImpl::Context::
OnReceivedResponse
(renderer process)
(main process)
Chrome: Navigation process in detail
HttpStreamParser
HttpNetworkTransaction
URLRequestHttpJob
ResourceLoader
URLRequest
ResourceDispatcherHost
ResourceDispatcher
WebURLLoaderImpl
blink::ResourceLoader
RawResource
DocumentLoader
HttpStreamFactoryHttpNetworkSession HttpStream
HttpBasicStrea
m
Renderer Process
Main Process
SpdyHttpStream
SpdyStream

More Related Content

Implementing Early Hints in Chrome - Approaches and Challenges

  • 1. Implementing Early Hints in Chrome Viet-Hoang Tran Université catholique de Louvain Supervisor: Kazuhiko Yamamoto IIJ Innovation Institute
  • 2. 200 OK + index.html GET /style.css 200 OK + /style.css Motivation Client Server GET / 200 OK + index.html GET /style.css 200 OK + /style.css Start rendering the page Start rendering the page Client Server GET /
  • 3. Early Hints allows the server to send some headers (hints) before the full response
  • 4. Early Hints: How it works Client Server GET / 200 OK + index.html GET / 103 Early Hints Link: </style.css>; rel=preload GET /style.css 200 OK + /style.css Client Server 200 OK + index.html GET /style.css 200 OK + /style.css Early Hints tells clients which assets they can preload, when the server is busy to prepare the main response. Start rendering the page Start rendering the page Pointer to important assets
  • 5. What is Early Hints ● An extension to HTTPbis, drafted by Kazuho Oku ● HTTP 103 status code: an Informational Response
  • 6. HTTP informational response The 1xx status codes: 103 Early Hints 100 Continue 101 Switching Protocols 102 Processing These interim messages come before final responses Do not change the final presentation (rendered page) on clients
  • 7. App Server Scenario 1 Trigger Push on HTTP/2 converter Scenario: – Application server is HTTP1 only – HTTP/2 converter in front of the app server By Kazuho Oku, DeNA Co., Ltd. In IETF 97 proceedings: slides-97-httpbis-sessb-early-hints GET / 103 Early Hints Link: /style.css PUSH /style.css 200 OK Proxy H2-converter 200 OK Client HTTP/2 HTTP/1 GET / Processtherequest
  • 8. GET / 103 Early Hints Link: 3p.com/style.css GET /style.css 200 OK +/style.css Client Origin Server 200 OK + index.html Scenario 2 Trigger preload of 3rd-party assets ● H2 Push does not work with 3rd-party assets ● With early hints, clients may send early requests to 3rd-party servers Adapted from Kazuho Oku, DeNA Co., Ltd. In IETF 97 proceedings: slides-97-httpbis-sessb-early-hints 3rd-party Server www.3p.com
  • 9. Implementation ● Why Chrome? – The only popular browser supporting Link preload header ● Current status: – Chrome just ignores 103 Early Hints ● My initial approach was: 1. Parse the 103 Early Hints response 2. Extract the URI in the Link header 3. Then try to send out the request But it is not that simple!
  • 10. Renderer process 1 (for website 1) Render thread Chrome Internals Overview Browser process I/O thread ChannelFilter ResourceDispatcher WebURLLoader Resource Dispatcher Host (master all requests in all renderers) UI thread (Interacts with user) RenderFrame Host WebKit/Blink ResourceLoader RawResource DocumentLoader RenderThread WebContents IPC Renderer process 2 (for website 2) Network Layer URLRequest HttpNetworkTransaction HttpStream URLRequest URLRequest IPC ChannelFilter WebKit/Blink I/O thread Channel Proxy RenderFrame
  • 11. Current Navigation Process Renderer Browser I/O Thread Initiate navigation Start URL Request Read “200 OK” Response Install New Document Create Frame Loader Start Preload Fetch assets Renderer ID + Document info Save Assets
  • 12. Navigation Process: First trial Renderer Browser I/O Thread Initiate navigation Start URL Request Read “103 Early Hints” Response Create Frame Loader Start Preload Fetch assets Renderer ID + Document info Save Assets ● We want to send requests before the main response arrives. ● But the preload requests requires context from the installed document, which is only available after the main response arrives Read “200 OK” Response Install New Document Chicken-and-Egg problem
  • 13. My approach Need to install and commit the Document object first Renderer Browser I/O Thread Initiate navigation Start URL Request Read “103 Early Hints” Response Create Frame Loader Start Preload Fetch assets Renderer ID + Document info Save Assets Read “200 OK” Response Install New Document
  • 14. Set up server side ● Nghttpx + mruby script – Worked, but – The 103 and 200 responses merged in a single TCP segment. ● python HTTP server – By design: send one response per request – Simple tweaks to make it deliver multiple responses - separately
  • 15. Process 103s status Client Server GET / 103 Early Hints Link: </style.css>; rel=preload GET /style.css 200 OK + /style.css 200 OK + index.html 1) Parse the 103 header, instead of ignoring it 2) Set up and commit the Document object 3) Trigger preload request (GET) for indicated assets Next step: connect the preloaded assets with the main response
  • 17. Challenge Chrome was designed to handle only one response per request
  • 18. Handle multiple responses We need to modify several layers to: 1) Resets the states at each layer when the main 200 response arrives. 2) Make sure it works in 2 cases: 1) the preloaded responses arrives before the main response 2) or they arrives after the main response This is an architectural change
  • 19. Layers need to be modified 1) In Browser Process: – HttpStreamParser for HTTP/1 – SpdyStream and SpdySession for HTTP/2 – HttpNetworkTransaction – Deferred Stages in ResourceLoader – HttpCache::Transaction (can ignore by disabling cache) – URLRequestHttpJob 2) In Renderer Process: – RenderFrame – DocumentLoader
  • 20. Implementation status ✔ Parse the 103 header at network layer (HTTP/1) ✔ Set up and commit the Document object ✔ Trigger preload fetching (GET) for indicated assets ✗ Handle multiple responses
  • 22. References 1. Life of a URL request. chromium.googlesource.com/chromium/src/+/lkgr/net/docs/life-of-a-url-request.md 2. Early Hints. By Kazuho Oku, DeNA Co., Ltd. In IETF 97 proceedings. 3. Multi-process Resource Loading. chromium.org/developers/design-documents/multi-process-resource-loading 4. My WIP patches and server scripts are available at: https://github.com/hoang-tranviet/early-hints-chrome/
  • 24. Preload vs Server Push Preload ● Can specify 3rd-party content e.g.: on CDN ● More fine-grained: can be specified in HTTP header or in HTML tag ● usually come along with datatype Push ● can’t be used by third-party hosted content. ● Need speculate (which may be wrong) https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf
  • 26. Chrome: Navigation process in detail HttpStreamParser HttpNetworkTransaction URLRequestHttpJob ResourceLoader URLRequest ResourceDispatcherHost ResourceDispatcher WebURLLoaderImpl blink::ResourceLoader RawResource DocumentLoader HttpStreamFactoryHttpNetworkSession HttpStream HttpBasicStrea m Renderer Process Main Process SpdyHttpStream SpdyStream

Editor's Notes

  1. Complement to H2 Push
  2. Chrome ignores all 1xx headers
  3. Not a Chrome-specific problem: also happens with Firefox, Safari, MS Edge
  4. This procedure is needed to process any 1xx response, not only 103 Early Hints.