Bug 273818 - PerformanceNavigationTiming decodedBodySize larger than encodedBodySize if resource is not encoded
Summary: PerformanceNavigationTiming decodedBodySize larger than encodedBodySize if re...
Status: REOPENED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Page Loading (show other bugs)
Version: Safari 17
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-05-07 04:41 PDT by Gernot Raudner
Modified: 2024-07-18 03:45 PDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gernot Raudner 2024-05-07 04:41:54 PDT
On a resource that has no encoding headers specified (e.g. no gzip, example website: https://gernotraudner.at), Safari 17.4.1 reports the `decodedBodySize` smaller than the `encodedBodySize`. In this specific example, the `decodedBodySize` is 294, while the `encodedBodySize` is 303. I can guarantee the server does no encoding, and it doesn't respond with any encoding headers. This seems to work fine with encoded resources though (`encodedBodySize` being smaller than `decodedBodySize`, as expected). So, to reproduce, simply

1. Open the network tab in devtools
2. Go to https://gernotraudner.at
3. enter `const navtimings = performance.getEntriesByType("navigation")[0]; console.log("encoded: ", navtimings.encodedBodySize, ", decoded: ", navtimings.decodedBodySize);` in the console
4. check the network tab and select the resource, check the sizes

In #3 you can see that the `encodedBodySize` is larger than the `decodedBodySize`, which cannot be the case.
Additionally, in #4 you can see that the "Bytes Received" of the body are 303B, while the resource size is 0.29KB. The tab also shows that compression is 0.97x (making it actually larger?).

I'm not 100% certain, but I think this used to work in Safari 16.
Comment 1 Alex Christensen 2024-05-08 07:43:11 PDT
That 9 byte difference seems to be from the HTTP/2 framing overhead: https://datatracker.ietf.org/doc/html/rfc9113#section-4.1
This is arguably correct, but now you know what that's from.
Comment 2 Gernot Raudner 2024-05-08 08:02:30 PDT
Maybe my example was bad, or this is a separate issue, not sure... I also have a webserver that doesn't support HTTP/2, and the difference is, interestingly enough, 18 bytes (35910 compressed versus 35892 decompressed).

It doesn't really solve my issue either, because I compare the data I generate on the server with the data I receive on the client, and even though the body matches, as well as the encodedBodySize (of course, since it's not encoded), but the decodedBodySize is invalid. I don't really see how this is arguably correct in the context of the Performance API. It might be correct in the context of HTTP frames, but this shouldn't be linked to the Performance API, should it?
Comment 3 Alex Christensen 2024-05-08 09:18:44 PDT
Could you send me a link to that server?  Feel free to email it to me by clicking my name if you don't want to post it on this public bugzilla.
Comment 4 Gernot Raudner 2024-07-18 03:45:33 PDT
sorry for not replying for so long. i built a little reproducer: https://github.com/DerGernTod/safari-decoded-body-size/tree/main

the server is serving http/1.1 so the http/2 framing overhead you mentioned doesn't apply. also, wouldn't the "bodySize" only refer to the body, and not to the framing?