質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

SmartyによるAjaxレスポンスの生成の描画速度が遅い

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,224

ms5025

score 204

前提・実現したいこと

SmartyによるAjaxレスポンスの生成の描画速度が遅いのでどうにかしたいです

現在Ajaxで取得したデータに基づいて、一部ページhtmlの内容を書き換える動きをしています。
簡単なイメージでいうと、左半分の項目をクリックすると
右半分に対応するデータが非同期で表示されるといった感じです。

データが多い場合は右半分のデータ部分を改ページさせるため、等間隔で切ったセクションの一部のみshow
他はhideにしています。(jqueryでshow hideで改ページさせています)

発生している問題・エラーメッセージ

右半分に表示するデータ量が多い場合、レスポンスで帰ってきたhtmlの描画に時間がかっているようです
データの取得自体には時間がかかっておらず、
データが返ってきてから描画をするのに時間がかかっているようです。

描画速度を上げるためにできることはあるでしょうか?
また、そもそもこのようなデータ量の場合非同期通信でデータを取得すること自体が誤りなのでしょうか?
(改ページや項目選択でsubmitさせないでほしいという要件があったためこうなりました)

class HagehageController extends AbstractActionController {

    /**
     * @return View 情報取得
     */
    public function hogehogeAction() {

        // 共通処理
        require_once('共通処理.php');

        // 情報取得
        $results['itemList'] = LibsHoge::getSearchItem($params['paramCD1'], $params['paramCD2'], $$params['searchText']);

        // smartyのview表示
        Smarty::render($params, $results);

    }

}

共通処理.php内で$paramsにポストデータをセットしていたり
Actionに対応するtplや表示に必要な物が共通処理として$resultsにセットしてあります。(フレームワークはzendを使用)
    // 〇〇コード
    var paramCD1 = $('#paramCD1').val();
    // 〇〇コード
    var paramCD2 = $('#paramCD2').val();
    // キーワード
    var searchText = $('#searchText').val();


    $.ajax({
        type: 'GET',
        url: "hogehoge",
        dataType: 'html',
        data: {"paramCD1": paramCD1, "paramCD2": paramCD2, "searchText": searchText}
    }).done(function (html) {
            var $list = $(".itemList");
            // リスト内クリア
            $list.empty();
            // レスポンス結果アペンド
            $list.append(html);

    }).fail(function(jqXHR, textStatus, errorThrown) {
            //エラー処理
    }); 
<section class="">
    <div>
        <assid >
        <h4>
      <span id="prev" data-action="prev"><<前回</span>
        <span id="next" data-action="next">次回>></span>
        </h4>
        </assid>
    </div>
    <section >
        {foreach from=$results.itemList key=key item=items}
            <li class="">
                <section class="">
                    <!-- 商品画像 -->
                    <figure">
                        <img  src="{$items.商品画像}"/>
                    </figure>
                    <dl class="itemInfo">
                        <dt>
                            品番:{$items.品番}
                        </dt>
                        <dt class="">
                            {$items.商品名}
                        </dt>
                        <dt class="">
                            {$items.価格}
                        </dt>
                        <!-- 以下商品の情報続く・・・ -->
                    </dl>
               </section>
            </li>
            <!-- 最大商品数ごとにセクション区切り -->
            {if (($key+1)%{$smarty.const.1ページ最大商品数} ==0)}</section><section>{/if}
            {/foreach}
        {/if}
</section >

追記★
上記tplではclass名を削除してありますが、
sectionのclassをhogeMenuとしてあります。
cssで'selected'classに対してshow状態を設定してあります。
初回1ページ目のsection以外は'selected'のclassがないためhide状態です。
下記は必要部分だけ抜き出してありますが
これに最大ページ数の制御などが追加されています。

