Menu Search
Jump to the content X X
Smashing Conf New York

You know, we use ad-blockers as well. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf New York, dedicated to smart front-end techniques and design patterns.

A Comprehensive Guide To HTTP/2 Server Push

The landscape for the performance-minded developer has changed significantly in the last year or so, with the emergence of HTTP/2 being perhaps the most significant of all. No longer is HTTP/2 a feature we pine for. It has arrived, and with it comes server push!

Aside from solving common HTTP/1 performance problems (e.g., head of line blocking and uncompressed headers), HTTP/2 also gives us server push! Server push allows you to send site assets to the user before they’ve even asked for them. It’s an elegant way to achieve the performance benefits of HTTP/1 optimization practices such as inlining, but without the drawbacks that come with that practice.

In this article, you’ll learn all about server push, from how it works to the problems it solves. You’ll also learn how to use it, how to tell if it’s working, and its impact on performance. Let’s begin!

Further Reading on SmashingMag: Link

What Is Server Push, Exactly? Link

Accessing websites has always followed a request and response pattern. The user sends a request to a remote server, and with some delay, the server responds with the requested content.

The initial request to a web server is commonly for an HTML document. In this scenario, the server replies with the requested HTML resource. The HTML is then parsed by the browser, where references to other assets are discovered, such as style sheets, scripts and images. Upon their discovery, the browser makes separate requests for those assets, which are then responded to in kind.

Typical Web Server Communication.5
Typical web server communication (Large preview6)

The problem with this mechanism is that it forces the user to wait for the browser to discover and retrieve critical assets until after an HTML document has been downloaded. This delays rendering and increases load times.

With server push, we have a solution to this problem. Server push lets the server preemptively “push” website assets to the client without the user having explicitly asked for them. When used with care, we can send what we know the user is going to need for the page they’re requesting.

Let’s say you have a website where all pages rely on styles defined in an external style sheet named styles.css. When the user requests index.html from the server, we can push styles.css to the user just after we begin sending the response for index.html.

Web Server Communication with HTTP/2 server push.7
Web server communication with HTTP/2 server push. (Large preview8)

Rather than waiting for the server to send index.html and then waiting for the browser to request and receive styles.css, the user only has to wait for the server to respond with both index.html and styles.css on the initial request. This means that the browser can begin rendering the page faster than if it had to wait.

As you can imagine, this can decrease the rendering time of a page. It also solves some other problems, particularly in front-end development workflows.

What Problems Does Server Push Solve? Link

While reducing round trips to the server for critical content is one of the problems that server push solves, it’s not the only one. Server push acts as a suitable alternative for a number of HTTP/1-specific optimization anti-patterns, such as inlining CSS and JavaScript directly into HTML, as well as using the data URI scheme9 to embed binary data into CSS and HTML.

These techniques found purchase in HTTP/1 optimization workflows because they decrease what we call the “perceived rendering time” of a page, meaning that while the overall loading time of a page might not be reduced, the page will appear to load faster for the user. It makes sense, after all. If you inline CSS into an HTML document within <style> tags, the browser can begin applying styles immediately to the HTML without waiting to fetch them from an external source. This concept holds true with inlining scripts and inlining binary data with the data URI scheme.

Web Server Communication with Inlined Content.
Web server communication with inlined content (Large preview10)

Seems like a good way to tackle the problem, right? Sure — for HTTP/1 workflows, where you have no other choice. The poison pill we swallow when we do this, however, is that the inlined content can’t be efficiently cached. When an asset like a style sheet or JavaScript file remains external and modular, it can be cached much more efficiently. When the user navigates to a subsequent page that requires that asset, it can be pulled from the cache, eliminating the need for additional requests to the server.

Optimal caching behavior.11
Optimal caching behavior. (Large preview12)

