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

HTTP/2 stream question #69

Open
leoj3n opened this issue Jan 13, 2019 · 4 comments

Comments

Projects
None yet
2 participants
@leoj3n
Copy link

commented Jan 13, 2019

In the done-ssr 3.0 release notes @matthewp gives an example of using HTTP/2 in which he provides done-ssr the headers object:

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  });

  render(headers).pipe(stream);
});

Does this happen when using done-ssr-middleware with Express?

I tried to determine that myself, and saw that done-ssr will return new SSRStream:

https://github.com/donejs/done-ssr/blob/99e1adc7eb4901686f4598db36ef6809901ccf59/lib/index.js#L29

Which has a SafeStream.prototype.pipe function like:

https://github.com/donejs/done-ssr/blob/99e1adc7eb4901686f4598db36ef6809901ccf59/lib/ssr-stream.js#L127-L131

That done-ssr-middleware calls with res like:

stream.pipe(res);

Does that mean done-ssr-middleware with Express is equivalent to the direct usage of done-ssr in the release notes example? I don't see anything listening on "stream" like:

server.on('stream', (stream, headers) => {

Note: I'm also using the spdy npm package instead of native the http2 module.

@matthewp

This comment has been minimized.

Copy link
Contributor

commented Jan 14, 2019

done-ssr supports the native http2 module, not spdy. Express doesn't yet support http2. So if you want to use Express you're stuck with http1 for the time being, unfortunately.

@matthewp matthewp added the question label Jan 14, 2019

@leoj3n

This comment has been minimized.

Copy link
Author

commented Jan 15, 2019

@matthewp Thanks for your reply. I have a few questions:

  1. You say done-ssr supports the native http2 module, but does that mean done-ssr-middleware does as well? That was the main thing I was not sure about in the OP, because the example is using done-ssr directly. Assuming a future where Express does support the native http2 module, how would that look like using done-ssr-middleware? Any new/special code required?
  2. The spdy npm package supports Express and uses spdy-transport which says it provides a generic http2 transport implementation, so could that mean using the "spdy" package with only h2 and http/1.1 protocols enabled might be equivalent to using the native http2 module?
  3. It seems that even without using the native http2 module, done-ssr still provides mutations to the browser when incremental rendering is enabled. Would enabling http2 simply turn those mutations into more efficient http2 server push events? This bitovi blog post states that "Using incremental rendering requires a HTTP/2 server and browser" but I think it's outdated now because of this PR (you might want to update that blog post to reflect this info for people finding it like me).

I guess the main thing I'm trying to figure out is if it is possible to layer all the goodies like incremental SSR rendering with HTTP/2 server push and bundle manifests on top of a framework like Express in an app already using various other Express-compatible middleware. I think this is what most people who already use Express in their app will want to do, so that they don't have to write the majority of the server code for their app themselves (probably why they are using Express to begin with). Obviously I'm pretty new to this and just trying to figure out what I need to do to make my existing Express app work with all the cool new stuff, so let me know where I've got things mixed up.

@matthewp

This comment has been minimized.

Copy link
Contributor

commented Jan 15, 2019

  1. No, done-ssr-middleware expects a request and response object and the http2 module does not have those. The http2 module is actually very different from the http module. I'm sure Express will want to support it some time in the future, and when that happens we'll make sure done-ssr-middleware works with it. But until that happens I can't really predict how that's going to look.
  2. The spdy package won't work because it has a different API than the http2 module. Specifically there's a different function to perform PUSH and done-ssr doesn't support it.
  3. Incremental works in all three of these scenarios:
    • HTTP1
    • HTTP2 with PUSH
    • HTTP2 without PUSH

Some times Chrome has PUSH turned off even for HTTP2 connections because they like to do A/B tests on how it will affect performance. In this case we'll use the preload links like we do with HTTP1. It's still faster than HTTP1 because of the shared TCP connection, but not as fast as PUSH.

I obviously understand the desire to use Express. But until it supports HTTP2 there's really nothing we can do. Making done-ssr flexible enough to work with HTTP1 and HTTP2, which as I said before are much different APIs, was a lot of work.

@matthewp

This comment has been minimized.

Copy link
Contributor

commented Jan 15, 2019

For some context on where Express is with H2 support, here their maintainer about it. Reading that, I experienced the same difficulties with making done-ssr and done-serve support either API.

done-serve used to use Express but I had to remove it. Now it has its own middleware layer that's basically a less-nice express.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.