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)
|