ASPNL logo (1 kb)
zaterdag 17 mei 2008




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

Gebruik altijd de Response Buffer

Door Charles Carroll
20 juni 2001

In mijn klas voor gevorderden hebben wij mijn fanatieke geloof in <%Response.Buffer = True%> en af en toe <%Response.Flush%> bevestigd, iets wat ik er bij elke cursist inhamer in mijn klassen.

We hebben talloze snelheidstesten gedaan zoals: Tijdsmeting waarbij 500 database records werden uitgelezen. Elke verandering (Getrows of Getstring, alle records in één keer overhalen, of 50 rijen tegelijkertijd, velden op naam of op nummer) werd gemeten. Veel van deze optimalisaties verminderden een opdracht van 4 naar 2 seconden. Maar het gebruik van Response.Buffer haalde het omlaag naar 3/10 van een seconde!!!! Waarom?????

Laten we de ober analogie vertellen....

Een ober komt naar je tafel in een druk restaurant. Er zitten 5 mensen aan je tafel. Hij vraagt wat persoon #1 wil drinken, loopt vervolgens naar een andere tafel waar hij hen 1 drankje laat bestellen waarna hij naar weer een andere tafel loopt waar hij 1 persoon vraagt wat voor hoofdgerecht hij wil om aan de volgende tafel te vragen wat voor een dessert iemand aan die tafel wil. Als hij terugkomt naar jouw tafel vraagt hij persoon #2 wat hij wil drinken, waarna hij alle andere tafels weer afgaat.

Dit verhaal is jouw webserver met <%Response.Buffer = False%> (de standaard instelling in IIS4 en IIS3). Hoewel het langzamer lijkt voor de aangrenzende tafel dat hij eerst jouw bestelling afmaakt, is het uiteindelijk sneller voor hem om 1 tafel tegelijk te doen.

Chaos, geen orde

Ook als een script <%Response.Buffer = False%> bevat zal het aantal overdrachten die nodig zijn om 10k te verplaatsen bepaald worden door de browser en server op een chaotische, erg moeilijk te achterhalen manier...
5 overdrachten van 2k
10 overdrachten van 1k
3 overdrachten van 3k + overdacht van 1k
Dit is niet efficiënt.

Maar als een script <%Response.Buffer = True%> bevat
==> 1 overdracht van 10k <==
Als 300 mensen naar dat script vragen, zullen er 300 overdrachten zijn, niet 301….3000 overdrachten afhankelijk van vele factoren.

MAAR, laten we zeggen dat je een pagina hebt zoals deze:
<%Response.Buffer = True%>
... 1k HTML ...
... 20k graphic ...
... 45k achtergrond geluid ...
... 4k HTML ...

Een aantal feiten:
De pagina zal sneller zijn als veel mensen de site bezoeken. Ga terug naar de ober analogie. 69k in 1 overdracht x een paar honderd gebruikers is veel makkelijker dan een paar honderd gefragmenteerde overdrachten.

Nu sluit een slim iemand een compromis:
<%Response.Buffer = True%>
... 1k HTML en/of ASP ...
<%Response.Flush%>
... 20k graphic ...
<%Response.Flush%>
... 45k achtergrond geluid ...
... 4k HTML en/of ASP ...

Nu:

  • De gebruiker ziet bij elke flush een gedeelte van de pagina verschijnen.
  • De gehele pagina wordt in 3 gecontroleerde overdrachten verstuurd. GEEN chaos meer.
  • Controle. Geen anarchie.

Een kleine verandering om je server sneller te maken

Ik had ooit eens een server met een CPU die constant 100% van z’n capaciteit nodig had. Ik veranderde registry (noot: in IIS4 en IIS5 kan dit met de Internet Service Manager gedaan worden) zodat alle pagina’s "Response.Buffer = True" werden. Het CPU gebruik ging vervolgens op en neer, in plaats van constant op 100% te staan. Genoeg bewijs dus. De gebruikers vonden de site beter, ik heb geen geld voor snellere hardware uitgegeven en geen code hoeven te wijzigen. Wanneer Response.Flush niet werkt...

Twee van mijn studenten willen graag wat toevoegen aan dit advies.
Rob Reno uit Florida ondervond dat te veel Response.Flush zijn pagina langzamer maakt. Code als deze:

<%Response.Buffer = True%>
... 1k of HTML en/of ASP ...
<% Do Until rstemp.EOF
... process data ...
rstemp.MoveNext
Response.Flush
Loop
%>

zal telkens de pagina een beetje verder weergeven, omdat ieder record telkens naar de browser gestuurd wordt. Als het echter 1000 records zijn, is het ook 1000 keer Response.Flush.

Verander de bovenstaande code naar:
<%Response.Buffer = True%>
... 1k of HTML en/of ASP ...
<%
Do Until rstemp.EOF
   counter = counter + 1
   ... process data ...
   rstemp.MoveNext
   If counter Mod 200 = 0 Then
      Response.Flush
   End If
Loop
%>

Nu worden de records gestuurd bij 200, 400,600,800 en 1000 records -- 5 in totaal.

Doug Cannon uit Utah schrijft....
Het enige dat je voor dit artikel mogelijk niet hebt getest is hoe Response.Flush reageert bij een erg langzame internetverbinding (bv. 28.8bps). Onze bezoekers op www.myfamily.com gebruiken nog vaak een 28.8 of 33.6 modems om verbinding te maken. We merkten dat er veel langzame snelheden waren op veel van onze pagina's. Wij gebruikten Response.Buffer = True op elke pagina, en twee Response.Flush commando's per pagina. Wij ontdekten, en Microsoft gaf dat uiteindelijk toe, dat de Response.Flsuh wacht totdat de client browser de flush bevestigt voordat hij doorgaat met het uitvoeren van de ASP code. Met een erg snelle internetverbinding merk je niks van dit probleem, maar een langzamere modem doet er langer over om deze opdracht uit te voeren; derhalve kan dan een flush slecht zijn. Wij gebruiken natuurlijk nog steeds Response.Buffer = True. We hebben echter alle Response.Flush commando's verwijderd van de site en we zagen onmiddellijk een dramatische verbetering van de snelheid.

Mijn opmerking: Ik gebruik Response.Flush succesvol en met snelheid gebruikt op 28.8 connecties, MAAR mijn servers zijn niet zo druk als www.myfamily.com. Als gevolg van de round-robin uitvoering van script (zie http://www.learnasp.com/advice/roundrobin.asp) kunnen hun servers er langer over doen bij een Response.Flush dan minder drukke servers!

© Charles Carroll (vertaling copyright ASPNL)

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL