Caching in ASP.NET - VaryByParam may need VaryByHeader
I was tidying up the blog this evening and adding a Reviews category when I visited one of my own pages and noticed that chunks of content were in German. I literally did a double take.
Then I realized that one of my performance optimizations since the site's been getting slammed was to add this to Permalink.aspx (the page that ultimately services DasBlog's single-post pages, no matter what you see in the URL.)
<%@ OutputCache Duration="1800" VaryByParam="*"%>
What could be wrong with that you ask? The idea was to handle different combinations of input and cache page output as appropriate. However, what input would cause my site to serve me, an anglophone, German?
Well, if a German fellow browsing with his browser's Accept-Language header set to anything like "de-DE" and he happened to be the FIRST guy to visit a specific page before it was cached, given the directive above, the page would be cached as it was shown to him. DasBlog will generate most non-content text in the requested language.
Ah! So I needed to:
<%@ OutputCache Duration="1800" VaryByParam="*" VaryByHeader="Accept-Language" %>Problem solved.
NOTE: I do use HttpCompression and some folks add Accept-Encoding to the VaryByHeader, but the HttpModule I use adds that programatically so everyone gets what they expect. All this caching DOES add up to memory. If someone visted every page in my site at least once with every possible language value, along with HttpCompression on in their browers, then again with HttpCompression off, my Web Server would have to hold a least numOfPages*2*numOfLanguages cached versions of pages.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
logger.Info("TotalMemory (before) : " + (System.GC.GetTotalMemory(True) / 1024).ToString)
It seems to indicate I jump from 2mb to 5mb when loading all one dataset, which is tolerable with 4gb of total memory. :)
I still had to force it to keep the object in the Cache until expiration because it kept kicking it out. It claimed it was not used enough, but I think any object over a certain size does not stick around long. I even have the Cache settings allowing up to 50% of memory.
There are also other memory related properties on the GC object, but I have not dug into it enough to determine if I can isolate usage by domain or even object. But managed code may not expose that level of detail.
Comments are closed.