教你50招提高ASP.NET性能(二十):7條便利的ViewState技巧

(32)Seven handy ViewState tips數據庫

招數32:緩存

7條便利的ViewState技巧app

Every time I have to deal with a classic ASP.NET Web Forms application, one of the first things I look at is the resulting source, to check whether the DOM is a complete mess and whether the ViewState is an enormous, unnecessary blob of ugliness. Usually, they indicate what kind of mess will be found further down the stack.
每次我不得不處理一個傳統的ASP.NET Web Forms應用時,首先查看生成的源碼,檢查DOM是否一團糟、ViewState是不是很大,多餘的醜陋代碼塊。一般,它們預示着發現的爛攤子會更爛。less

<input type=」hidden」 name=」__VIEWSTATE」 id=」__VIEWSTATE」 value=」/wFzY3JpcHQ6IE9uY2xpY2s9J3dpbmRvdy5vcGVuKCJFcXVpcG1lbnQtRGV0YWlscy5hc3B4P1VzZWQtMjAxMC1UZXJl…(continues for 18,000 characters)…UlVTIiB3aWR0aD=」 />
<input type=」hidden」 name=」__VIEWSTATE」 id=」__VIEWSTATE」 value=」/wFzY3JpcHQ6IE9uY2xpY2s9J3dpbmRvdy5vcGVuKCJFcXVpcG1lbnQtRGV0YWlscy5hc3B4P1VzZWQtMjAxMC1UZXJl…(此處省略18,000個字)…UlVTIiB3aWR0aD=」 />

 

Inadvertently using ViewState when it’s not necessary substantially increases the amount of data going back and forth, and can lead to a greater prevalence of invalid ViewState exceptions; the bigger the blob, the more likely it could be interrupted in transmission and not be posted back in entirety in a post.
當沒有必要大幅度地增長往來數據量時無心中使用ViewState,可能致使更大的廣泛無效的ViewState異常;代碼塊越大,越有可能在傳輸中中斷而且可能在一次提交中不徹底回發。ide

(33)Unless you’re tracking a Text_Changed event, you don’t need ViewState enabled on TextBoxes and similar controls. Classic ASP.NET automatically repopulates TextBox.Text values upon postback, even without ViewState enabled. Turn it off on each TextBox with EnableViewState= 「false」 on each one.post

招數33:ui

除非跟蹤一個Text_Changed事件以外,你不需在TextBoxes和相似的控件上要啓用ViewState。傳統的ASP.NET回發時會自動地填充TextBox.Text的值,甚至沒有啓用ViewState的狀況下。在每一個TextBox使用EnableViewState=「false」關掉ViewState。this

You can do this for other controls like labels, but unless you’re setting their values after the page’s load event, you won’t reduce the size of the ViewState.
你能夠在其它控件像labels禁用ViewState,可是除非在頁面加載事件後設置它們的值,你將不能減小ViewState的大小。spa

(34)The same goes for most implementations of Repeaters, ListViews, and so on. These are usually the biggest culprits and they can be ugly. The advantage of ViewState with these is avoiding having to populate values again in a postback. 翻譯

招數34:

這一樣適用於Repeaters, ListViews, 等等大多數的控件實現。這些一般可能成爲醜陋的罪魁禍首。ViewState對於這些的優點是避免不得不在回發時從新填充值。

If you’re convinced that it’s worth passing ViewState back and forth again and again to save your app the extra database hit…well…you’re probably wrong. Save the database hit (if you need to) with some caching and disable that dang ViewState on that Repeater!
若是你相信這是值得一次又一次地回傳ViewState以便節省你的應用程序額外的數據庫訪問...好...你可能錯了。使用一些緩存減小數據庫訪問(若是你須要)而且在Repeater上禁用那見鬼的ViewState纔是正道!

(35)If you’re re-binding data anyway, or just toggling one property on postback (asp:Panel anyone?), turn off that ViewState! Please!

