Function visible() - Very slow

Function visible() - Very slow

magic16magic16 Posts: 8Questions: 1Answers: 0

Hi team,

I'm working on a dashboard interface with dataTable in ajax. I created a form with a select list to select the columns (80+ columns) what you want to show.
The PHP ajax check the columns to show, the rights on the columns and the xhr ajax return dataTable datas and the columns to show/hide.
The ajax call response in 370ms (50 rows) but the draw of table is during 4/5s. I desactivated my each on the visibility and the draw of table is instant.

Does the visible function have performance issues? I created this exemple on jsFiddle: https://jsfiddle.net/m45gy64c/5/ to show the problem.

This question has an accepted answers - jump to answer

Answers

  • magic16magic16 Posts: 8Questions: 1Answers: 0
    edited December 2017

    I continued my research, and I found the problem on the visible() function:

    _api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {
        var ret = this.iterator( 'column', function ( settings, column ) {
            if ( vis === undefined ) {
                return settings.aoColumns[ column ].bVisible;
            } // else
            __setColumnVis( settings, column, vis );
        } );
    
        // Group the column visibility changes
        if ( vis !== undefined ) {
            // Second loop once the first is done for events
            this.iterator( 'column', function ( settings, column ) {
                _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
            } );
    
            if ( calc === undefined || calc ) {
                this.columns.adjust();
            }
        }
    
        return ret;
    } );
    

    It's the part on "Group the column visibility changes". If I comment this part the draw is fast:

        // Group the column visibility changes
        /*if ( vis !== undefined ) {
            // Second loop once the first is done for events
            this.iterator( 'column', function ( settings, column ) {
                _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
            } );
    
            if ( calc === undefined || calc ) {
                this.columns.adjust();
            }
        }*/
    } );
    

    Do you have an idea on the problem ?

  • magic16magic16 Posts: 8Questions: 1Answers: 0
    edited December 2017
    if ( calc === undefined || calc ) {
        this.columns.adjust();
    }
    

    For skip this part, there is the second parameter of visible redrawCalculations that we can set to false. So the call of callback column-visibility is the problem.

    Is there a possibility to add a parameter on visible to skip the callback fire ?

  • allanallan Posts: 62,315Questions: 1Answers: 10,225 Site admin

    Call column().visible() with redrawCalculations set to false and then call columns.adjust() when you've finished the loop: https://jsfiddle.net/m45gy64c/6/

    Allan

  • magic16magic16 Posts: 8Questions: 1Answers: 0

    Thank for your answer but set the false on redrawCalculations do not resolve the problem of slowing. I don't want to use columns.adjust() in my case but only show/hide my columns in Ajax call like this:

    ajax: function (data, callback, settings) {
        var _form = $('form[name="filters"]');
        $.extend(data, _form.serializeAssoc());
        $.ajax({
            url: 'myurl',
            type: 'post',
            data:  JSON.stringify(data),
            dataType: 'json',
            contentType: "application/json; charset=utf-8",
            success: function (json) {
                var _i = 0;
                _table.columns().every(function() {
                    this.visible(json.columns[_i]['visible'], false);
                    _i++;
                });
                callback(json);
            }
    }
    

    But the problem of slowing appears after the first call when I use draw()

  • magic16magic16 Posts: 8Questions: 1Answers: 0

    It's not a problem on Datatable but on the plugin fixHeader using this callback:

    _fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis, calc] );
    
  • magic16magic16 Posts: 8Questions: 1Answers: 0

    An exemple here on the click on the button "Reload": https://jsfiddle.net/m45gy64c/9/

  • allanallan Posts: 62,315Questions: 1Answers: 10,225 Site admin
    Answer ✓

    Agreed - FixedHeader is running somewhat slowly here since the column visibility is being triggered once for every column.

    What you could do is to use columns().visible() to group the changes. Then it will only be triggered twice - once to make all the columns that should be visible, visible. And then another one for all the hidden columns. That would be far more efficient.

    Allan

  • magic16magic16 Posts: 8Questions: 1Answers: 0

    Thanks for your answer. It's not perfect but it's more efficient. And I think we can't do better, except if I disable fixHeader ...

  • magic16magic16 Posts: 8Questions: 1Answers: 0
    edited January 2018

    Do you know why columns().visible() with parameter true is slow and isn't slow with false ? With the parameter false, there is a problem of scroll top.

    You can see an exemple here: https://jsfiddle.net/m45gy64c/12/.

  • allanallan Posts: 62,315Questions: 1Answers: 10,225 Site admin

    It takes about 1 second on my computer when pressing the reload button in that example. It is slower like that since it needs to layout 80 columns, calculate their width and then apply them to the fixed header row.

    If you hide all columns, then there are no columns to layout and calculate their width, so yes, I would expect that to be a lot faster.

    Allan

This discussion has been closed.