Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

📝 [Proposal]: Early hints #3211

Open
3 tasks done
ReneWerner87 opened this issue Nov 21, 2024 · 3 comments
Open
3 tasks done

📝 [Proposal]: Early hints #3211

ReneWerner87 opened this issue Nov 21, 2024 · 3 comments

Comments

@ReneWerner87
Copy link
Member

ReneWerner87 commented Nov 21, 2024

Feature Proposal Description

Objective:

Introduce support for the HTTP 103 Early Hints status code in the Go Fiber framework to enhance web performance by allowing clients to preload resources before the final response is ready.

Background:

The HTTP 103 Early Hints status code enables servers to send preliminary responses containing links to resources that clients can begin preloading while the server prepares the final response. This mechanism reduces page load times by utilizing the client’s idle time effectively.

https://developer.chrome.com/docs/web-platform/early-hints

Example:
https://www.103earlyhints.com/
image

Internal Implementation:

  • Connection Hijacking: Utilize Fasthttp’s connection hijacking to gain direct access to the underlying network connection, enabling the sending of 1xx status codes.
  • Manual Response Construction: Construct the 103 response manually, including the appropriate Link headers, and write it to the connection.
  • Synchronization: Ensure that the Early Hints are sent before the final response, managing timing to prevent race conditions.

Note: Careful handling is required to manage the connection state and ensure compatibility with existing middleware and response handling mechanisms.

conn, brw, err := c.Fasthttp.Hijack()
if err != nil {
    return fmt.Errorf("Error on Hijacken the connection %v", err)
}
defer conn.Close()

// Early Hints send
earlyHints := "HTTP/1.1 103 Early Hints\r\n" +
    "Link: </styles.css>; rel=preload; as=style\r\n" +
    "Link: </script.js>; rel=preload; as=script\r\n" +
    "\r\n"

if _, err := brw.WriteString(earlyHints); err != nil {
    return fmt.Errorf("Error seinding Early Hints: %v", err)
}
if err := brw.Flush(); err != nil {
    return fmt.Errorf("Error flushing the buffer: %v", err)
}

Considerations:

  • Browser Support: As of now, not all browsers support 103 Early Hints. Developers should implement feature detection or provide fallbacks as necessary.
  • Security Implications: Ensure that the resources indicated in Early Hints are safe to preload, as clients will initiate requests before receiving the final response.
  • Performance Testing: Conduct thorough performance testing to validate the benefits of Early Hints in various scenarios.

Conclusion:

Implementing HTTP 103 Early Hints in Go Fiber can significantly improve page load times by allowing clients to preload critical resources. This proposal outlines a method to integrate this feature into Fiber, providing developers with a powerful tool to enhance web performance.

Alignment with Express API

As of now, Express.js does not natively support the HTTP 103 Early Hints status code. This limitation stems from the underlying Node.js HTTP server, which, until recently, did not implement support for the 103 status code. Discussions on the Express.js GitHub repository have highlighted that Express.js relies on Node.js to provide this functionality before it can be utilized within the framework.

HTTP RFC Standards Compliance

The proposed implementation of the HTTP 103 Early Hints status code in Go Fiber aligns with the specifications outlined in RFC 8297, titled “An HTTP Status Code for Indicating Hints.” 

Key Compliance Aspects:

  1. Informational Status Code:
    RFC 8297 introduces the 103 (Early Hints) status code as an informational response, allowing servers to send preliminary header fields to clients before the final response is ready. This proposal ensures that the 103 status code is utilized appropriately to convey early hints to clients.

  2. Use of Link Headers:
    The RFC specifies that the 103 response is primarily intended to include Link header fields, enabling clients to begin preloading resources. The proposed implementation adheres to this by allowing developers to specify Link headers in the Early Hints response, facilitating resource preloading by clients.

  3. Non-Final Response Handling:
    According to RFC 8297, clients should process the 103 response as a non-final response and continue waiting for the final response. The implementation ensures that the 103 Early Hints response is sent prior to the final response, maintaining the correct sequence as per the RFC.

  4. Compatibility Considerations:
    The RFC advises caution when sending 103 responses over HTTP/1.1 due to potential client compatibility issues. The proposed implementation includes mechanisms to detect client capabilities and conditionally send Early Hints, thereby adhering to the compatibility considerations outlined in the RFC.

By aligning with these key aspects of RFC 8297, the proposed feature ensures compliance with HTTP standards, promoting interoperability and enhancing web performance through the effective use of Early Hints.

API Stability

The proposed implementation of the HTTP 103 Early Hints status code in Go Fiber is designed with long-term stability in mind. By adhering to established HTTP standards and following best practices in API design, we aim to provide a robust and reliable feature that minimizes the need for future changes or deprecations.

Feature Examples

API Design:
Introduce a method in the fiber.Ctx context to facilitate sending Early Hints.

func (c fiber.Ctx) SendEarlyHints(hints map[string]string) error

Usage Example:
Demonstrate how developers can utilize the new method within a route handler.

app.Get("/", func(c fiber.Ctx) error {
    hints := map[string]string{
        "/styles.css": `rel="preload"; as="style"`,
        "/script.js":  `rel="preload"; as="script"`,
    }
    if err := c.SendEarlyHints(hints); err != nil {
        return err
    }
    // Proceed with generating the final response
    return c.SendString("Hello, World!")
})

Checklist:

  • I agree to follow Fiber's Code of Conduct.
  • I have searched for existing issues that describe my proposal before opening this one.
  • I understand that a proposal that does not meet these guidelines may be closed without explanation.
@grivera64
Copy link
Member

grivera64 commented Dec 1, 2024

@ReneWerner87 According to the Chrome developer link and mdn web docs:

In addition,
Early Hints are recommended to only be sent over HTTP/2 or HTTP/3 connections
and most browsers will only accept them over those protocols.

Will this lead to problems when implementing this feature, as fasthttp doesn't support (as of now) HTTP/2 or higher? There is an http2 fork of fasthttp according to fasthttp's README.md, but it doesn't seem to have as much support.

I've seen that using a proxy (like nginx) may help us here, but this wouldn't be a native fix within Fiber itself. We could potentially include this work around in the docs for the feature.

@gaby
Copy link
Member

gaby commented Dec 1, 2024

I feel like this should be implemented in fasthttp first.

@ReneWerner87
Copy link
Member Author

I feel like this should be implemented in fasthttp first.

could also be done
create a proposal in fasthttp as a start

I don't think it will lead to problems, as it is only an addition, but it would clearly be better placed in the core, provided they allow it and don't say that it can be implemented with the current possibilities

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests

3 participants