Add options to compress callback request payload - #3925
Conversation
|
Doesn't dash already support this via the Maybe adding support for fast api's compression directly in dash could be helpful too: https://fastapi.tiangolo.com/advanced/middleware/#gzipmiddleware And ideally you don't really want dash running compression on the main thread in most cases. Having the server do it instead is generally better/faster/more flexible, such as nginx https://docs.nginx.com/nginx/admin-guide/web-server/compression/ |
[…]
This was also my first thought when I looked into this! Unfortunately, all these standard compression mechanism will only work for the HTTP response from the server to the client downloading the data. This PR would address the other direction when uploading the data which is not covered by the standard means. I enhanced the description to make this a little more clear. |
|



This implements an option to compress the payload of a callback's request (see #3924).
This would be useful when transmitting large amounts of data from the client-side to the server-side (server to client is already covered by standard HTTP compression via Content-Encoding).
The basic idea is that the server side callbacks can be marked for payload compression with two parameters
compress_payload: boolandcompress_threshold: intthat indicate if the request body should be compressed and the minimum size of body before compressing.On the client side the JSON of the body is constructed as before. When the callback is marked for request compression and the request body exceeds the compression threshold, the body is compressed and send as binary with the header
Content-Encoding=gzip.On the server side the request is checked for the content encoding header and the request body is decompressed when necessary.
Advantage of this solution is that it does not depend on compressing individual properties and can be used without compromising client-side callbacks to be able to access properties.
Downside is that a new dependency has to be introduced to actually compress the payload in the browser (I opted for https://github.com/101arrowz/fflate).
I would expect this change to be able to really speed-up application performance for use-cases where loads of data are transmitted and would love to get some feedback on this. I did some experiments and observed roundtrip response time improvements up to 10x. Some numbers showing the average speed-up ratio of the roundtrip response time depending for different connections and the payload sizes.
Compression almost never hurts the roundtrip response times which is why I would go for a default
compress_thresholdof around 5 KB - 50 KB (but keepcompress_payload=Falseper default).Naming of the parameters could be adjusted if we want to emphasise that they only apply to the request part of the callback and not the response. Might also be an option to have a single parameter that takes a
dict.This seems to work fine across all backends (flask, fastapi, and quart).
I first tried sending the compressed payload as Base64-encoded data inside JSON, but sending it as raw binary is significantly more efficient. It is also less proprietary, avoids adding a base64 package to the dash renderer, and allows a reverse proxy to decompress the payload transparently (which would reset/remove the content encoding header).
Contributor Checklist
compress_payloadandcompress_thresholdto callbacksoptionals
CHANGELOG.md