0

Demo

I am working on a table whose columns can be resized by dragging on the right side of any header element. In addition, the table is contained within a class grid, which is both draggable and resizable.

As shown in the demo, the actual functionality of these features work just fine. However, in Firefox, resizing columns and resizing the grid vertically cause significant performance lag. In fact, even IE has better performance for resizing the columns, although it still has lag on the grid vertical resize. That leaves Chrome, which doesn't have any performance issues whatsoever.

What can I do to make these resize actions responsive across all browsers and scalable for larger row numbers (say, 150 instead of the 50 in the fiddle)?

I suspect the issue lies in the alsoResize option for each header:

$('#header-D').resizable(
    {
        handles: "e",
        minWidth: 20,
        alsoResize: "td:nth-child(5)"
    }
);

I'm thinking the nth-child selector should be replaced with $("td").eq(5), although I can't find how to make that co-operate with JSON notation. Or perhaps there's a way to resize one td that automatically resizes all the corresponding td's below, but I'm not sure how this is feasible in this particular instance since I've been forced to use display:inline-block on the cells to make the table formatting work with the scrollbar and resizing functionality.

1 Answer 1

1

You are experiencing a lag while resizing because you are executing a large block of code that modifies the DOM every moment the grid is re-sized.

Modifying the DOM is an expensive operation and should be used sparingly. Every time the DOM is modified, the browser must re-draw the page to reflect your changes. There are definitely browser differences in how well they handle re-drawing the page.

Frankly, I'm very impressed that Chrome is able to handle all of your DOM modifications without a discernible lag. There is a lot of DOM modifying code in your resize handler function.

To fix this problem, you should only modify the DOM once the user has finished re-sizing the element. You can do this with a setTimeout and an extra pair of width and height variables. If the width and height variables from outside the setTimeout match the values retrieved inside the setTimeout, then you know that the user has stopped resizing the grid and you can safely modify the DOM.

Working JSFiddle

The significant changes in the above JSFiddle are:

The resize function handler:

        var rGridNewWidth = parseInt($('.grid').css("width"));
        var rGridNewHeight = parseInt($('.grid').css("height"));

        setTimeout(function() {    

            var gridNewWidth = parseInt($('.grid').css("width"));
            var gridNewHeight = parseInt($('.grid').css("height"));

            if (rGridNewWidth == gridNewWidth && rGridNewHeight == gridNewHeight) {

                $('.grid .container').css("height", gridFeedManagerContainerHeight +     (gridNewHeight-gridInitialHeight));
                    $('.grid .grid-table-container').css("width", gridTableWidth + (gridNewWidth-gridInitialWidth));
                    $('.grid .grid-table-container').css("height", gridTableHeight + (gridNewHeight-gridInitialHeight));

                $(".grid-snap-outer").css("width", parseInt($(".grid").css("width")));
                $(".grid-snap-outer").css("height", parseInt($(".grid").css("height")));

                $(".button-ok").css("width",gridTableWidth + (gridNewWidth-gridInitialWidth));
                $('.grid .grid-table-header-container').css("width", gridTableHeaderWidth + (gridNewWidth-gridInitialWidth));

                $(".corner-right").css("left", cornerOffset + (gridNewWidth-gridInitialWidth));
            }

        }, 150);

Setting the grid overflow to hidden:

overflow:hidden;

In my example, I set the delay on the setTimeout to 150 milliseconds. This means that if the user stops resizing the grid for 150 milliseconds, then the grid will resize.

Sign up to request clarification or add additional context in comments.

2 Comments

I tried your JSFiddle and played around with the setTimeout value (from 1ms to 1000), but in each case the performance didn't really improve
@Amalgam54 There is a significant performance difference for me. In your first example, the whole page freezes up and I can't even continue resizing. In my example, it will actually resize smoothly. If you wanted to do further optimization, you could store a reference to $('.grid') outside of the handler function. That you save you the expense of DOM traversal to find the element with class .grid every time the resize handler is invoked. Updated fiddle: jsfiddle.net/MAEvS/631

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.