[C# .NET] performance / Viewstate 350kb groot = te groot???

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 21:59
Heren/dames developers,

Ik heb een formulier gebouwd en het laden van dit formulier duurt momenteel erg lang (15sec.).

Nu heb ik even gekeken in de source en nu zie ik dat er al een viewstate in staat van 350 kilobyte.
Dit is in mijn beleving veel te groot en ik denk dat mede hierdoor het laden ontzettend lang duurt.

Het is een vrij complex formulier met circa 30 velden. met o.a. een aantal dropdowns gevuld met soms wel 20~100 keuzes. Daarnaast zit er ook een op jquery gebasseerde autocomplete in, welke het array ook in de source code plaatst.
Lijkt mij dat mede hierdoor de viewstate ook ontzettend groot is.

Het is door tijdsgebrek (en de wens van de klant) helaas niet mogelijk om het formulier op te splitsen over meerdere pagina's in een wizard (wat mijn voorkeur had).

Misschien wat tips hoe ik deze viewstate kan reduceren?

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 20:51

Haan

dotnetter

Je zou de viewstate uit kunnen zetten, maar dan moet je wel zorgen dat de dropdowns gevuld blijven na een postback (ik ga er vanuit dat je deze in de code-behind vult gezien de grootte van het aantal opties)

Overigens zou het laden ook met viewstate geen 15s hoeven te duren, je kan dus ook eerst met ASP.NET tracing aan de slag gaan, dan kan je zien waar de bottle neck zit.

[ Voor 29% gewijzigd door Haan op 17-10-2011 11:47 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 21:59
Dank je voor de tip.

Viewstate uitschakelen gaat helaas niet. Ik gebruik namelijk de viewstate voor sommige andere functies.
Maar ik heb de asp trace aangezet en zie daar dat 1 van de dropdownlists 320kb van de viewstate voor zijn rekening neemt.

Hier ga ik dus even naar kijken, want dit lijkt niet helemaal juist. :+

Acties:
  • 0 Henk 'm!

  • L-VIS
  • Registratie: April 2005
  • Laatst online: 22:13
Haan schreef op maandag 17 oktober 2011 @ 11:44:
Je zou de viewstate uit kunnen zetten, maar dan moet je wel zorgen dat de dropdowns gevuld blijven na een postback (ik ga er vanuit dat je deze in de code-behind vult gezien de grootte van het aantal opties)

Overigens zou het laden ook met viewstate geen 15s hoeven te duren, je kan dus ook eerst met ASP.NET tracing aan de slag gaan, dan kan je zien waar de bottle neck zit.
Vaak kom ik dan tot de conclusie dat de viewstate idd het probleem is. Load en Save viewstate zullen vaak zware methods zijn.

Wat als quick-fix wel eens wil helpen is, is de viewstate op te slaan serverside. Hiervoor heb je wel een sql server nodig. Daarna kijken welke controls de viewstate nodig hebben. Hij staat bijvoorbeeld ook voor labels aan, by default.

Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 21:59
die 320kb van de eerder genoemde dropdownlist lijkt qua data wel te kloppen. Echter zie ik tijdens het debuggen dat het vullen van deze data 2x gebeurt. :?

Heb dus even een check om de 2e keer gebouwd of de lijst al gevuld is of niet. Hopelijk scheelt dit in de laadtijd.
Even testen nog. Ik laat het nog weten.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
L-VIS schreef op maandag 17 oktober 2011 @ 13:15:
[...]
Wat als quick-fix wel eens wil helpen is, is de viewstate op te slaan serverside. Hiervoor heb je wel een sql server nodig. Daarna kijken welke controls de viewstate nodig hebben. Hij staat bijvoorbeeld ook voor labels aan, by default.
Het is totaal niet nodig om het zo complex te doen. Je kunt de viewstate ook gewoon in memory opslaan. Je zet dan gewoon in een hidden-field een key op de pagina en serverside hou je gewoon een Dictionary bij met die keys en de bijbehorende ViewState. Let er alleen wel op om de viewstate ook weer weg te gooien als hij niet meer geldig is, anders loopt je geheugen op een gegeven moment vol.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 21:59
pdebie schreef op maandag 17 oktober 2011 @ 13:43:
Echter zie ik tijdens het debuggen dat het vullen van deze data 2x gebeurt. :?
Heb dus even een check om de 2e keer gebouwd of de lijst al gevuld is of niet. Hopelijk scheelt dit in de laadtijd.
Even testen nog. Ik laat het nog weten.
Nou heb even getest en dit scheelde inderdaad de helft. Echter duurde het nu nog ruim 7 seconden.
Ben verder gaan zoeken in de code, want als er al dit soort foutjes in zaten zat er vast nog meer in.

Daarbij zag ik dat bij het ophalen van de data uit de database (middels LINQ) deferred loading aan stond.
Dit heb ik uitgeschakeld.

En voila! Van ruim 15 sec naar 1.6 sec. laadtijd.
Kan nog sneller heb ik het idee, dus daar gaan we nog even in duiken.
De viewstate is nog wel net zo groot, want de data staat nog steeds in de dropdownlist.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
De laadtijd wordt zo wel heel erg afhankelijk van de uploadsnelheid... Ik zou toch een kijken hoe of je die viewstate echt zo nodig hebt. Zie bijvoorbeeld:
http://weblogs.asp.net/bleroy/archive/2005/03/11/394280.aspx
http://www.codeproject.com/KB/aspnet/hmvsiooc.aspx
Woy schreef op maandag 17 oktober 2011 @ 13:55:
Je zet dan gewoon in een hidden-field een key op de pagina en serverside hou je gewoon een Dictionary bij met die keys en de bijbehorende ViewState. Let er alleen wel op om de viewstate ook weer weg te gooien als hij niet meer geldig is, anders loopt je geheugen op een gegeven moment vol.
Zo'n dictionary is er al in de vorm van de sessie ;) (zo waarschijnlijk, maar ik gebruik nooit webforms)

Dit draadje doet me trouwens denken aan \[ASP.NET][troll] Een grote clientside overhead faal?

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Woy schreef op maandag 17 oktober 2011 @ 13:55:
[...]

Het is totaal niet nodig om het zo complex te doen. Je kunt de viewstate ook gewoon in memory opslaan. Je zet dan gewoon in een hidden-field een key op de pagina en serverside hou je gewoon een Dictionary bij met die keys en de bijbehorende ViewState. Let er alleen wel op om de viewstate ook weer weg te gooien als hij niet meer geldig is, anders loopt je geheugen op een gegeven moment vol.
Dat klinkt toch nog steeds een tikkeltje complex. Heeft ASP.NET niet zoiets als de viewstate management in JSF (Java EE), waar je gewoon declaratief zegt dat de state op de server moet komen?

In JSF worden er dan voor X pages Y versies van de viewstate bijgehouden.

In het algemeen is de keuze tussen state on server and on client wel altijd lastig. Met state op de server voorkom je het heen en weer transporteren (wat vooral bij AJAX erg lastig kan zijn), maar als de user veel pagina's in verschillende tabs open heeft en/of veel de back button gebruikt houdt het een keertje op.

Met state on client maak je feitelijk gebruik van een distributed memory en is je state oneindig groot, maar zoals de post aangeeft, het telkens uploaden en daarna deserializing (decrypten in ASP.NET?) kunnen een grote belasting vormen.
L-VIS schreef op maandag 17 oktober 2011 @ 13:15:
Hij staat bijvoorbeeld ook voor labels aan, by default.
Worden er hier eigenlijk ook constanten in de viewstate gezet dan?

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Kun je niet een lightweight anonymous object gebruiken om die ene dropdown te populaten. Ik kan me haast niet voorstellen dat je alle info nodig hebt van de objecten die je databind aan die dropdown. (Anders is het wel een absurd lange dropdown.)

[ Voor 10% gewijzigd door Grijze Vos op 17-10-2011 20:48 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
pedorus schreef op maandag 17 oktober 2011 @ 17:08:
Zo'n dictionary is er al in de vorm van de sessie ;)
De vraag is natuurlijk of je je sessie wil "vervuilen" met alle viewstates van een gebruiker. Ik zou dan toch kiezen om daar een losse dictionary te nemen. Die zou je eventueel wel gewoon per user in de sessie op kunnen slaan, maar dan kom je al snel in de problemen als mensen cookies niet accepteren. Als je hem gewoon in de Application scope opslaat en een hidden field gebruikt werkt het altijd ( Zolang je geen server farm hebt)
flowerp schreef op maandag 17 oktober 2011 @ 17:39:
[...]
Dat klinkt toch nog steeds een tikkeltje complex. Heeft ASP.NET niet zoiets als de viewstate management in JSF (Java EE), waar je gewoon declaratief zegt dat de state op de server moet komen?
Zover ik weet niet, maar misschien dat het ondertussen wel als standaard feature aangeboden word. Ik heb het inderdaad altijd vreemd gevonden dat het geen out of the box optie was.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 21:59
Grijze Vos schreef op maandag 17 oktober 2011 @ 20:47:
(Anders is het wel een absurd lange dropdown.)
Nou dit blijkt inderdaad het geval te zijn.
Ik zag dat de query die uitgevoerd werd maar liefst 5000 items opleverde en daar de dropdown mee vulde! |:(

Dat hadden ze me van tevoren niet verteld dat het om zoveel items zou gaan.
Dus ik ga denk ik een andere oplossing bedenken ipv de dropdown. Een autocomplete ofzo die een webservice aanroept oid.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
pdebie schreef op maandag 17 oktober 2011 @ 22:21:
Dus ik ga denk ik een andere oplossing bedenken ipv de dropdown. Een autocomplete ofzo
Prima idee.
Woy schreef op maandag 17 oktober 2011 @ 21:47:
De vraag is natuurlijk of je je sessie wil "vervuilen" met alle viewstates van een gebruiker. Ik zou dan toch kiezen om daar een losse dictionary te nemen. Die zou je eventueel wel gewoon per user in de sessie op kunnen slaan, maar dan kom je al snel in de problemen als mensen cookies niet accepteren. Als je hem gewoon in de Application scope opslaat en een hidden field gebruikt werkt het altijd ( Zolang je geen server farm hebt)
De hack waar ik naar linkte slaat zelfs maar 1 viewstate op lijkt wel, wat effectief betekend dat het fout gaat als je meer dan 1 tab van de pagina open hebt. Maar het blijft sowieso een hack, veel beter is het om de viewstate te reduceren tot een normale omvang (met die links die ik heb gegeven). Of iets anders zoals MVC gebruiken natuurlijk ipv dat ouderwetse webforms. :p

Ik heb trouwens eigenlijk nog geen webforms-site gezien die met cookies uit nog werkt (cookieless="true" zou moeten kunnen maar heeft ook zo zijn nadelen).

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Viewstate opslaan in je sessie is een performance tweak at best. Uitzonderingen daargelaten is viewstate niet de reden waarom een pagina langzaam laad. Maargoed dat had je zelf ook al gemerkt.

Mocht je nou toch je viewstate in je sessie willen opslaan. Ga dit niet zelf zitten doen, er is een ingebouwde provider om dit te regelen. Je kunt namelijk een eigen viewstate provider in je pagina pluggen als je wilt.
Om het op te slaan in je sessie voeg je dit toe aan je page code behind

C#:
1
2
3
protected override PageStatePersister PageStatePersister {
        get { return new SessionPageStatePersister(this); }
}


Pas op dat je dit niet blindelings voor elke pagina aanzet. Iets over als je een hamer hebt lijkt alles een spijker..

Alternatief zou je natuurlijk ook een provider kunnen schrijven die je viewstate naar een memcached server wegschrijft oid.

Acties:
  • 0 Henk 'm!

  • tonyisgaaf
  • Registratie: November 2000
  • Niet online
Vul je niet gewoon je DropDownList te laat? Namelijk tijdens je OnLoad i.p.v. OnInit?
Het volgende linkje zag ik nog niet voorbijkomen, heeft mij veel bijgespijkerd over het minimaliseren van de ViewState zonder kunstgrepen http://weblogs.asp.net/in...erstanding-viewstate.aspx

NL Weerradar widget Euro Stocks widget Brandstofprijzen widget voor 's Dashboard


Acties:
  • 0 Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 21:59
Gebeurt nu inderdaad niet tijdens de init. Dus 'te laat' zoals jij aangeeft.
Dank je voor het artikel. Ga ik eens rustig doorlezen als ik wat tijd over heb.

Daarnaast moet ik het voorstel van de autocomplete nog voorleggen hier, maar dat gaat goed komen.

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18:44

gorgi_19

Kruimeltjes zijn weer op :9

Is de Viewstate de grootste oorzaak? Sowieso kan je HttpCompressie gebruiken om de snelheid nog verder te verhogen. Maar wellicht is het ook mogelijk dat de serverside parsetime simpelweg te hoog is door andere oorzaken (indexen in databases, etc.)

Digitaal onderwijsmateriaal, leermateriaal voor hbo

Pagina: 1