LoginSignup
4
4

More than 5 years have passed since last update.

非表示の要素があるjQuery UI Sortableは重い

Posted at

jQuery-ui便利ですよね。
jQuery-uiのsortableで、順番を入れ替えられる様に実装していたのですが、検証中、チェックボックスのオンオフで一部要素を非表示にする機能と組み合わせるとドラッグが重いと言うチケットが回ってきました。

原因を調査した所、sortable.jsで最初に起動する_mouseStartメソッドの中で呼ばれているrefreshPositionsメソッドの以下の場所が重い用でした。

            if ( !fast ) {
                item.width = t.outerWidth();
                item.height = t.outerHeight();
            }

非表示の要素をouterWidth()すると、他のより重い模様。
実際、以下の様な検証HTMLを作って確かめて見ると顕著でした

<html lang="ja">
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script>
$(function () {
    var display = $("#display");
    var hide = $("#hide");
    hide.hide();
    console.time("display");
    for ( var i = 0; i < 1000; i++ ) {
        display.outerHeight();
    }
    console.timeEnd("display");
    console.time("hide");
    for ( var i = 0; i < 1000; i++ ) {
        hide.outerHeight();
    }
    console.timeEnd("hide");
});
        </script>
    </head>
    <body>
        <hide id="display"> テスト </div>
        <div id="hide"> テスト </div>
    </body>
</html>

idがdisplayの要素は表示したまま、idがhideの要素は非表示にしたまま1000回ずつouterHeightを呼び出した所

display: 34.49ms
hide: 419.26ms

という結果になり、10倍の速度差が有りました。

回避方法思いつかなかったので、sortable.jsを以下の様にして対応しました。

            if (!fast) { 
                if ( t.is(':visible') ) {
                    item.width = t.outerWidth();
                    item.height = t.outerHeight();
                } else {
                    item.width = 0;
                    item.height = 0;
                }
            }

何か良い回避方法があればご指摘ください。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4