CodeDredd / h3-compression

Adds compression to h3 requests (brotli, gzip, deflate)
MIT License
69 stars 2 forks source link

Compression with Nuxt swr cache #5

Open YannickArmspach opened 11 months ago

YannickArmspach commented 11 months ago

Environment

Reproduction

https://github.com/YannickArmspach/nuxt3-h3-compression

Describe the bug

Hello,

I try to activate compression with Nuxt cache without success.

Compression works fine by default in nuxt (ssr) with NitroPlugin integration: image

But if I activate the nuxt cache (swr), the cache is returned but without compression: image

Is there another solution (hook?) to also compress the cache returned by nuxt?

Additional context

No response

Logs

No response

YannickArmspach commented 11 months ago

Okey, the solution was in my question :D it works with the "beforeResponse" hook:

nitro.hooks.hook('beforeResponse', async (event, response) => {
    await useCompression(event, response)
})

@CodeDredd This may be a better example for your documentation because it works with the cache. Not ?

CodeDredd commented 6 months ago

I think your idea sounds good. But i am no nitro expert. I don't know if that has any down sides using it that way.

bernhardberger commented 4 months ago

I think your idea sounds good. But i am no nitro expert. I don't know if that has any down sides using it that way.

in conjunction with another issue (swr not handling Buffer steams correctly, see [need to find link]) I think one would need to check first if the body in the response is a Buffer or serialized data as we wouldn't want to gzip binary data. I also think we should be careful not to touch the internal _nuxt routes.

Other than that I think it's fine.

PS: I agree, you need that hook with SWR. Might actually be the proper way to do it.

infabo commented 4 months ago

Okey, the solution was in my question :D it works with the "beforeResponse" hook:

nitro.hooks.hook('beforeResponse', async (event, response) => {
    await useCompression(event, response)
})

@CodeDredd This may be a better example for your documentation because it works with the cache. Not ?

Using the beforeResponse hook comes with one major drawback: it is executed on every single response. You don't notice on a powerful CPU. But we noticed that our response time went through the roof (150ms without -> 1200ms with compression).

bernhardberger commented 4 months ago

I think the reason it doesn't fire in SWR context is this:

https://github.com/CodeDredd/h3-compression/blob/main/src/helper.ts#L18

const encoding = getRequestHeader(event, 'accept-encoding')

Pretty sure SWR cache requests are without accept-encoding headers (which makes sense since they're basically server-side requests).

The proper way would probably to generate all 3 and then check in the nitro onBeforeResponse hook for client accept-encoding headers and return the cached version accordingly.

CodeDredd commented 4 months ago

When i got some time i am gonna try out what i see with swr. @bernhardberger I dont think generating all 3 compressions is a good idea since this costs resources.

Using the beforeResponse hook comes with one major drawback: it is executed on every single response. You don't notice on a powerful CPU. But we noticed that our response time went through the roof (150ms without -> 1200ms with compression).

If you use beforeResponse you can use useCompressionStream. I think this shouldn't impact response time that much.

bernhardberger commented 4 months ago

When i got some time i am gonna try out what i see with swr. @bernhardberger I dont think generating all 3 compressions is a good idea since this costs resources.

If you use beforeResponse you can use useCompressionStream. I think this shouldn't impact response time that much.

I think @infabo could share some insights here, maybe even to the extent of a PR?

andrewspy commented 1 month ago

@CodeDredd using beforeResponse with useCompressionSteam does not work for me with SWR cache on Nuxt v3.13.2. I have to revert to useCompression.

When i got some time i am gonna try out what i see with swr. @bernhardberger I dont think generating all 3 compressions is a good idea since this costs resources.

Using the beforeResponse hook comes with one major drawback: it is executed on every single response. You don't notice on a powerful CPU. But we noticed that our response time went through the roof (150ms without -> 1200ms with compression).

If you use beforeResponse you can use useCompressionStream. I think this shouldn't impact response time that much.