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;
}
}
何か良い回避方法があればご指摘ください。