At Squarespace, we strive to provide our customers and their visitors with fast and responsive browsing experiences. Today, we proudly announce HTTP/2 support for all Squarespace sites with TLS enabled.
HTTP, or hypertext transfer protocol, is an application-layer protocol that defines the communication mechanisms between a client and server. It is the foundation of data communication for the world wide web. HTTP/1.1 has been in use since the late ’90s and, even though it introduced the concept of connection reuse, it suffers from considerable performance limitations. It is limited to processing a single request per TCP connection which forces browsers to open many TCP connections to load requests in parallel. This limitation has forced developers to come up with workarounds to improve page load speeds.
HTTP/2
HTTP/2 is a major revision of the HTTP protocol that addresses the performance limitations of HTTP/1.1. It is based on the SPDY protocol originally created at Google. The features of HTTP/2 include:
Binary: HTTP/2 is a binary protocol that sends data in binary frames. Compared to plain text-based protocols, the determination of the start and end of frames becomes easier and there is no need to spend time translating textual information to binary format. Debugging a binary protocol is harder, but the network can more effectively generate and parse binary frames.
Multiplexed streams: HTTP/2 uses streams, “independent, bidirectional sequences of frames exchanged between the client and the server” according to RFC 7540. A single HTTP/2 connection can open multiple concurrent streams allowing multiple request and response messages to be in flight at the same time. The protocol also allows parts of one message to be intermingled with another during transmission. In the end, this allows a client to use a single TCP connection per origin to load a website.
Stream prioritization: HTTP/2 allows the client to 1) specify a weight to each stream to define which streams should be considered more important, and 2) build a dependency tree for the streams. This could potentially allow a browser to specify which images should take priority as a user scrolls down a page, for example.
Header compression: HTTP/2 remains a stateless protocol but it adds the ability to compress header frames using HPACK. HPACK compresses header values, and they can be reconstructed from previously received frames after transmission.
Server push: HTTP/2 allows the server to anticipate what the client’s next request will be and “push” the data ahead of time.
Application Layer Protocol Negotiation (ALPN)
Application Layer Protocol Negotiation (ALPN) is an extension to the TLS protocol that allows the client and server to negotiate which protocol to use without unnecessary round trips. With ALPN, the client sends a list of accepted protocols, ordered by preference, and the server responds with its choice. The HTTP/2 protocol makes use of Application Layer Protocol Negotiation (ALPN). Squarespace’s servers support both the HTTP/2 and HTTP/1.1 protocols.
HTTP/1.1 Workarounds
With HTTP/1.1, developers tried to increase page load speed through techniques like domain sharding, concatenation of files, image spriting, and inlining of assets. HTTP/2 renders some of these optimization workarounds obsolete.
Domain sharding: Sharding of domains results in the execution of additional DNS queries, establishment of additional TCP connections and (potentially) TLS handshakes. It also invalidates the benefits of stream prioritization. In HTTP/2, multiplexed streams allow multiple assets to be fetched in parallel over a single connection, achieving the same result.
Concatenation of files and image spriting: The information in concatenated CSS, JavaScript, or image sprites will likely not be used by all pages on your website. Therefore, data is downloaded unnecessarily during first load. Furthermore, small edits to the concatenated files result in a cache invalidation of the entire file. In HTTP/2, segregating frequently updated assets from assets that are more static results in better caching performance.
Inlining of assets: Embedding CSS or JavaScript into the HTML page invalidates the benefits of stream prioritization. In addition, if the embedded code is heavily used across HTML pages, more data is sent over the wire unnecessarily. In HTTP/2, server push may be used to attain the same result.
HTTP/2 in Action
A reverse proxy and load balancer, codenamed Echo, built by our Edge Infrastructure team is responsible for routing all Squarespace traffic. It is written in Java 8 and is powered by Netty. Netty is an asynchronous, event-driven framework for the development of high-performance, low-latency network applications. It has built-in support for many protocols such as HTTP/1.1 and HTTP/2. It also exposes some low-level, native features such as TLS support via OpenSSL/BoringSSL/LibreSSL, epoll support on Linux, and kqueue support on BSD (soon) via an easy-to-use and consistent API. The framework provides some end-to-end solutions for common problems (e.g. SOCKS and Web Proxies), but it really shines when used as a toolbox to create something like a load balancer.
HTTP/2 support was introduced to Netty as of version 4.1. The current API is marked unstable as it may change without much notice. The biggest challenge in working with native HTTP/2 connections, streams, and requests is that there’s a lot more persistent state and more events that need to be dealt with. Netty’s API is quite closely following RFC 7540 and it will be interesting to see how native, user-facing HTTP/2 APIs will evolve over time. Current Java HTTP/2 implementations build upon existing APIs, such as the Servlet API, which has had almost two decades to mature and hide the internals of HTTP/2 from the user. Netty provides a built-in translation layer (see HttpToHttp2ConnectionHandler and InboundHttp2ToHttpAdapter), but it accumulates the full request and response body in memory. This wasn’t suitable for something like our reverse proxy.
Our implementation translates HTTP/2 frames into HTTP/1.1 requests, and HTTP/2 streams are interpreted as HTTP/1.1 connections. Responses are translated back into frames and returned over the corresponding streams. The following snippet of simplified pseudocode illustrates some of the details that need to be dealt with when working with native HTTP/2:
class Example extends Http2FrameAdapter { void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endStream) { HttpRequest request = HttpConversionUtil.toHttpRequest(streamId, headers, true); ctx.fireChannelRead(request); if (endStream) { ctx.fireChannelRead(LastHttpContent.EMPTY_LAST_CONTENT); } } int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) { ctx.fireChannelRead(new DefaultHttpContent(data.retain())); if (endOfStream) { ctx.fireChannelRead(LastHttpContent.EMPTY_LAST_CONTENT); } return data.readableBytes(); } }
To inspect the HTTP/2 requests, view the Protocol column in the Network tab in your browser’s developer console.
After we completed the rollout of HTTP/2, we noticed a drop in HTTPS traffic in favor of HTTP/2 traffic. At this point, around 20% of all Squarespace traffic is currently over HTTP/2.
The Product
All Squarespace sites with the TLS option enabled will be automatically delivered through the more efficient HTTP/2 protocol when loaded in a browser with HTTP/2 support. HTTP/2 is already supported by the most current releases of Chrome, Edge, Internet Explorer, Safari, and Firefox. To check if your browser supports HTTP/2, click here. TLS needs to be enabled on Squarespace websites to make use of HTTP/2 because no browser currently supports HTTP/2 over an unencrypted connection. Current Squarespace users can see instructions on how to enable TLS (SSL) on their site by checking out our Help guide.
We’re excited to continue to change the face of the Internet by providing HTTP/2, one of the latest technologies, to all of our customers at no additional cost, with its significant speed improvements and enhanced security features. If you’re interested in these types of challenges and would like to join our team, we’re hiring.