When we inline content, however, that content doesn’t have its own caching context. Its caching context is the same as the resource it’s inlined into. Take an HTML document with inlined CSS, for instance. If the caching policy of the HTML document is to always grab a fresh copy of the markup from the server, then the inlined CSS will never be cached on its own. Sure, the document that it’s a part of may be cached, but subsequent pages containing this duplicated CSS will be downloaded repeatedly. Even if the caching policy is more lax, HTML documents typically have limited shelf life. This is a trade-off that we’re willing to make in HTTP/1 optimization workflows, though. It does work, and it’s quite effective for first-time visitors. First impressions are often the most important.

These are the problems that server push addresses. When you push assets, you get the practical benefits that come with inlining, but you also get to keep your assets in external files that retain their own caching policy. There is a caveat to this point, though, and it’s covered toward the end of this article. For now, let’s continue.

I’ve talked enough about why you should consider using server push, as well as the problems that it fixes for both the user and the developer. Now let’s talk about how it’s used.

How To Use Server Push Link

Using server push usually involves using the Link HTTP header, which takes on this format:

Link: </css/styles.css>; rel=preload; as=style

Note that I said usually. What you see above is actually the preload resource hint13 in action. This is a separate and distinct optimization from server push, but most (not all) HTTP/2 implementations will push an asset specified in a Link header containing a preload resource hint. If either the server or the client opts out of accepting the pushed resource, the client can still initiate an early fetch for the resource indicated.

The as=style portion of the header is not optional. It informs the browser of the pushed asset’s content type. In this case, we use a value of style to indicate that the pushed asset is a style sheet. You can specify other content types14. It’s important to note that omitting the as value can result in the browser downloading the pushed resource twice. So don’t forget it!

Now that you know how a push event is triggered, how do we set the Link header? You can do so through two routes:

  • your web server configuration (for example, Apache httpd.conf or .htaccess);
  • a back-end language function (for example, PHP’s header function).

Here’s an example of configuring Apache (via httpd.conf or .htaccess) to push a style sheet whenever an HTML file is requested:

<FilesMatch "\.html$">
    Header set Link "</css/styles.css>; rel=preload; as=style"
<FilesMatch>

Here, we use the FilesMatch directive to match requests for files ending in .html. When a request comes along that matches this criteria, we add a Link header to the response that tells the server to push the resource at /css/styles.css.

Side note: Apache’s HTTP/2 module can also initiate a push of resources using the H2PushResource directive. The documentation for this directive states that this method can initiate pushes earlier than if the Link header method is used. Depending on your specific setup, you may not have access to this feature. The performance tests shown later in this article use the Link header method.

As of now, Nginx doesn’t support HTTP/2 server push, and nothing so far in the software’s changelog15 has indicated that support for it has been added. This may change as Nginx’s HTTP/2 implementation matures.

Another way to set a Link header is through a server-side language. This is useful when you aren’t able to change or override the web server’s configuration. Here’s an example of how to use PHP’s header function to set the Link header:

header("Link: </css/styles.css>; rel=preload; as=style");

If your application resides in a shared hosting environment where modifying the server’s configuration isn’t an option, then this method might be all you’ve got to go on. You should be able to set this header in any server-side language. Just be sure to do so before you begin sending the response body, to avoid potential runtime errors.

Pushing Multiple Assets Link

All of our examples so far only illustrate how to push one asset. What if you want to push more than one? Doing that would make sense, right? After all, the web is made up of more than just style sheets. Here’s how to push multiple assets:

Link: </css/styles.css>; rel=preload; as=style, </js/scripts.js>; rel=preload; as=script, </img/logo.png>; rel=preload; as=image

When you want to push multiple resources, just separate each push directive with a comma. Because resource hints are added via the Link tag, this syntax is how you can mix in other resource hints with your push directives. Here’s an example of mixing a push directive with a preconnect resource hint:

Link: </css/styles.css>; rel=preload; as=style, <https://fonts.gstatic.com>; rel=preconnect

Multiple Link headers are also valid. Here’s how you can configure Apache to set multiple Link headers for requests to HTML documents:

<FilesMatch "\.html$">
    Header add Link "</css/styles.css>; rel=preload; as=style"
    Header add Link "</js/scripts.js>; rel=preload; as=script"
<FilesMatch>

This syntax is more convenient than stringing together a bunch of comma-separated values, and it works just the same. The only downside is that it’s not quite as compact, but the convenience is worth the few extra bytes sent over the wire.

Now that you know how to push assets, let’s see how to tell whether it’s working.

How To Tell Whether Server Push Is Working Link

So, you’ve added the Link header to tell the server to push some stuff. The question that remains is, how do you know if it’s even working?

This varies by browser. Recent versions of Chrome will reveal a pushed asset in the initiator column of the network utility in the developer tools.

Chrome indicating that an asset has been pushed by the server16
Chrome indicating that an asset has been pushed by the server (Large preview17)

Furthermore, if we hover over the asset in the network request waterfall, we’ll get detailed timing information on the asset’s push:

Chrome showing detailed timing information of the pushed asset18
Chrome showing detailed timing information of the pushed asset (Large preview19)

Firefox is less obvious in identifying pushed assets. If an asset has been pushed, its status in the browser’s network utility in the developer tools will show up with a gray dot.

Firefox indicating that an asset has been pushed by the server20
Firefox indicating that an asset has been pushed by the server (Large preview21)

If you’re looking for a definitive way to tell whether an asset has been pushed by the server, you can use the nghttp command-line client22 to examine a response from an HTTP/2 server, like so:

nghttp -ans https://jeremywagner.me

This command will show a summary of the assets involved in the transaction. Pushed assets will have an asterisk next to them in the program output, like so:

id  responseEnd requestStart  process code size request path
 13     +50.28ms      +1.07ms  49.21ms  200   3K /
  2     +50.47ms *   +42.10ms   8.37ms  200   2K /css/global.css
  4     +50.56ms *   +42.15ms   8.41ms  200  157 /css/fonts-loaded.css
  6     +50.59ms *   +42.16ms   8.43ms  200  279 /js/ga.js
  8     +50.62ms *   +42.17ms   8.44ms  200  243 /js/load-fonts.js
 10     +74.29ms *   +42.18ms  32.11ms  200   5K /img/global/jeremy.png
 17     +87.17ms     +50.65ms  36.51ms  200  668 /js/lazyload.js
 15     +87.21ms     +50.65ms  36.56ms  200   2K /img/global/book-1x.png
 19     +87.23ms     +50.65ms  36.58ms  200  138 /js/debounce.js
 21     +87.25ms     +50.65ms  36.60ms  200  240 /js/nav.js
 23     +87.27ms     +50.65ms  36.62ms  200  302 /js/attach-nav.js

Here, I’ve used nghttp on my own website23, which (at least at the time of writing) pushes five assets. The pushed assets are marked with an asterisk on the left side of the requestStart column.

Now that we can identify when assets are pushed, let’s see how server push actually affects the performance of a real website.

Measuring Server Push Performance Link

Measuring the effect of any performance enhancement requires a good testing tool. Sitespeed.io24 is an excellent tool available via npm25; it automates page testing and gathers valuable performance metrics. With the appropriate tool chosen, let’s quickly go over the testing methodology.

Testing Methodology Link

