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

Chrome finally ships Accept-Encoding: zstd — Please update example #70

Open
jab4 opened this issue Apr 1, 2024 · 3 comments
Open

Comments

@jab4
Copy link

jab4 commented Apr 1, 2024

Hi and late Happy Easter all!

As the title suggests, no issue in the buggy sense.

I ran some benchmarks against a 4 MB HTML file:

  # none......:  4,039,229 Bytes;  100 requests in   3.16 secs  (avg=0.0316 s per req)
  # gzip......:  1,290,963 Bytes;  100 requests in  17.65 secs  (avg=0.1765 s per req)
  # obgz......:  1,290,963 Bytes;  100 requests in  17.27 secs  (avg=0.1727 s per req)
  # zstd1.....:  1,392,549 Bytes;  100 requests in   4.01 secs  (avg=0.0401 s per req)
  # zstd2.....:  1,310,025 Bytes;  100 requests in   4.32 secs  (avg=0.0432 s per req)
  # zstd3.....:  1,240,800 Bytes;  100 requests in   4.45 secs  (avg=0.0445 s per req)
  # zstd4.....:  1,222,309 Bytes;  100 requests in   4.76 secs  (avg=0.0476 s per req)
  # zstd5.....:  1,195,749 Bytes;  100 requests in   5.84 secs  (avg=0.0584 s per req)
  # zstd6.....:  1,157,140 Bytes;  100 requests in   6.94 secs  (avg=0.0694 s per req)
  # zstd7.....:  1,133,898 Bytes;  100 requests in   8.18 secs  (avg=0.0818 s per req)
  # zstd8.....:  1,120,307 Bytes;  100 requests in   9.71 secs  (avg=0.0971 s per req)
  # zstd9.....:  1,115,600 Bytes;  100 requests in   9.80 secs  (avg=0.0980 s per req)
  # zstd10....:  1,095,873 Bytes;  100 requests in  12.33 secs  (avg=0.1233 s per req)
  # zstd11....:  1,082,522 Bytes;  100 requests in  18.20 secs  (avg=0.1820 s per req)
  # zstd12....:  1,081,317 Bytes;  100 requests in  21.91 secs  (avg=0.2191 s per req)
  # zstd13....:  1,059,720 Bytes;  100 requests in  52.40 secs  (avg=0.5240 s per req)
  # zstd14....:  1,044,099 Bytes;  100 requests in  67.91 secs  (avg=0.6791 s per req)
  # zstd15....:  1,036,078 Bytes;  100 requests in  87.37 secs  (avg=0.8737 s per req)
  # zstd16....:    983,006 Bytes;  100 requests in 103.78 secs  (avg=1.0378 s per req)
  # zstd17....:    980,923 Bytes;  100 requests in 115.09 secs  (avg=1.1509 s per req)
  # zstd18....:    972,316 Bytes;  100 requests in 141.62 secs  (avg=1.4162 s per req)
  # zstd19....:    971,972 Bytes;  100 requests in 145.05 secs  (avg=1.4505 s per req)
  # zstd20....:    971,972 Bytes;  100 requests in 146.45 secs  (avg=1.4645 s per req)
  # zstd21....:    971,972 Bytes;  100 requests in 148.13 secs  (avg=1.4813 s per req)
  # zstd22....:    971,962 Bytes;  100 requests in 152.34 secs  (avg=1.5234 s per req)

Kindly suggest updating your README's example section to include output buffering:

# Serve ZSTD compressed PHP pages to modern 2024 web browsers:
# Place this snippet *before* any of your HTML output begins.
if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'zstd')) {
    header("Content-Encoding: zstd");
    ob_start(function(&$data) {
        return zstd_compress($data, 3); # level 3 is default, max. and slowest is 22
    });
} else {
    ob_start('ob_gzhandler'); # fallback for older browsers
}

Perhaps @remicollet could put some soft pressure on the PHP core team to bundle this extension? 🚀

Thanks!

@BelleNottelling
Copy link

I'm quite happy chromium browsers now announce that they accept zstd. It's far faster than either gzip or brotli.

Of course, based on my own testing brotli is still a great upgrade over gzip both in terms of speed and compression ratio, but zstd offers very similar compression ratios to brotli while being significantly faster which makes it the clear winner in all cases in my eyes.

I've actually gone ahead and created my own replacement for PHP's ob_gzhandler function which is able to auto select between zstd, brotli, gzip, and deflate content encoding based on the server it's running on and the client that's connecting to it.
https://github.com/HostByBelle/CompressionBuffer

Here's the PHP developer server sending zstd compressed output to chrome:
image

I haven't yet made a release of CompressionBuffer as it's only had minimal testing done plus no unit tests written, but the logic behind it is pretty straightforward and PHPStan is happy on it's highest level.

Although it's not super important for just an example, I personally include it over the above code example as that one is what I would consider incomplete. At the very least it would probably be worth mentioning that false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'zstd') will also trigger if the client is trying to inform the server to not use zstd encoding, along with suggesting that Vary: Accept-Encoding be sent in the headers for caching compatibility.

Either way, thank you @kjdev for building both this and the brotli extension! They are great additions to the PHP ecosystem. I for one am exciting knowing that some clever handling of the output buffer means PHP apps can utilize zstd compression before either NGINX or Apache get official support for it. Awesome!

@jab4
Copy link
Author

jab4 commented Apr 10, 2024

Thanks @BelleNottelling, much appreciated!

@BelleNottelling
Copy link

You're welcome @jab4!

Feel free to submit issues if you come across any issues & notice potential improvements.

Hope it comes in handy :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants