Giveth / giveth-dapps-v2

This project is the aggregation of GIVeconomy and Giveth.io DApps in a single repo
https://staging.giveth.io
GNU General Public License v3.0
54 stars 32 forks source link

ImproveWebsite Rendering #4122

Open MohammadPCh opened 1 month ago

MohammadPCh commented 1 month ago

There are three primary types of rendering: client-side, server-side, and static. Here’s a detailed look:

1. Client-Side Rendering

In client-side rendering, pages are rendered in the browser, and the server plays no role in rendering. This approach can create SEO challenges because search engine bots require pre-rendered pages for indexing. If we rely solely on client-side rendering, our pages may not be indexed effectively by search engines.

2. Server-Side Rendering

With server-side rendering, the server renders the page on each request and sends it to the client. This ensures that search engines can index the website properly.

3. Static Rendering

Similar to server-side rendering, but the pages are rendered once at build time and served as static HTML, with the option to periodically rerender them (e.g., every 10 minutes).

Currently, our website primarily uses server-side rendering for most of our pages (Home Page, Projects Page, Project Page, etc.). Let's consider the Projects Page as an example:

  1. The user navigates to https://giveth.io/projects/all.
  2. The Vercel server fetches data from our server (Impact Graph).
  3. The Vercel server builds the Projects page and returns it to the client.
  4. The browser displays the rendered site to the user.
  5. If the user's wallet is connected, the client (browser) sends another request to the Impact Graph server to fetch project data, which includes user-specific data for each project (e.g., liked? boosted?).
  6. The client re-renders the page again.

As illustrated, the page is rendered twice within 2-3 seconds for a single request. Improving this process could enhance performance and user experience. But how can we do it? Let's explore potential improvements.

Here are my suggestions for enhancing our website's performance:

  1. Use Static Pages Instead of Server-Side Rendering

    • Description: Instead of rendering on each request, we can switch to static pages. This change would cut the backend requests by half and eliminate server-side rendering delays. For users whose wallets are not connected, they will see the page as it was last updated (based on our refresh timing), which might be slightly outdated.
    • Benefits: Increases loading speed since no rendering is required for users without connected wallets.
    • Considerations: This approach requires confirmation from the Project Manager as it impacts how up-to-date the content users see.
  2. Improve Client-Side Rendering

    • Description: Update only the necessary parts of the project cards when a user’s wallet is connected, rather than re-rendering the entire page.
    • Benefits: Reduces processing and enhances user experience by minimizing the amount of data that needs to be re-rendered, leading to quicker interactions.
  3. Redesign Project Cards

    • Description: Consider removing some elements from the project cards that may not be essential for users to see at a glance. This could simplify the information presented and improve user engagement. it makes the db calculations simpler.
    • Considerations: This adjustment requires collaboration and confirmation from both the Project Manager and design team to ensure the new design meets user needs and expectations.

cc: @laurenluz @divine-comedian @jainkrati @MoeNick @aminlatifi @mhmdksh @mosaeedi

aminlatifi commented 1 month ago

Thanks @MohammadPCh I support your ideas. Regarding the project card, we can provision some optimized view in the backend to update it only on events. Then, fetching data from that will not be costly. So, we can disable those so far but have program to return them in an efficient way.

jainkrati commented 1 month ago

@MohammadPCh pls share screenshot of perf rendering so that we can estimate how much improvement we get if we spend efforts on this immediately

divine-comedian commented 1 month ago

@MohammadPCh - what are some examples with static rendering where information could become outdated?

Donation Table for projects? Recurring Donations page for users? Instant Boosting sorting for projects page?

How granular can this approach be? Can we only define static rendering for certain pages or it has to be one approach for the whole website?

MohammadPCh commented 1 month ago

Server-Side rendering: image Static page:

Screenshot 2024-05-06 at 10 56 00 PM

As illustrated, the response time has decreased from 2.04s to 12ms. cc: @jainkrati

MohammadPCh commented 1 month ago

@divine-comedian Let's apply this concept specifically to the projects page, considering a refresh interval of 10 minutes. For instance, attributes like the total amount, number of contributors, and estimated matching amount are calculated approximately every 10 minutes. Therefore, they reflect data that might be up to 10 minutes old.

Exactly, it's a route-specific concept. Therefore, for each route, we can make a decision among these three concepts based on our specific needs and considerations.

divine-comedian commented 1 month ago

Wow this is crazy! I think for the all and qf projects page this would be huge! We'll need to consider instant boosting requirements, I would recommend if we go the static rendering route (which it seems like we should) we try to re-render every 5 minutes.

How does it handle with pagination? Will it be able to handle loading more projects just as fluidly?

Then for handling state changes such as for a logged in user, we could make it render via client-side?

MohammadPCh commented 1 month ago

@jainkrati @divine-comedian Here's a simple demonstration: https://giveth-dapps-v2-git-static-page-test-givethio.vercel.app/ It only contains the /all address, created solely for testing purposes. compare it with staging.

MohammadPCh commented 1 month ago

@divine-comedian we need to consider the edge cases on pagination. For instance, if a project is added to the top of the list, we might inadvertently display duplicate project cards.

divine-comedian commented 1 month ago

@jainkrati @divine-comedian Here's a simple demonstration: https://giveth-dapps-v2-git-static-page-test-givethio.vercel.app/ It only contains the /all address, created solely for testing purposes. compare it with staging.

The difference between staging is only marginal in loading speed. I think we'll need to see how it compares under heavy load.

jainkrati commented 1 month ago

THanks for sharing the perf comparison numbers @MohammadPCh ! Can you pls list down which all pages can be moved to static rendering in 1st PR.

Also can you identify which components currently nested in Client Side rendered pages can be created as Server Side rendered ?

MohammadPCh commented 1 month ago

@divine-comedian This change would cut the backend requests by half for showing(rendering) the projects page. I think it would be helpful.

MohammadPCh commented 1 month ago

@divine-comedian @maryjaf, here is the preview link for testing static pages. You can test /projects, /qf, and their sub-URLs: Preview Link

divine-comedian commented 1 month ago

Thanks @MohammadPCh

I tested around today and still couldn't find any serious improvement to loading speeds. I think it's very much tied up to back-end performance issues.

My opinion is we need to fix the back-end performance and then come back to this and do more testing. If we make these changes without noticing any notable improvement in performance AND introduce new bugs into the website that would be bad.

jainkrati commented 1 month ago

Need to monitor before and after performance metrics for Static rendering to ensure that only BE is responsible for the latencies.

As per @divine-comedian we should first fix BE and then FE perf