I wanted measure the impact of server push on website performance in a meaningful way. In order for the results to be meaningful, I needed to establish points of comparison across six separate scenarios. These scenarios are split across two facets: whether HTTP/2 or HTTP/1 is used. On HTTP/2 servers, we want to measure the effect of server push on a number of metrics. On HTTP/1 servers, we want to see how asset inlining affects performance in the same metrics, because inlining is supposed to be roughly analogous to the benefits that server push provides. Specifically, these scenarios are the following:

  • HTTP/2 without server push
    In this state, the website runs on the HTTP/2 protocol, but nothing whatsoever is pushed. The website runs “stock,” so to speak.
  • HTTP/2 pushing only CSS
    Server push is used, but only for the website’s CSS. The CSS for the website is quite small, weighing in at a little over 2 KB with Brotli compression26 applied.
  • Pushing the kitchen sink
    All assets in use on all pages across the website are pushed. This includes the CSS, as well as 1.4 KB of JavaScript spread across six assets, and 5.9 KB of SVG images spread across five assets. All quoted file sizes are, again, after Brotli compression has been applied.
  • HTTP/1 with no assets inlined
    The website runs on HTTP/1, and no assets are inlined to reduce the number of requests or increase rendering speed.
  • Inlining only CSS
    Only the website’s CSS is inlined.
  • Inlining the kitchen sink
    All assets in use on all pages across the website are inlined. CSS and scripts are inlined, but SVG images are base64-encoded and embedded directly into the markup. It should be noted that base64-encoded data is roughly 1.37 times larger27 than its unencoded equivalent.

In each scenario, I initiated testing with the following command:

sitespeed.io -d 1 -m 1 -n 25 -c cable -b chrome -v https://jeremywagner.me

If you want to know the ins and outs of what this command does, you can check out the documentation28. The short of it is that this command tests my website’s home page at https://jeremywagner.me29 with the following conditions:

  • The links in the page are not crawled. Only the specified page is tested.
  • The page is tested 25 times.
  • A “cable-like” network throttling profile is used. This translates to a round trip time of 28 milliseconds, a downstream speed of 5,000 kilobits per second and an upstream speed of 1,000 kilobits per second.
  • The test is run using Google Chrome.

Three metrics were collected and graphed from each test:

  • first paint time
    This is the point in time at which the page can first be seen in the browser. When we strive to make a page “feel” as though it is loading quickly, this is the metric we want to reduce as much as possible.
  • DOMContentLoaded time
    This is the time at which the HTML document has completely loaded and has been parsed. Synchronous JavaScript code will block the parser and cause this figure to increase. Using the async attribute on <script> tags can help to prevent parser blocking.
  • page-loading time
    This is the time it takes for the page and its assets to fully load.

With the parameters of the test determined, let’s see the results!

Test Outcomes Link

Tests were run across the six scenarios specified earlier, with the results graphed. Let’s start by looking at how first paint time is affected in each scenario:

First paint time30
First paint time (Large preview31)

Let’s first talk a bit about how the graph is set up. The portion of the graph in blue represents the average first paint time. The orange portion is the 90th percentile. The grey portion represents the maximum first paint time.

Now let’s talk about what we see. The slowest scenarios are both the HTTP/2- and HTTP/1-driven websites with no enhancements at all. We do see that using server push for CSS helps to render the page about 8% faster on average than if server push is not used at all, and even about 5% faster than inlining CSS on an HTTP/1 server.

When we push all assets that we possibly can, however, the picture changes somewhat. First paint times increase slightly. In HTTP/1 workflows where we inline everything we possibly can, we achieve performance similar to when we push assets, albeit slightly less so.

The verdict here is clear: With server push, we can achieve results that are slightly better than what we can achieve on HTTP/1 with inlining. When we push or inline many assets, however, we observe diminishing returns.

It’s worth noting that either using server push or inlining is better than no enhancement at all for first-time visitors. It’s also worth noting that these tests and experiments are being run on a website with small assets, so this test case may not reflect what’s achievable for your website.

Let’s examine the performance impacts of each scenario on DOMContentLoaded time:

DOMContentLoaded time32
DOMContentLoaded time (Large preview33)

The trends here aren’t much different than what we saw in the previous graph, except for one notable departure: The instance in which we inline as many assets as practical on a HTTP/1 connection yields a very low DOMContentLoaded time. This is presumably because inlining reduces the number of assets needed to be downloaded, which allows the parser to go about its business without interruption.

Now, let’s look at how page-loading times are affected in each scenario:

Page-loading time34
Page-loading time (Large preview35)

The established trends from earlier measurements generally persist here as well. I found that pushing only the CSS realized the greatest benefit to loading time. Pushing too many assets could, on some occasions, make the web server a bit sluggish, but it was still better than not pushing anything at all. Compared to inlining, server push yielded better overall loading times than inlining did.

Before we conclude this article, let’s talk about a few caveats you should be aware of when it comes to server push.

Caveats On Using Server Push Link

Server push isn’t a panacea for your website’s performance maladies. It has a few drawbacks that you need to be cognizant of.

You Can Push Too Much Stuff Link

In one of the scenarios above, I am pushing a lot of assets, but all of them altogether represent a small portion of the overall data. Pushing a lot of very large assets at once could actually delay your page from painting or being interactive sooner, because the browser needs to download not only the HTML, but all of the other assets that are being pushed alongside of it. Your best bet is to be selective in what you push. Style sheets are a good place to start (so long as they aren’t massive). Then evaluate what else makes sense to push.

You Can Push Something That’s Not on the Page Link

This is not necessarily a bad thing if you have visitor analytics to back up this strategy. A good example of this may be a multi-page registration form, where you push assets for the next page in the sign-up process. Let’s be crystal clear, though: If you don’t know whether you should force the user to preemptively load assets for a page they haven’t seen yet, then don’t do it. Some users might be on restricted data plans, and you could be costing them real money.

Configure Your HTTP/2 Server Properly Link

Some servers give you a lot of server push-related configuration options. Apache’s mod_http2 has some options for configuring how assets are pushed. The H2PushPriority setting36 should be of particular interest, although in the case of my server, I left it at the default setting. Some experimentation could yield additional performance benefits. Every web server has a whole different set of switches and dials for you to experiment with, so read the manual for yours and find out what’s available!

Pushes May Not Be Cached Link

There has been some gnashing of teeth over whether server push could hurt performance in that returning visitors may have assets needlessly pushed to them again. Some servers do their best to mitigate this. Apache’s mod_http2 uses the H2PushDiarySize setting37 to optimize this somewhat. H2O Server has a feature called Cache Aware server push38 that uses a cookie mechanism to remember pushed assets.

If you don’t use H2O Server, you can achieve the same thing on your web server or in server-side code by only pushing assets in the absence of a cookie. If you’re interested in learning how to do this, then check out a post I wrote about it on CSS-Tricks39. It’s also worth mentioning that browsers can send an RST_STREAM frame to signal to a server that a pushed asset is not needed. As time goes on, this scenario will be handled much more gracefully.

As sad it may seem, we’re nearing the end of our time together. Let’s wrap things up and talk a bit about what we’ve learned.

Final Thoughts Link

If you’ve already migrated your website to HTTP/2, you have little reason not to use server push. If you have a highly complex website with many assets, start small. A good rule of thumb is to consider pushing anything that you were once comfortable inlining. A good starting point is to push your site’s CSS. If you’re feeling more adventurous after that, then consider pushing other stuff. Always test changes to see how they affect performance. You’ll likely realize some benefit from this feature if you tinker with it enough.

If you’re not using a cache-aware server push mechanism like H2O Server’s, consider tracking your users with a cookie and only pushing assets to them in the absence of that cookie. This will minimize unnecessary pushes to known users, while improving performance for unknown users. This not only is good for performance, but also shows respect to your users with restricted data plans.

All that’s left for you now is to try out server push for yourself. So get out there and see what this feature can do for you and your users! If you want to know more about server push, check out the following resources:

Thanks to Yoav Weiss43 for clarifying that the as attribute is required (and not optional as the original article stated), as well as a couple of other minor technical issues. Additional thanks goes to Jake Archibald44 for pointing out that the preload resource hint is an optimization distinct from server push.

This article is about an HTTP/2 feature named server push. This and many other topics are covered in Jeremy’s book Web Performance in Action45. You can get it or any other Manning Publications46 book for 42% off with the coupon code sswagner!

(rb, vf, al, il)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2016/02/breaking-it-down-to-the-bits-how-the-internet-dns-and-https-work/
  2. 2 https://www.smashingmagazine.com/2017/04/secure-web-app-http-headers/
  3. 3 https://www.smashingmagazine.com/2016/10/next-generation-server-compression-with-brotli/
  4. 4 https://www.smashingmagazine.com/2016/05/modern-wordpress-server-stack/
  5. 5 http://provide.smashingmagazine.com/normal-server-response.svg
  6. 6 http://provide.smashingmagazine.com/normal-server-response.svg
  7. 7 http://provide.smashingmagazine.com/server-push-response.svg
  8. 8 http://provide.smashingmagazine.com/server-push-response.svg
  9. 9 https://en.wikipedia.org/wiki/Data_URI_scheme
  10. 10 http://provide.smashingmagazine.com/inlined-content-unopt.svg
  11. 11 http://provide.smashingmagazine.com/caching-unopt.svg
  12. 12 http://provide.smashingmagazine.com/caching-unopt.svg
  13. 13 https://w3c.github.io/preload
  14. 14 https://w3c.github.io/preload/#link-element-interface-extensions
  15. 15 https://nginx.org/en/CHANGES
  16. 16 https://www.smashingmagazine.com/wp-content/uploads/2017/02/chrome-push-indicator-large-opt.png
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2017/02/chrome-push-indicator-large-opt.png
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2017/02/push-timing-large-opt.png
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2017/02/push-timing-large-opt.png
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2017/02/firefox-push-indicator-large-opt.png
  21. 21 https://www.smashingmagazine.com/wp-content/uploads/2017/02/firefox-push-indicator-800w-opt.png
  22. 22 https://nghttp2.org
  23. 23 https://jeremywagner.me
  24. 24 https://www.sitespeed.io
  25. 25 https://www.npmjs.com
  26. 26 https://www.smashingmagazine.com/2016/10/next-generation-server-compression-with-brotli
  27. 27 https://en.wikipedia.org/wiki/Base64#MIME
  28. 28 https://www.sitespeed.io/documentation/sitespeed.io/configuration
  29. 29 https://jeremywagner.me
  30. 30 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-first-paint-800w-opt.png
  31. 31 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-first-paint-800w-opt.png
  32. 32 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-domcontentloaded-large-opt.png
  33. 33 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-domcontentloaded-large-opt.png
  34. 34 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-page-load-large-opt.png
  35. 35 https://www.smashingmagazine.com/wp-content/uploads/2017/02/graph-page-load-800w-opt.png
  36. 36 https://httpd.apache.org/docs/2.4/mod/mod_http2.html#h2pushpriority
  37. 37 https://httpd.apache.org/docs/2.4/mod/mod_http2.html#h2pushdiarysize
  38. 38 https://h2o.examp1e.net/configure/http2_directives.html
  39. 39 https://css-tricks.com/cache-aware-server-push
  40. 40 https://tools.ietf.org/html/rfc7540#section-8.2
  41. 41 https://www.filamentgroup.com/lab/modernizing-delivery.html
  42. 42 https://www.igvita.com/2013/06/12/innovating-with-http-2.0-server-push/
  43. 43 https://blog.yoav.ws.
  44. 44 https://jakearchibald.com
  45. 45 https://manning.com/books/web-performance-in-action?a_aid=webopt&a_bid=63c31090
  46. 46 https://manning.com

↑ Back to top Tweet itShare on Facebook

Jeremy Wagner is a performance-obsessed front end developer, author and speaker living and working in the frozen wastes of Saint Paul, Minnesota. He is also the author of the Manning Publications book Web Performance in Action, a web developer's companion guide for creating fast websites. You can find him on Twitter @malchata, or read his blog of ramblings.

  1. 1

    Jake Archibald

    April 10, 2017 4:15 pm

    Apologies if this is nitpicking, but Link: rel=preload isn’t really anything to do with HTTP/2 push, it’s just that some front-end servers have decided to convert one to the other.

    So, the info in “How To Use Server Push” only applies if you’re using a particular type of server that performs that conversion.

    5
  2. 4

    Daniela Matos de Carvalho

    April 10, 2017 4:34 pm

    Thanks for the article. Another resource that might be interesting:

    Optimize with Server Push and Service Workers

    3
    • 5

      Very interesting, Daniela. I opened an issue to fetch-inject, where I use fetch to do parallel asynchronous downloading of assets. It should pair nicely with your performance testing, and I’d love to see it working alongside Server Push. Cheers.

      0
  3. 6

    Hadrien Gardeur

    April 10, 2017 6:14 pm

    It’s still very unclear to me if HTTP/2 Server Push provides real benefit over simply relying on a browser’s abilty to use Link: rel=preload and proper HTTP caching (Cache-Control).

    Tracking a user with a cookie to decide if you should push content or not feels very intrusive and overkill.

    1
    • 7

      Benedikt Christoph Wolters

      April 10, 2017 8:53 pm

      1) the benefit wrt. to preload is that you a) save a RTT and b) can prioritize resources regardless of what the browser might think its best to request next.

      2) Moreover, a cookie does not give any indication of whether the information it holds is actually correct. Nobody can guarantee that the user hasnt cleared the cache but kept the cookie (in fact there are things like ccleaner who do that kind of stuff)

      1
      • 8

        Hadrien Gardeur

        April 10, 2017 10:10 pm

        1) There’s no round trip if you use Cache-Control over ETag or Last-Modified and the resources are in cache.
        2) Browsers have their own behaviour regarding priorities, rel=preload is usually very high priority, I don’t really see how the server can take a better decision with limited/unreliable info (a cookie).
        3) Exactly, which is why reinventing the wheel (controlling cache with a cookie) is IMO a bad idea.

        1
  4. 9

    As I was half way through reading I was thinking this is going to be awesome. We can make our websites so much faster.

    Then with the end results it was kind of a let down. This really has nothing to do with the article but just that the push feature of http2 doesn’t seem to have the desired effect that most developers would be hoping for.

    1
    • 10

      I certainly understand where you’re coming from, but here’s something to consider: The site in the test case was my blog, a highly optimized site with small assets. Assets that are small enough that would be also practical to inline on an HTTP/1 workflow. I felt this would provide a reasonable test case for what was possible with push as compared to inlining.

      I understand that the test case isn’t mind blowing, but I would say that the effects are more significant than you might suspect. In the case of pushing CSS, we see an 8% improvement of time to first paint over no pushing mechanism used at all. That’s nothing to sneeze at, IMO, especially on slower connections. Imagine a site that might take 4 or 5 seconds to begin painting (which is already slow). With push enabled, you’re talking about getting that first paint time down to 3.68-4.6 seconds. And with relatively little effort to implement.

      On top of that, think of the benefits that come with using push instead of inlining: No more redundant data inlined across several pages that the user agent has to download on subsequent page navigations. No more dealing with inlining /period/. The developer gains convenience with a simpler workflow and the user gets a performance benefit. That seems like a win to me. :)

      I would highly recommend you give it a shot and see how it all works for you. You may be surprised at what server push can do for you in your specific situation.

      Thanks for reading. :)

      1
  5. 11

    Mark Mennell

    April 11, 2017 7:02 am

    Server PUSH is only one feature of HTTP2. A bigger feature in my view is persistent connections, so at the TCP/IP layer the socket is kept open instead of having to reconnect each request – this has the biggest performance impact I understand..

    Just thought this article should at least mention server push is one of many features of HTTP2, and IMO not even the biggest features in terms of perf.

    0
  6. 12

    HTTP/2 Push is indeed interesting, here is another guide, with a website that actually use the feature:

    https://www.shimmercat.com/en/blog/articles/whats-push/

    0
  7. 13

    Great post! thanks for sharing, Jeremy!

    1

Leave a Comment

You may use simple HTML to add links or lists to your comment. Also, use <pre><code class="language-*">...</code></pre> to mark up code snippets. We support -js, -markup and -css for comments.

↑ Back to top