Viewstate w asp.net
Posted by Krzysztof Zmorzyński
Tuesday, June 09, 2009 9:18:00 AM
Viewstate w asp.net to prawdziwe przekleństwo. Rośnie jak rak na stronie, zazwyczaj w zastraszającym tempie. Tak naprawdę jednak w 90% można go po prostu wyłączyć (albo poważnie ograniczyć), szczególnie jeśli dotyczy on takich kontrolek jak TextBox, Checkbox itp - w skrócie tych wszystkich kontrolek, które przekazują swoje wartości przez post formy (po zdarzeniu Init, ale przed Load, tak jak to widać na cyklu życia strony w asp.net).
Przyznam, że jestem zwolennikiem wyłączania viewstate gdzie tylko się da. GridView to jedna z tych kontrolek, która jest szczególnie łakoma na viewstate: każdy wiersz zawierający nawet tylko asp:HyperLink czy Label potrafi dorzucić tam swoje 3 grosze, jeśli tylko kontrolka ta jest DataBindowana.
Przykładowo, dla takiego wiersza:
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink id="_edit" runat="server" Text="Link"
NavigateUrl='<%# "/Edit.aspx?id=" + Eval("Id") %>'> </asp:HyperLink>
</ItemTemplate>
</asp:TemplateFiel>
Hyperlink '_edit' zapamięta swój url w viewstate. Prawdopodobnie zupełnie niepotrzebnie. Dzieje się tak dlatego, ponieważ viewstate śledzi zmiany jakie w nim zachodzą, zapisuje je a następnie odczytuje przy kolejnym przeładowaniu. Więcej na ten temat i jak z tym walczyć znajduje się na stronie właśnie poświęconej problemom z viewstatem. Polecam, długa lektura lecz bardzo pouczająca.
To, czego natomiast nigdzie nie znalazłem, to informacja, że nawet w takim przypadku:
<asp:TemplateField>
<ItemTemplate>
<%# Eval("Id") %>
</ItemTemplate>
</asp:TemplateFiel>
viewstate dla tego wiersza jest również zapisywany! Sprawdź, włącz Trace na stronie i sam się przekonaj. Dziwne? Trochę. Na szczęście wystarczy zamienić to na:
<asp:TemplateField>
<ItemTemplate>
<asp:Literal runat="server" enableviewstate="false" Text='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
I po kłopocie.
A co to ma wspólnego z gMetrix? W trakcie budowy tej strony internetowej natknąłem się właśnie na taką sytuację i postanowiłem się tą informacją podzielić :)