招數35:

若是你不管如何也要從新綁定數據,或者只是在回發時切換一個屬性(asp:Panel 任何一個),請關掉ViewState!

(36)If you do need ViewState, understand the page lifecycle and bind your data appropriately. A control loads its ViewState after Page_Init and before Page_Load, i.e. server controls don’t start tracking changes to their ViewState until the end of the initialization stage.

招數36:

若是你確實須要使用ViewState,理解頁面的生命週期並適當地綁定數據。控件在Page_Init以後Page_Load以前加載它的的ViewState,也就是說,服務端控件在結束初始化階段以前都沒有開始跟蹤ViewState的改變。

Any changes to ViewState mean a bigger ViewState, because you have the before value and the after value. So, if you’re changing or setting a control’s value, set it before ViewState is being tracked, if possible.
任何ViewState的更改意味着更大的ViewState,由於你得到更改先後的值。因此,若是你正在改變或設置控件的值,若是可能的話,設置它以前的ViewState是正在跟蹤的。

(37)You may think it’s impossible to turn off ViewState on a DropDownList, even if you re-bind it on every postback. But with a tiny bit of elbow grease you can keep ViewState enabled and avoid passing all your option values back and forth. This is particularly worthwhile for DropDownLists with a big ListItem collection.

招數37:

你也許認爲在DropDownList上關掉ViewState是不可能的,即時你在每次回發時從新綁定它。可是隨着一點點的費力工做你可以保持ViewState的啓用而且避免反覆地傳輸全部的選項值。

One way is to turn off ViewState and bind the select value manually to the actual posted value, like so:
一種方法是關閉ViewState並手動綁定實際傳輸的選項值,像這樣:

string selectedId = Request[Countries.UniqueID];
if (selectedId != null)
Countries.SelectedValue = selectedId;

 

However, you may prefer something I came across more recently. Instead of binding your DropDown-List in the typical Page_Load or Page_Init, bind it in the control’s Init event:
然而,你可能更喜歡我最近的一些嘗試。在控件的Init事件上綁定事件,而不是在傳統的Page_Load或Page_Init事件綁定你的DropDown-List。

<asp:DropDownList ID=」Countries」 ...
OnInit=」CountryListInit」 />
protected void CountryListInit(object sender, EventArgs e)
{
Countries.DataSource = // get data from database
Countries.DataBind();
}

 

(38)Make it your habit to turn off ViewState on every control by default, and only turn it on when you need it. If a page doesn’t need ViewState anywhere, turn it off at the page level.

招數38:

你應該養成一個習慣:在默認狀況下關閉全部控件的ViewState,只有當你須要的時候打開ViewState。若是一個頁面不須要任何ViewState,在頁面級關閉它。

You do all that work to reduce requests, combine and compress static references, and make sure your code is as clean as possible - don’t ruin it with a ViewState monster! If you’re anal, you can completely remove all traces of ViewState from pages that don’t need it by inheriting from a BasePage such as this:
你作全部工做來減小請求,合併和壓縮靜態引用,並確保你的代碼儘量的簡潔 - 別讓ViewState怪獸毀了它!If you’re anal(不知道怎麼翻譯),你能夠繼承一個基類頁面,從頁面徹底移除全部的ViewState跟蹤,像這樣:

/// <summary>
/// BasePage providing cross-site functionality for pages that should not have ViewState enabled.
/// </summary>
public class BasePageNoViewState : Page // Or of course, inherit from your standard BasePage, which in turn inherits from Page
{
    protected override void SavePageStateToPersistenceMedium(object viewState)
    {
    }
    
    protected override object LoadPageStateFromPersistenceMedium()
    {
        return null;
    }
    
    protected override void OnPreInit(EventArgs e)
    {
        // Ensure that ViewState is turned off for every page inheriting this BasePage
        base.EnableViewState = false;
        base.OnPreInit(e);
    }
}
相關文章
相關標籤/搜索