在 ASP.NET 2.0 預設實現 AJAX 有二種方式,一種是 CallBack 機制,另一種是 ASP.NET AJAX 的 UpdatePanel。如果就開發使用的便利性而言,無可爭議的一定是使用 UpdatePanel,因為它可以讓 AJAX 實現的不著痕跡;而使用 CallBack 機制必需實作 System.Web.UI.ICallbackEventHandler 介面,並處理 CallBack 用戶端與伺服端進行資料交換的所有細節。這代表 CallBack 機制一無可取嗎?或者它只是個過時的產物嗎?

以下做個「取得伺服端時間」的簡單範例做比較,分別以 CallBack 及 UpdatePanel 來實現 AJAX 的效果。

我們在頁面上放置二個按鈕,一個「CallBack Click」的按鈕是置於頁面上,另一個「UpdatePanel Click」的按鈕則置於 UpdatePanel 中,另外在頁面下方(UpdatePanel 之外)放置一個無關的 GridView 來呈現資料。

使用 UpdatePanel 取得伺服端時間,在「UpdatePanel Click」的 Click 事件撰寫如下程式碼

1     'UpdatePanel 中的按鈕 Click
2     Protected Sub btnUpdatePanelButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
3         Label1.Text = Now.ToString() '伺服端時間
4     End Sub

使用 CallBack 取得伺服端時間就比較麻煩了點,需要實作 System.Web.UI.ICallbackEventHandler 介面的 GetCallbackResult 及 RaiseCallbackEvent,並撰寫用戶端的 JavaScript 處理 CallBack 的回傳結果。

*.aspx.vb

01     Implements System.Web.UI.ICallbackEventHandler
02
03     ''' <summary>
04     ''' 傳回 CallBack 的傳回結果。
05     ''' </summary>
06     Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
07         Return Now.ToString() '傳回伺服端時間
08     End Function

09
10     ''' <summary>
11     ''' 處理 CallBack 的傳入引數。
12     ''' </summary>
13     ''' <param name="eventArgument">CallBack 前端傳入引數。</param>
14     Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
15     End Sub

16
17     Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
18         'Button1 的 onclick 執行 CallBack 回伺服端
19         btnCallBackButton.Attributes("onclick") = Me.ClientScript.GetCallbackEventReference(Me, "", "ReceiveServerData", "")
20     End Sub

*.aspx

1     <script type="text/javascript">
2     function ReceiveServerData(rValue)
3     {
4         var o = document.getElementById("Label1");
5         o.innerText = rValue;
6     }

7     </script>

執行程式,並使用 Fidder 來查看程式執行過程。首先執行「UpdatePanel Click」按鈕來取得伺服端時間,接著執行「CallBack Click」按鈕來取得伺服端時間。

在 Fidder 中可以明顯的發現同樣取得伺服端時間的功能,使用 UpdatePanel 回傳的 Size 高達 21255 Bytes,而 CallBack 卻只有 693 Bytes,有沒有很驚訝,同樣的功能回傳的 Size 竟差異30倍左右。

接下來把 GridView 拖曳至 UpdatePanel 中再執行一次程式。

執行程式,同樣使用 Filder 查看結果。

當 GridView 放置 UpdatePanel 中時,使用 UpdatePanel 回傳的 Size 高達 44313 Bytes,而 CallBack 還是只有 693 Bytes。

會有以上的結果是必然的,因為 UpdatePanel 無法預知要更新那些部分,只要是在 UpdatePanel 中的控制項,它需要在執行 AJAX 非同步更新時維護所有子控制項的狀態,所以需傳遞更多的資訊。如果沒有傳輸量的問題,UpdatePanel 無疑是實現 AJAX 的完美機制;但在頁面部分需要好的執行效能時,CallBack 就是個不錯的選擇。

ASP.NET 魔法學院


DotBlogs Tags: CallBack UpdatePanel

Feedback

  • Allen Kuo 2008/7/29 下午 01:30 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    我對Ajax不熟,如果我說得不對煩請告知

    針對您第一次的實驗,而結論是使用updatepanel要比callback傳輪超過30倍,我覺得不太合理,因為updatepanel是將整個form送回去,因此updatepanel送回去時,跟您網頁裡有多少表單控制項,以及viewstate長度是有關係的,而您在第一次測試時就為表單加入了gridview,因此我猜您若給gridview 更多筆記錄,導致viewstate變大時,二者的差距應該會不止30倍才對

    因此,比較合理的結論應該是callback傳回的資料量真的很少, 而updatepanel由於是將form傳回,因此傳回的量會因為form裡的控制項多寡有正比的關係

    如果form裡沒有grid控制項, 只是純粹有一些textbox等控制項時, 傳輸量應該就不會差到30倍

    當然啦, 要用callback or updatepanel應該不會單純地只用流量來決定

  • jeff377 2008/7/29 下午 01:57 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    會因測試的案例會有差異,基本上 UpdatePanel 雙向傳輸量會與頁面的控制項多少有關係,而 CallBack 的雙向傳輸量是以更新的局部而定(固定傳輸量)。

  • jeff377 2008/7/29 下午 01:59 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    在愈複雜的頁面,更能顯示出 CallBack 的效能優勢;例如我們做的訂單頁面,表頭+表身高達上百個欄位,測試的結果 UpdatePanel 及 CallBack 的傳輸量就高達上百倍的差異。

  • 雲淡風清 2008/9/8 上午 10:30 回覆

    # 此二者的比較意義不大

    針對Callback和UpdatePanel此二者之比較,若只著單純的讀取伺服器時間比較會有技術上的盲點,因為callback取回單純之字串一定是比較快的,不太需要真正實測,一如光速或飛機誰快,也實在不需要多測,即使有數據也只是瞭解那種落差到底有多大。

    而說callback過時一點也不為過,因為它是在AJAX這個名詞還沒推出時,就已經設計的東西,功能上陽春許多。

    而callback與UpdatePanel二者能力差異的顯現,在於UpdatePanel是一個較為全面性考量的東西,例如您可以將GridView,DetailsView等控制項放進去。

    如果您真的要測試二者的差異,建議如下:
    1. callback + GridView效能
    2. UpdatePanel + GridView效能

    這時您應該知道真正的考驗來了。。。

    附註:
    1.Allen Kuo說的對,GridView的ViewState會影響到Size,所以若能將ViewState取消最好。
    2.至於UpdatePanel的Render方式,在ASP.NET 4.0時會有新的改進,只Render特定欄位值,一種比Partial Rendering可以聚焦到更小區塊的技術。

  • jeff 2008/9/8 上午 11:35 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    to 雲淡風清 :
    文章內容本來就是特別使用 GridView 來說明 CallBack 與 UpdatePaenl 的差異。
    1. callback + GridView效能
    2. UpdatePanel + GridView效能

  • 雲淡風清 2008/9/8 下午 03:27 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    我的老天爺呀...是我理解錯誤,還是你沒弄懂我的問題.

    GridView的DataSource及DataBind還有分頁,編輯與刪除,全透過callback來實現AJAX功能,也就是不需要將GridView放在UpdatePanel之中才算,這個才叫callback+Gridview!

    而本篇文章只是單純的取回伺服器時間,那根本不足以說明什麼的,所以我才覺得callback與UpdatePanel相比,有點不倫不類...

  • jeff 2008/9/8 下午 04:40 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    to 雲淡風清 :
    我想您誤解我當初做這個比較的用意,我不是要拿 CallBack 來取代 UpdatePanel,只是單純在說明應該適時的使用 UpdatePanel 或 CallBack。
    一般是不可能大費功夫的使用 CallBack 方式來實作整個GridView 的分頁、編輯、刪除動作;我的作法也是二者同時使用,把一些適合用 CallBack 處理的部分加進控制項中。

  • jeff 2008/9/8 下午 04:49 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    to 雲淡風清 :
    也許這個文章主旨下的不好,也許應該改成「UpdatePanel 及 CallBack 的使用時機」會好點 ...

    這篇文章只是以這個案例來突顯 UpdatePanel 在某些需求時會傳遞過多資料量,也要適合配合 CallBack 來使用。

  • 雲淡風清 2008/9/8 下午 06:22 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    同意你啦!給你鼓勵...寫文章很不容易的!^___^

  • jane 2009/2/25 下午 12:04 回覆

    # re: CallBack 與 UpdatePanel 的效能比較

    我倒是覺得這一篇很好阿,
    板主明明就是要告訴大家使用的時機,
    實在沒有必要說不過別人,就說別人標題下不好

標題 *
名稱 *
Email (將不會被顯示)
Url
回應
登入後使用進階評論
Please add 1 and 2 and type the answer here: