Our blazing fast Grid component built with pure JavaScript


Post by ankamomkar »

Hi Team
I am trying to filter out the data if my data conisists 3000+ pools then it is taking more time to filter so it is effecting the performance issue.Below is my code

const poolsSearch = debounce((props: any) => {
    const { source, value } = props;
    const valueLower = value.trim().toLowerCase();
    const poolNoResources = intl.formatMessage({ id: 'PoolNoResources' }).toLowerCase();
    const grid = source.up('grid');
    const store = grid.store;
    const container = source.up('container');
    const { labelField } = container.widgetMap;
    const totalPools = poolsGridRows.length;
    store.clearFilters();
    if (!valueLower) {
      labelField.html = intl.formatMessage({ id: 'ShowingPools' }, { 0: totalPools });
      return;
    }
    store.filterBy((record: any) => {
      const recordNameLower = record.Name.toLowerCase();
      if (filterBy === 'filterResources') {
        return record.isResource && recordNameLower !== poolNoResources && recordNameLower.includes(valueLower);
      }
      return !record.isResource && recordNameLower.includes(valueLower);
    });
    requestAnimationFrame(() => {
      labelField.html = intl.formatMessage({ id: 'ShowingOutOfTotalPools' }, { 0: store.getCount(), 1: totalPools });
    });
  }, 100);
  {
              type: 'text',
              cls: ' b-pool-search b-textfield-custom',
              ref: 'searchField',
              triggers: {
                plug: {
                  cls: 'b-fa b-fa-search b-fieldtrigger',
                  align: 'start',
                },
              },
              listeners: {
                input(props: any) {
                  poolsSearch(props);
                },
              },
            },

Post by Animal »

Don't unfilter then filter the store. Both will cause a UI updte of course.

Use

store filter({
    id : 'my-unique-filter-id',
    filterBy((record: any) => {
      const recordNameLower = record.Name.toLowerCase();
      if (filterBy === 'filterResources') {
        return record.isResource && recordNameLower !== poolNoResources && recordNameLower.includes(valueLower);
      }
      return !record.isResource && recordNameLower.includes(valueLower);
    });

That will replace any previous filter that was added by that id.

But thst should be pretty quick. If it's not, use the browser Performance tab and see where the time goes.


Post by ankamomkar »

HI animal
The above code is working as expected but when I input any value it takes time to see the value in UI. Is there any solution instead of debouncing is there any other solution not knowing the lag between the keyboard and UI?

Thanks
Omkar


Post by Animal »

Well, that "debounce" thing.

See how the standard way of delaying a filter event from tying is done in our examples: https://www.bryntum.com/products/scheduler/examples/filtering/

Screenshot 2024-08-07 at 16.16.04.png
Screenshot 2024-08-07 at 16.16.04.png (629.21 KiB) Viewed 265 times

Post by ankamomkar »

Hi animal
In the listeners I am passing input instead of input can we pass any other method to capture the input value because while passing the input it is taking time to capture the value and to show in the UI.

 tbar: {
      cls: 'b-pool-grid-toolbar',
      items: [
        {
          type: 'container',
          style: 'margin-top:auto',
          items: [
            {
              type: 'text',
              cls: ' b-pool-search b-textfield-custom',
              ref: 'searchField',
              triggers: {
                plug: {
                  cls: 'b-fa b-fa-search b-fieldtrigger',
                  align: 'start',
                },
              },
              listeners: {
                input(props: any) {
                  poolsSearch(props);
                },
              },
            },
            {
              type: 'label',
              ref: 'labelField',
              cls: 'b-pool-search-label',
              content: intl.formatMessage({ id: 'ShowingPools' }, { 0: poolsGridRows.length }),
            },
          ],
        },
        }

Post by Animal »

As illustrated in https://www.bryntum.com/products/scheduler/examples/filtering/ and the scheenshot I posted: Do not use the input event. It fires immediately upon keyboard input.

Use the change event, and decide upon your own keyStrokeChangeDelay to give a little delay from typing to filtering.


Post by ankamomkar »

Hi animal
I used your code and it is working as expected but when I am trying to enter 1st letter it is working as expected but later with the second letter and removal of the letter I am seeing a delay in seeing the value in UI.

{
              type: 'text',
              cls: ' b-pool-search b-textfield-custom',
              ref: 'searchField',
              keyStrokeChangeDelay: 100,
              triggers: {
                plug: {
                  cls: 'b-fa b-fa-search b-fieldtrigger',
                  align: 'start',
                },
              },
              listeners: {
                change(props: any) {
                  const { source, value } = props;
                  const valueLower = value.trim().toLowerCase();
                  const poolNoResources = intl.formatMessage({ id: 'PoolNoResources' }).toLowerCase();
                  const grid = source.up('grid');
                  const store = grid.store;
                  const container = source.up('container');
                  const { labelField } = container.widgetMap;
                  const totalPools = poolsGridRows.length;
                  const filterId = 'pools-search-filter';
                  store.filter({
                    id: filterId,
                    filterBy: (record: any) => {
                      const recordNameLower = record.Name.toLowerCase();
                      if (filterBy === 'filterResources') {
                        return (
                          record.isResource &&
                          recordNameLower !== poolNoResources &&
                          recordNameLower.includes(valueLower)
                        );
                      }
                      return !record.isResource && recordNameLower.includes(valueLower);
                    },
                  });
                  labelField.html = valueLower
                    ? intl.formatMessage({ id: 'ShowingOutOfTotalPools' }, { 0: store.getCount(), 1: totalPools })
                    : intl.formatMessage({ id: 'ShowingPools' }, { 0: totalPools });
                },
              },
            },

Post by alex.l »

Do you see that problem here? https://www.bryntum.com/products/scheduler/examples/filtering/
Please provide steps to reproduce it using our demo or attach runnable code.

Did you try to profile it in DevTools to see what exactly took that time?

All the best,
Alex


Post Reply