Re: [w3ctag/design-reviews] `sec-metadata` (#280)

> Which encodes as a binary structured header value in 6 characters as:

Please, please, please don't do that. The whole point of using structured headers is to avoid creating new parsers and formats -- along with the bugs and interop problems that come with them. 

Furthermore, if you go with a binary encoding, you're locking yourself into that set of values; if you want to add any, you'll need to mint new headers.

IOW, don't over-optimise for header size. Making these less wordy (e.g., `dest` instead of `destination`) will get you a long way. One of our aims for SH is to make future serialisations more efficient, so think of what you get with HPACK / QPACK as a floor, not a ceiling.

And, if you don't go binary, you _can_ split into multiple headers, which does give you better compression out of the dynamic table. That's because each **complete** header value is stored in the dynamic table; if there are many permutations of a single header, it can blow out the total dynamic header table size and cause them to be pushed out.

In your proposed approach, there are ~600 permutations of values, whereas if you split it out, there are 30 possible values. 

Even with the binary encoding (which again please don't do!), that's 30000 bytes of space in the dynamic table (assuming all permutations are seen on a connection) (see [here](https://httpwg.org/specs/rfc7541.html#dynamic.table.management) for how to calculate the size of a header for purposes of the dynamic table). 

If we use this style:

~~~
Sec-MD-User: ?T
Sec-MD-User: ?F
Sec-MD-Dest: audio
Sec-MD-Dest: audioworklet
Sec-MD-Dest: document
Sec-MD-Dest: embed
Sec-MD-Dest: empty
Sec-MD-Dest: font
Sec-MD-Dest: image
Sec-MD-Dest: manifest
Sec-MD-Dest: object
Sec-MD-Dest: paintworklet
Sec-MD-Dest: report
Sec-MD-Dest: script
Sec-MD-Dest: serviceworker
Sec-MD-Dest: sharedworker
Sec-MD-Dest: style
Sec-MD-Dest: track
Sec-MD-Dest: video
Sec-MD-Dest: worker
Sec-MD-Dest: xslt
Sec-MD-Dest: nested-document
Sec-MD-Site: same-origin
Sec-MD-Site: same-site
Sec-MD-Site: cross-site
Sec-MD-Mode: same-origin
Sec-MD-Mode: cors
Sec-MD-Mode: no-cors
Sec-MD-Mode: navigate
Sec-MD-Mode: websocket
~~~

I count it as a maximum of 1509 bytes in the dynamic table (again, assuming that all of the directives are seen). Much less impact, easy to parse and extensible to boot.

The default dynamic table size for the headers in one direction on a connection is [4,096 bytes](https://httpwg.org/specs/rfc7540.html#SettingValues). While many browsers increase that on the response side, it's not clear whether it's safe to assume that on the request side, as servers generally have more stringent per-connection memory constraints.

In actual use, the number of permutations seen on a connection will often be lower. However, from what I can tell from your use case, there will still be a fair amount of variance, no? Also, think about things like proxies that are mixing traffic from multiple clients onto one upstream connection.

The upshot here is that HTTP header compression is heavily optimised for header values that don't have a lot of variance on a connection. Don't fight it :)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3ctag/design-reviews/issues/280#issuecomment-438845441

Received on Wednesday, 14 November 2018 22:38:29 UTC