vert-x3 / vertx-web

HTTP web applications for Vert.x
Apache License 2.0
1.11k stars 534 forks source link

Implement 103 Early Hints (RFC 8297) #2284

Open cavallium opened 2 years ago

cavallium commented 2 years ago

Describe the feature

Currently it's not possible to send an early-hints response (103 Early Hints (RFC 8297)) using the RoutingContext.

Use cases

Early hints is useful to instruct the browser to preload some webpage resources and reduce the loading time

Contribution

I never contributed to vert.x before, I don't know to implement it correctly. I found that vert.x implemented an HTTP response that can be sent before the final response, almost like 103 Early Hints: HTTP 100 Continue. Using RountingContext.writeContinue() I can send a HTTP 100 Continue before the final response. To implement early hints, vert.x-web could implement a method called RountingContext.writeEarlyHints(...) that works in the same way.

pmlopes commented 2 years ago

I've to be honest, this is the 1st time I've heard about this header. From what I understood from the RFC this is similar to what H2 does and we actually have some support (for H2) in the static handler:

https://github.com/vert-x3/vertx-web/blob/master/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/StaticHandlerImpl.java#L524-L540

However in order to write the correct response, we may need to also implement some support for it on vertx-core as this special 103 mode requires writing the HTTP response headers, but not complete the request

pmlopes commented 2 years ago

This is also an experimental RFC and currently only supported by Google Chrome:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103

pmlopes commented 2 years ago

Depends on https://github.com/eclipse-vertx/vert.x/pull/4508

Ludo-LM commented 2 years ago

We are using Vert.x since few years to implement our micro-frontend aggregator. It is currently used on leroymerlin.fr, leroymerlin.it, leroymerlin.es and leroymerlin.pt (2.3 billions hits/month). Until today we use server push to push critical css and js to the browser, we discover that Chrome removed the support of server push (https://developer.chrome.com/blog/removing-push/) in Chrome 106 (august 2022). This results in a 100ms increase in our "largest contentful paint".

Early Hint is replacing Server Push and should become a great feature to improve web performance. Browsers that are not able to handle early hints just ignore it.

There are many experimentation on early hints today and it should become a standard for all the browsers in few months https://www.fastly.com/blog/beyond-server-push-experimenting-with-the-103-early-hints-status-code https://blog.cloudflare.com/early-hints/ https://developer.chrome.com/blog/early-hints/

vietj commented 2 years ago

@Ludo-LM we are trying first to get https://github.com/eclipse-vertx/vert.x/pull/4508 there and then we can implement this like we did for push

pmlopes commented 2 years ago

@Ludo-LM @cavallium I can imagine this feature as a new handler that takes the functionality out of the static handler. You can imagine it like:

router.get("/static/*")
  .handler(EarlyHintsHandler.create()
    .link(Link.create("style.css").as("style").rel("preload"))
    .link(Link.create("script.js").as("script").rel("preload"))
...

Which should then at the wire level write:

103 Early Hint
Link: </styles.css>; rel=preload; as=style
200 OK
Content-Type: text/html

<!DOCTYPE html>
...
<link rel=”stylesheet” type=”text/css” href=”style.css”>
...

According to the spec we can do multiple 103 responses, so we don't need to keep any state at the server processing side, as the HTML spec states that only the 1st will be processed.

https://html.spec.whatwg.org/multipage/semantics.html#early-hints

We need to define this Link @DataObject to allow customization of the resource.

cavallium commented 1 year ago

The vert.x pull request has been merged

vietj commented 1 year ago

I scoped it to 4.4.0 to be on the radar, not sure it makes the deadline though.