/*pager*/
.hogeMenu { display: none; }
.hogeMenu.selected { display: block; }
// 改ページ制御
$(document).on('click', '.改ページclass', function () {

    var current = parseInt($('.hogeMenu.selected').index('.hogeMenu'));
    if ($(this).is('.prev') && current !== 0) {
        current = current - 1;
        $('.hogeMenu').removeClass('selected').eq(current).addClass('selected');
        $('body,html').animate({scrollTop: 0}, 0);
    } else if ($(this).is('.next')) {
        current = current + 1;
        $('.hogeMenu').removeClass('selected').eq(current).addClass('selected');
        $('body,html').animate({scrollTop: 0}, 0);
    }
    current = current + 1;

    // ページボタン制御
    $('.prev').show();
    $('.next').show();
    if (current == 1)
    {
        $('.prev').hide();
    }

});
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2018/12/10 11:09

    「liタグを最大商品数でセクションで区切って、それ以外はhideにしています。」は提示できないのでしょうか。

    キャンセル

  • ms5025

    2018/12/11 10:19

    >kei344 それはcssでhideにしてるだけなんで・・・それ以外にどういえば・・・。あげる必要あります?一応clickタイミングの処理も追加しましたがこちらはあまり関係ないですよね。

    キャンセル

  • ms5025

    2018/12/11 10:26

    >kei344さん すいません上記tplでclass名を軒並み抜いているので意味不明でしたね。実際はsectionに対してclassがあり、selectedのついたセクションのみshow状態にしているだけです。

    キャンセル

回答 2

checkベストアンサー

+2

自分の場合ですと、htmlだけを送信してもらう場合はそこまで遅いと感じたことはないです。
プラスアルファで画像なんかを送っている場合は遅いことがあります。
その場合は極力画像サイズを小さくして送っています。

データ通信の詳細(画像なのかタグだけなのか、データ量とか)がわかりかねるので微妙な回答になりますが。
データ通信を要する場合においては極力ローカルで完結できるような通信手段をとるべきだと思います。
それが通信はできていて描画が不安定だというのならば通信して取得してきたデータサイズに問題もあるような気がします。
あと、受信データを小出しで取得するという手もありますが、データの種類によっては難しい場合もあるのでなんとも言えません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/11 10:01

    丁寧な回答ありがとうございました!
    私も情報が足りませんでした、申し訳ありません。
    よくあるスクロールしながら表示はNGでボタン改ページでお願いしますとのことでした。
    でもよく考えたら、改ページごとにsubmitするのはNGなだけだったので
    改ページボタン押下タイミングで次ページ情報取得のajax走らせたらいいんでしょうかね。
    けど1ページ横3商品×4列の12商品程度の小さな情報をを改ページごとに取得処理走らせるのって
    ちゃんとイケてる処理なんでしょうか・・・。
    けどその方が再度マスタから最新情報取得できるので安全な気もしてきました・・・

    キャンセル

  • 2018/12/11 13:15

    現段階でイケてる処理かどうかはms5025さんにしかわからないです。
    通信&描画共に速度を出すためにサーバーがどの程度までの膨大な通信を可能としてくれるのか、圧縮などの処理は必要か、データ分割は必要か、データそのものを取得せずURLだけを取得することで軽くできないかなど。
    それによって最適な処理を書いていければイケてる処理にはなるはずです通信は。

    しかし、描画が遅いことがネックならばデータ取得後の自分の書いたコードを見直してみましょう。
    キャッシュを使わずに毎回データを更新していないかとか、余計な処理を書いていないかとか。

    安全面を考慮するならサーバーの通信とデータ授受の方法そのものを見直してください。

    キャンセル

  • 2018/12/11 14:45

    了解しました。ありがとうございました!

    キャンセル

+2

スピード重視なら、もしjson→dom的なことをやっているならその処理をすっとばし
サーバー側でhtml形式でデータを出力してもらい、そのまま流し込むようにすることでしょう

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/10 10:21

    スクロールされるたび表示というよくあるあのタイプはNGが出ています。
    そうなると改ページ事に取得ということになるのでしょうか。
    ありがとうございます。仕様のほうの改正を考えてみます。

    キャンセル

  • 2018/12/10 10:25 編集

    > あのタイプはNG

    あらそうですか、そうなると無尽蔵のCPUパワーと、高速大容量のメモリ
    ストレスないネットワークを用意すれば、ブラウザのレンダリングエンジンが
    優秀なら運が良ければ一瞬で表示されます。
    質問者さんがおっしゃっている解決策とはそういうことです。

    たとえばgooglemapで町内を表示しようとおもったとき
    世界地図を全部読み込んでから表示するようなやり方です

    キャンセル

  • 2018/12/11 10:02

    なるほどそうなりますよね。
    ということは仕様のほうでカバーってことですよね。
    ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる