A couple of recommendations after looking at your site:
Put some of your static files (images, js, etc.) on different domains so that they can be downloaded at the same time. (also turn off cookies for those domains)
Use image sprites instead of separate images.
Move around when things are loaded. It looks like the script files for the ads are holding up content. You should make content of the site load first by putting it in the HTML before the ads. Also, make sure that the height and width of things are specified such that the layout doesn't change as things are downloaded, this makes the site feel slow. Use Google Chrome's developer tools to look at the download order and timeline of all your object downloads.
Most of the slowness looks like it's coming from downloading items from sharepointads.com. Perhaps fewer adds, or have them use space already reserved for them by specifying height and width.
Add a far future expires time to the header for all static content.
Serve scaled images. Currently the browser is resizing the images. You could save tons of bandwidth by serving the images already the proper size.
Also, download YSlow (from yahoo) and Page Speed (from google)
To set the Cache-Control You have to specify it yourself. You can either do it in web.config , IIS Manager for selected folders (static, images ...) or set it in code. The HTTP 1.1 standard recommends one year in future as the maximum expiration time.
Setting expiration date one year in future is considered good practice for all static content in your site. Not having it in headers results in If-Modified-Since requests which can take longer then first time requests for small static files. In these calls ETag header is used.
When You have Cache-Control: max-age=315360000 basic HTTP responses will outnumber If-Modified-Since> calls and because of that it is good to remove ETag header and result in smaller static file response headers. IIS doesn't have setting for that so You have to do response.Headers.Remove("ETag"); in OnPreServerRequestHeaders()
And if You want to optimize Your headers further You can remove X-Powered-By:ASP.NET in IIS settings and X-Aspnet-Version header (altough I don't see in Your response) in web.config - enableVersionHeader="false" in system.web/httpRuntime element.
For more tips I suggest great book - http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839
Use custom Windows performance counters. They are very lightweight (1 to 2%), and you can use them not just to count, but also for timing measurements, to look at how often certain operations are slower than a threshold, etc.
If you're using IIS 7, you can enable Failed Request Tracing. To limit the perf impact, be careful to not enable it for too many pages. Those traces can provide lots of detail, and you can inject more info into them programmatically if you need to.
Use the Windows Event log to write custom details under exceptional conditions. Perf impact is minimal as long as you don't over-do it.
One cause of sawtooth memory behavior can be not calling Dispose() when you should (or wrapping IDisposable objects in using statements, which will call it for you); you might want to review your code to look for that.
In case it's helpful, you might also be interested in the performance tips from my book: Ultra-Fast ASP.NET.
Edit: you might also try using .NET Memory Profiler (free trial available) to attach to the running process. It's fairly invasive compared to counters, but if you need to capture a snapshot of the current state of memory to debug your problem, there may not be a better choice.
Can I listen to SQL Server Service
Broker queues from .NET applications
running on a different machine?
Yes.
If so, should I do it?
If not, what would you recommend?
You might consider using SqlDependency. It uses Service Broker behind the scenes, but not explicitly.
You can register a SqlDependency object with a SELECT query or a stored procedure. If another command changes the data that was returned from the query, then an event will fire. You can register an event handler, and run whatever code you like at that time. Or, you can use SqlCacheDependency, which will just remove the associated object from the Cache when the event fires.
You can also use Service Broker directly. However, in that case you will need to send and receive your own messages, as with MSMQ.
In load-balanced environments, SqlDependency is good for cases where code needs to run on every web server (such as flushing the cache). Service Broker messages are better for code than should only run once -- such as sending an email.
In case it helps, I cover both systems in detail with examples in my book (Ultra-Fast ASP.NET).
A stackoverflow user actually has a good book on this subject:
http://www.amazon.com/gp/product/1430223839?ie=UTF8&tag=mfgn21-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=1430223839
A couple of recommendations after looking at your site:
Also, download YSlow (from yahoo) and Page Speed (from google)
This book may be helpful.
http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839
To set the Cache-Control You have to specify it yourself. You can either do it in web.config , IIS Manager for selected folders (static, images ...) or set it in code. The HTTP 1.1 standard recommends one year in future as the maximum expiration time.
Setting expiration date one year in future is considered good practice for all static content in your site. Not having it in headers results in
If-Modified-Since
requests which can take longer then first time requests for small static files. In these calls ETag header is used.When You have
Cache-Control: max-age=315360000
basic HTTP responses will outnumberIf-Modified-Since>
calls and because of that it is good to remove ETag header and result in smaller static file response headers. IIS doesn't have setting for that so You have to doresponse.Headers.Remove("ETag");
inOnPreServerRequestHeaders()
And if You want to optimize Your headers further You can remove
X-Powered-By:ASP.NET
in IIS settings andX-Aspnet-Version
header (altough I don't see in Your response) in web.config -enableVersionHeader="false"
in system.web/httpRuntime element.For more tips I suggest great book - http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839
A few ideas:
In case it's helpful, you might also be interested in the performance tips from my book: Ultra-Fast ASP.NET.
Edit: you might also try using .NET Memory Profiler (free trial available) to attach to the running process. It's fairly invasive compared to counters, but if you need to capture a snapshot of the current state of memory to debug your problem, there may not be a better choice.
Read this booK: http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839/ref=sr_1_1?ie=UTF8&s=books&qid=1289574343&sr=8-1
To answer your questions:
Yes.
You might consider using
SqlDependency
. It uses Service Broker behind the scenes, but not explicitly.You can register a
SqlDependency
object with aSELECT
query or a stored procedure. If another command changes the data that was returned from the query, then an event will fire. You can register an event handler, and run whatever code you like at that time. Or, you can useSqlCacheDependency
, which will just remove the associated object from the Cache when the event fires.You can also use Service Broker directly. However, in that case you will need to send and receive your own messages, as with MSMQ.
In load-balanced environments,
SqlDependency
is good for cases where code needs to run on every web server (such as flushing the cache). Service Broker messages are better for code than should only run once -- such as sending an email.In case it helps, I cover both systems in detail with examples in my book (Ultra-Fast ASP.NET).