blog スタッフブログ
HOME > スタッフブログ > CMS > PowerCMS > PowerCMSで記事グループに表示される記事が増えた時のJavaScriptパフォーマンス改善案

PowerCMSで記事グループに表示される記事が増えた時のJavaScriptパフォーマンス改善案

PowerCMS 4 / PowerCMS 5に記事グループを作成する機能がありますが、記事数が膨大(例えば5,000件)になるとフロントエンドの処理にも時間がかかるようになります。具体的には画面左側の「記事の一覧」をドラッグ&ドロップで並び替えたり、画面右側の「グループの記事」に項目を移動したりする機能を実現する jQuery UI Sortableの初期化に時間がかかるのです。

最初は画面左側の「記事の一覧」ではjQuery UI Sortableの使用を諦めることを考えたのですが、何か情報がないか探ってみたところStackOverflowに「 jQuery UI .sortable() call is slow when applies to thousands of elements」という質問があり、それに対する回答のコードで解決できました。

コードの要旨は以下の通りです。

  • 画面左側の「記事の一覧」ではjQuery UI Sortableの初期化をしない
  • 記事の項目(borderで囲まれた四角)にマウスオーバーした時、その要素のみjQuery UI Sortableが利用できるようになる
  • jQuery UI Sortableのopacityオプションを指定するとパフォーマンスが大きく劣化するので指定しない

つまり、項目にマウスオーバーをして画面右側の「グループの記事」に項目を移動しそうだな、という時その項目のみjQuery UI Sortableの機能が利用できるようになるのです。jQuery UI Sortableのrefreshメソッドを呼ぶのですが、処理時間は一瞬なので違和感なく使えるように思います。ただし、画面左側の「記事の一覧」で記事の順番を並び替えた後で画面右側の「グループの記事」に項目を移動するような操作の際は違和感が出るかもしれません。

画面に記事グループのUIが表示された後に操作が可能になるまでに時間がかかっている、という場合は上記解説をご確認の上でお試しください。編集するのはmt-static/plugins/GroupSorting/js/item_sort.jsの冒頭です。

jQuery( function( jQuery )
{
    // ----------------------------------------
    // sort
    // ----------------------------------------
    let timerId = null;
    const $left_listing = jQuery( '#item-left.listing ul' ).sortable( {
        connectWith : '.listing ul',
        containment : '#container',
        items       : '.sorting-initialize',
        stop        : itemsort.sort_stop
    } );
    $left_listing.find('li:not(.sorting-initialize)').one('mouseenter', function () {
        clearTimeout(timerId);
        jQuery(this).addClass('sorting-initialize');
        timerId = setTimeout(function () {
            $left_listing.sortable('refresh');
        }, 300);
    });

    jQuery( '#item-right.listing ul' ).sortable( {
        connectWith : [ '.listing ul' ],
        containment : '#container',
        opacity     : 0.5,
        cursor      : 'move',
        items       : 'li',
        stop        : itemsort.sort_stop
    } );
    jQuery( '.listing ul' ).disableSelection();

最近の記事

カテゴリ

アーカイブ

スタッフ別