今更?ASP.NET Ajax(非同期処理)で一覧表示パフォーマンス改善

ASP.NETでGridViewを使用した一覧表示でAjax(非同期)処理による一覧データの追加処理についての備忘録です。


HTML5のCANVASを拒絶する訳ではないけどASP.NETでも図形描画できる!


ポストバックが発生しない不思議な障害についてはこちら!

機能

メイン処理で縦スクロール位置によって一覧の追加データを取得するか判断して、
追加データを取得する場合はAjax(非同期)処理によりAjaxSample2.aspxよりデータ取得して
一覧に追加して表示します。
なお、ヘッダーはスタイルシートを使い固定しています。

AjaxSample.aspxファイルでのAjax(非同期)処理サンプル

まずはヘッダ部ですが、GridViewで使用するスタイルシートを記述

<head id="Head1" runat="server">
    <title>非同期処理で一覧データ取得サンプル</title>
    <link href="../../css/std.css" rel="stylesheet" />
    <style type="text/css">
        tr.Freezing {
	        Z-INDEX: 10; POSITION: relative; ; TOP: expression(this.offsetParent.scrollTop); 
        }
        .HeaderStyle th a {color:black; text-decoration:none;}
        .GridStyle
        {
	        overflow-y:auto;
	        width:210px;
	        height:500px;
        }
    </style>
</head>


非同期でサーバとやりとりをするXmlHTTPRequestインスタンス生成

function getHttpObject()
{
    var retval=null;
    try
    {
	retval=new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e)
    {
	try
	{
		retval=new ActiveXObject("Microsoft.XMLHTTP");
	}
	catch(oc)
	{
		retval=null;
	}
    }
 
    if(!retval && typeof XMLHttpRequest != "undefined")
    {
	retval=new XMLHttpRequest();
    }
    return retval;
}


非同期処理でのサーバー通信とサーバーからの応答時の処理

function send() {
    //非同期通信を行うためのXMLHttpRequestオブジェクトを生成
    xmlReq = getHttpObject();
    if(xmlReq)
    {
        //現在表示中データを退避
        initData = document.getElementById("result").innerHTML;

        //サーバーからの応答時の処理を定義(結果のページへの反映)
        xmlReq.onreadystatechange = getAsynData;
        //キャッシュを回避するため時刻を付加
        var paramList = "time=" + (new Date().getTime());
        // サーバーとの通信を開始
        xmlReq.open("GET","AjaxSample2.aspx?" + paramList,true);
        xmlReq.send(null);
    }
}


非同期処理で取得したデータを一覧(テーブルタグ内)に追記

//非同期処理からデータを取得
function getAsynData() {
    var nCnt;
    var newData;

    var msg = document.getElementById("result");
    if (xmlReq.readyState == 4) {
        if (xmlReq.status == 200) {
            nCnt = initData.length;
            nCnt = initData.lastIndexOf("</TABLE>", nCnt);

            //追加データを取得
            newData = xmlReq.responseText;

            //現在表示中データに取得データを追加
            msg.innerHTML = initData.substring(0, nCnt).concat(newData);

        } else {    //通信に失敗した場合
            msg.innerHTML = initData;
        }
    }
}


JavaScriptのonloadイベントで一覧のスクロールイベントの処理を記述
一覧スクロール時にデータ取得位置より下側ならば非同期通信処理を呼び出す

//一覧のスクロールイベント時の処理を定義
function setOnScrollEvent(){
    document.getElementById("Grid").onscroll = function(){
        scrollTop = document.getElementById('Grid').scrollTop;

	//一覧のスクロール位置より追加データを取得するか判断
	if(Number(scrollTop) > Number(一覧データ取得位置)){
   	    //非同期通信によりデータ取得
	    send();
	}
    }
}

//グリッドビューのスクロール時のイベント処理追加
window.onload = setOnScrollEvent;


↑ここまでがJavaScriptでこの後はHTMLの記述
GridViewコントロールを使用して一覧表示

<body>
    <form id="form1" method="post" runat="server" >
        <asp:Panel ID="Panel1" runat="server" Height="500px" Width="210px" BorderStyle="Solid" BorderWidth="2px">
            <div id="Grid" class='GridStyle'>
            <div id="result" class='DummyBackColor'>
            <asp:GridView style="overflow:auto" ID="gdViewSample" runat="server">
                <Columns>
                    <asp:BoundField  DataField="TestColumn1" HeaderText="カラム1">
                        <ItemStyle Width="70px"  HorizontalAlign="Left"
                        VerticalAlign="Middle" />
                        <HeaderStyle  Width="70px" HorizontalAlign="Center" />
                    </asp:BoundField>
                    <asp:BoundField  DataField="TestColumn2" HeaderText="カラム2">
                        <ItemStyle Width="70px" HorizontalAlign="Left"
                        VerticalAlign="Middle" />
                        <HeaderStyle  Width="70px" HorizontalAlign="Center" />
                    </asp:BoundField>
                    <asp:BoundField  DataField="TestColumn3" HeaderText="カラム3">
                        <ItemStyle Width="70px" HorizontalAlign="Center"
                        VerticalAlign="Middle" />
                        <HeaderStyle Width="70px" HorizontalAlign="Center" />
                    </asp:BoundField>
                </Columns>
                <HeaderStyle BackColor="Control" CssClass="Freezing HeaderStyle"
                    ForeColor="Black" />
            </asp:GridView>
            </div></div>
        </asp:Panel>
    </form>
</body>
</html>

AjaxSample2.aspxファイルでのAjax(非同期)処理サンプル

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Response.Clear()
        Response.BufferOutput = True
        Response.Write(AjaxSample.aspxに返すHTMLデータ)
        Try
            Response.End()
        Catch ex As Exception
        Finally
        End Try
    End Sub