Understanding HTTP/2 Server Push with Node‑SPDY Examples
This article explains how HTTP/2 server push works, why it improves page load performance, and provides practical Node‑SPDY code examples for pushing assets, redirects, cache‑validation messages, and integrating Server‑Sent Events to notify clients of pushed resources.
HTTP/2 allows a server to send multiple responses for a single client request, known as server push, which can eliminate the round‑trip latency caused by waiting for the browser to discover additional resources such as JavaScript, CSS, or images referenced in the HTML.
Inlining a resource is effectively a manual form of server push, but HTTP/2 makes the pattern more efficient and powerful because pushed resources can be cached independently and reused across pages.
Getting Started with HTTP/2 Server Push
Inline resources cannot be cached separately and must be duplicated across pages, whereas pushed resources can be cached by the browser and reused. The following minimal SPDY server demonstrates pushing a JavaScript file to the client:
spdy.createServer(options, function(req, res) {
// push JavaScript asset (/main.js) to the client
res.push('/main.js', {'content-type': 'application/javascript'}, function(err, stream) {
stream.end('alert("hello from push stream!")');
});
// write main response body and terminate stream
res.end('Hello World!
');
}).listen(443);When the browser parses the <script src="/main.js"></script> tag, the main.js file is already cached, avoiding an extra network round‑trip.
What Else Can Be Pushed?
Beyond static assets, any HTTP response can be pushed, including redirects. The example below pushes a JavaScript file and a 301 redirect to another asset:
spdy.createServer(options, function(req, res) {
// push JavaScript asset (/newasset.js) to the client
res.push('/newasset.js', {'content-type': 'application/javascript'}, function(err, stream) {
stream.end('alert("hello from (redirected) push stream!")');
});
// push 301 redirect: /asset.js -> /newasset.js
res.push('/asset.js', {':status': 301, 'Location': '/newasset.js'}, function(err, stream) {
stream.end('301 Redirect');
});
// write main response body and terminate stream
res.end('
');
}).listen(443);This technique lets the browser cache both the redirect and the final asset without additional network latency.
More advanced uses include pushing cache‑invalidation signals or future‑dated 304 responses to control resource lifetimes, allowing the server to actively manage the client cache.
If a server is overly aggressive, browsers can limit or cancel pushed streams, so finding a balanced push strategy is essential for optimal performance.
Client Notification of Server Push
HTTP/2 server push does not provide a JavaScript API for notifications, but it can be combined with Server‑Sent Events (SSE) to inform the client when a pushed resource is available:
spdy.createServer(options, function(req, res) {
// set content type for SSE stream
res.setHeader('Content-Type', 'text/event-stream');
var messageId = 1;
setInterval(function(){
// push a simple JSON message into client's cache
var msg = JSON.stringify({'msg': messageId});
var resourcePath = '/resource/' + messageId;
res.push(resourcePath, {}, function(err, stream) { stream.end(msg); });
// notify client that resource is available in cache
res.write('data:' + resourcePath + '\n\n');
messageId += 1;
}, 2000);
}).listen(443);The client subscribes to the SSE channel and, upon receiving a notification, fetches the pushed resource from the cache using XHR:
<script>
var source = new EventSource('/');
source.onmessage = function(e) {
document.body.innerHTML += "SSE notification: " + e.data + '<br />';
// fetch resource via XHR... from cache!
var xhr = new XMLHttpRequest();
xhr.open('GET', e.data);
xhr.onload = function() {
document.body.innerHTML += "Message: " + this.response + '<br />';
};
xhr.send();
};
</script>All streams share the same TCP connection, eliminating extra connection overhead and unnecessary round‑trips. Combining SSE with server push enables arbitrary binary or text resources to be delivered efficiently.
Innovations and Open Questions
Server push opens many optimization opportunities, such as deciding which resources to push, when to push them, and whether they are already cached. Future browsers may add APIs for smarter push decisions, cache management, and application design patterns that fully exploit this powerful HTTP/2 feature.
Disclaimer: The content is sourced from public internet channels, presented neutrally for reference and discussion only. Copyright belongs to the original authors or institutions; please contact for removal if infringed.
Art of Distributed System Architecture Design
Introductions to large-scale distributed system architectures; insights and knowledge sharing on large-scale internet system architecture; front-end web architecture overviews; practical tips and experiences with PHP, JavaScript, Erlang, C/C++ and other languages in large-scale internet system development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.