Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Poor Rendering Performance caused by CSS blur filter #703

Closed
MananTank opened this issue Dec 3, 2022 · 9 comments · Fixed by #710
Closed

Poor Rendering Performance caused by CSS blur filter #703

MananTank opened this issue Dec 3, 2022 · 9 comments · Fixed by #710

Comments

@MananTank
Copy link
Member

Problem

UI rendering performance is very poor and there are a lot of dropped frames when scrolling the page.

Root Cause

This is happening because filter: blur CSS is used to create the Aurora effect.

filter: blur filter is extremely taxing on CPU/GPU and should be avoided for creating Aurora effect ( because that requires applying the blur on a large element with a large blur radius )

If we remove the filter:blur CSS - rendering issues get resolved

See the attached video:

thirdweb-rendering-perf.mp4

Solution

Instead of creating the blur at runtime with CSS - just use an image

See https://cosmos.network/ for example


Tested on

Hardware: Macbook Pro 16" (2021) (M1 Pro)
Browser: Chrome 107

@jnsdls
Copy link
Member

jnsdls commented Dec 3, 2022

good find, would happily accept a PR that solves this while keeping the visuals the same / compatibly similar

@MananTank
Copy link
Member Author

@jnsdls I created an aurora image using Figma and a react sandbox to try it out

Check out this Sandbox ( Code )

What do you think?

@jnsdls
Copy link
Member

jnsdls commented Dec 4, 2022

@MananTank looks good! my only concern would be the possibility of the image "popping in" but it seems like you've largely solved that. I also think depending on how large the aurora is we may be able to prioritize the loading of it / embed it as base64 if absolutely necessary (or mark it as needing to be pre-loaded at least)

do you want to take a stab at making a PR to replace the css blur gradient with your aurora png approach?

@MananTank
Copy link
Member Author

@jnsdls

In the sandbox, the Image loading is quite slow because the request is sent after JS execution. I wanted to preload the image in the sandbox but I couldn't do it because Codesandbox changes the URL of the image request sent via JS compared to the one preloaded in the HTML file. The Image would be loaded much earlier in the Thirdweb's Next.js app. Also, the image I have used is not perfect - it's quite large (~500kB) and should be optimized to improve image loading

I have created an optimized image. If you check the sandbox's public folder - there are two versions of the image - a WebP (~100kB) and a PNG (~500kB). WebP looks almost as good as PNG one but it has some artifacts of compression (only visible when you look really closely).

I used the Google Chrome team's Squoosh App to optimize the PNG to WebP but I'm not 100% satisfied with the output so I used the PNG one for the demo sandbox. I would like to try out a few more tools to optimize the PNG size without compromising the quality. I don't trust Nextjs's Image component to do that properly for a gradient image, So we will have to do it manually.

Once we have an optimized image, We can start with the preloading approach, it should load the image super quickly (and also try the fade-in animation on the image like the sandbox to gracefully load the image) but if that does not feel good and we want to start rendering the UI with the image already there, then we can try out the base64 encoding approach and compare which feels the best ( and also test its impact on page load perf metrics like FCP and LCP )


I'm happy to do a PR for this - but I will be quite busy this week and may not be able to work on it this week. If you are fine with that, you can leave this one to me 👍

(However, If you do decide to implement it yourself, Make sure to add overflow:hidden style to your App container element (not the body!) to make sure there are no horizontal and vertical overflows caused by aurora images - refer to the sandbox for example )

@jnsdls
Copy link
Member

jnsdls commented Dec 5, 2022

All sounds good, will see if we get to it this week but likely won't so unless otherwise noted this one is all yours! 🎉

@jnsdls jnsdls mentioned this issue Dec 6, 2022
@jnsdls
Copy link
Member

jnsdls commented Dec 6, 2022

All sounds good, will see if we get to it this week but likely won't so unless otherwise noted this one is all yours! 🎉

I lied, merged it just now - but there's more to do on perf side for sure

@MananTank
Copy link
Member Author

MananTank commented Dec 6, 2022

@jnsdls 🚨

The Aurora blur appears to be much smaller than it used to be - It looks a bit weird now

image


Before: https://thirdweb-n9d5q39ri.thirdweb-preview.com/

After: https://thirdweb-ipuya0hks.thirdweb-preview.com/


Looks like the issue is the max-width: 66vw style shown below - removing it seems to be fixing this issue

image

image

@jnsdls
Copy link
Member

jnsdls commented Dec 6, 2022

fixed, thx - it does need a max width otherwise it ends up wayy to big on large resolutions but 66vw was too small

@MananTank
Copy link
Member Author

MananTank commented Dec 6, 2022

@jnsdls I think the current max-width:80vw is also a bit too small for regular desktop screen size. I would suggest doing the same thing that I have done in the sandbox and avoid setting max-widths altogether.

  • Put the image inside the section (element with max-width)
  • use width:200% + max-width:none on the image ( you can use continue using 400% for mobile/tablet )

This will make it so that the image has the proper size (X% of section width) no matter what the device-width

See the below video for Example:

aurora-resizable.mp4

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

Successfully merging a pull request may close this issue.

2 participants