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

DataTable: Advanced Filter performance issue (excess re-rendering) #5017

Open
djuuuuus opened this issue Oct 3, 2023 · 0 comments
Open

DataTable: Advanced Filter performance issue (excess re-rendering) #5017

djuuuuus opened this issue Oct 3, 2023 · 0 comments
Labels
Type: Performance Issue is performance or optimization related

Comments

@djuuuuus
Copy link

djuuuuus commented Oct 3, 2023

Describe the bug

Problem 1: If start typing inside of the Input field at the filter, then will trigger the re-render of React and as a consequence – the full grid will be rendered too! As a result, you get freeze while typing.

it relates to this topic from official documentation https://primereact.org/datatable/#advanced_filter
image

Here filtration passes only at BE side, not FE!

If you have a small dataset it works great, but if you have a medium-sized and larger dataset you will get performance issues.
image

Problem 2: If you type text inside of the filter input and do not apply the filter (Pressing at Apply button) - then the filter changes its icon without applying/sending a request to BE!

image

BTW to display this option - I have enabled this setting from React Chrome extension.
image

Also, I would say the browser version of React, TS, PrimeReact does not matter.

Reproducer

https://codesandbox.io/s/primereact-demo-reproduce-problem-lz5psk

PrimeReact version

10.0.2 latest at 03.10.2023

React version

18.x

Language

TypeScript

Build / Runtime

Vite

Browser(s)

Chrome 117 (I think this is an issue not dependent on browser)

Steps to reproduce the behavior

Problem 1 https://codesandbox.io/s/primereact-demo-reproduce-problem-lz5psk

  1. I just got this example from official documentation. DataTable - Filter - Advanced https://primereact.org/datatable/#advanced_filter
  2. Remove paginator from DataTable
    image
  3. use getCustomersXLarge
    image
  4. Drop other code for transparency....
  5. Start typing and get freezes!

All together + my comments, on why this happens
image

That is all!

Problem 2 the same link as for Problem 1 or original documentation example.

  1. Open any filter
  2. Type any symbols
  3. Filter toggle switched to applied, but the grid is not filtered and the request has not sent to BE yet.

image

My Comments, Thoughts and Questions.

Problem 1:
Comment: I fix re-renders via using uncontrolled components with form from https://react-hook-form.com/ which has a personal state (by this manual https://primereact.org/inputtext/#hookform).
Question: Could you tell me if this is the right approach, do we have other ways?

Problem 2:
Comment: After fix re-render I made 2 tries to fix this issue with side effect of applying a filter toggle button!
Question 1: Do we have ways to manage the toggling filter button?
Question 2: Do we have access to a full filter popup? ( I can manage only body content, not more)
Question 3: Do we have access to events when the popup is hiding/showing?
Question 4: How I can close popup by button from body of popup?

Short description:

  1. use separate uncontrolled components with form from https://react-hook-form.com/ which has a personal state.
  2. use the onBlur effect inside an uncontrolled component in two ways:
    3.1. using filterCallback to store data into grid (Try#1)
    3.2. manually storing data inside into grid into some property (Try#2)

Each of the two approaches (3.1 and 3.2) had personal disadvantages and each of them resolved re-render problem but side-effect with toggle of filter applying works wrong in both cases and works wrong in the original grid too.
Check it, please!

Try#1 to fix Problem 2 with re-render grid via using:

  1. uncontrolled component
  2. OnBlur event
  3. invocation filterCallback()

https://codesandbox.io/s/primereact-demo-try-1-y5hqdl

So, we need move logic for typing values into separate component state – uncontrolled (I hope I use correct terms).
I installed https://react-hook-form.com/ from this manual https://primereact.org/inputtext/#hookform

image

I created separate file, wrote code, passed dependencies and removed excess moments. Also, I did next changes:

  1. Create separate component ColumnFilterForm.tsx file.
  2. Install react-hook-form and use inside ColumnFilterForm.tsx.
    3.1 inside in ColumnFilterForm.tsx, according manual of using ReactHookForm I use InputTextarea component which using as built in store variable “field” of form
    3.2 At onBlurEvent I invoke callback of DataTable -> filterCallback which save data into grid, into it filters and rerender grid as result. It is not perfect solution, but at this moment we avoid freezes while client input text.
  3. Reuse ColumnFilterForm.tsx into App.js
  4. Override Apply button to invoke filterApplyCallback to apply all changes from all filters!

image

Summary: So, we have one side effect. When the client types something into the Input and clicks outside the Filter popup, the input value will be saved in some way because the onBlur effect has been called.

image

Try#2 to fix Problem 2 with re-render grid via using:

  1. uncontrolled component
  2. saving data inside of grid without side effect of toggle filter button via manual storing.
  3. add mark up for custom Apply button with using filterApplyCallback
  4. hide the original Apply button for filter popup

https://codesandbox.io/s/primereact-demo-try-2-xnzwwy

Here I found solution which also work, but I cannot close filter popup after the request is complete.

  1. I just store data inside of grid but by different way
    image
  2. hide apply button from filter popup
    image
  3. render my custom button into filter body with onClickEvent = filterApplyCallback.
    image

I don't know why but into SandBox in some way grid TOTALLY reloaded!
For me all works OK, The Filter popup just stays open.
I cannot get access to filter pop up to close it after the Apply button is pressed.

In the screen below I caught the moment when the filter was applied, the request was sent, grid was filtered correctly, and the filter popup was not hidden.

Summary: Everything is fine, but after submitting and clicking the Apply button (calling the filterApplyCallback), the popup does not close.

image

Looks like I need some event to manually close Filter popup or something else, but I have access only to the part of this popup – place where I can render my input…

This is screen from my project. All is OK, but I after applying pop up still showing.
image
image

I investigated datatable.esm.js and found applyFilter() which invokes hide().
Hide() - this is just private useState to which I don’t have access.
Possible, I need do the same and it makes me totally happy, but I don’t know how.
image

NOTES

FYI Sometimes it fails, but just update order of Import and it will work well.
image

Expected behavior

In general we have 2 problems:

  1. When typing symbols, re-render should be skipped, otherwise you will get freezes.

  2. If you type text inside of the filter input and do not apply the filter (Pressing at Apply button) - then the filter changes its icon without applying/sending a request to BE!
    NOTE: If we follow one of my suggested approaches (Try#1 or Try#2) when I am using uncontrolled components with different variations of using DataTable callback and tricks to store data I will expect the next behavior:

Case 1:
WHEN
1. Filter Popup opened
2. Text was typed
3. Apply button was clicked
THEN
1. Apply filtration
2. Filter grid (BE filtration request, just reinitialize grid, it works OK, skip this)
3. Update icon for Filter grid

Case 2:
WHEN
1. Filter Popup opened
2. Text was typed
3. Apply button was NOT clicked
4. Click occurs on one of the follow places:
click by close filter button
click by out space of filter
click by clear button
THEN
1. Typed data can be erased or left as is, it does not matter.
2. Filter should not be applied
3. Icon of Filter left as it - not applied

@djuuuuus djuuuuus added the Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible label Oct 3, 2023
@djuuuuus djuuuuus changed the title DataTable: Advanced Filter performance issue (excess renders grid while filtration). DataTable: Advanced Filter performance issue (excess renders grid while filtration) and toggle filter apply icon even when no filter is applied. Oct 3, 2023
@melloware melloware added Type: Performance Issue is performance or optimization related and removed Status: Needs Triage Issue will be reviewed by Core Team and a relevant label will be added as soon as possible labels Oct 3, 2023
@melloware melloware changed the title DataTable: Advanced Filter performance issue (excess renders grid while filtration) and toggle filter apply icon even when no filter is applied. DataTable: Advanced Filter performance issue (excess re-rendering) Oct 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Performance Issue is performance or optimization related
Projects
None yet
Development

No branches or pull requests

2 participants