50 ways to Avoid Find And Fix ASP.NET Performance Issues
cache

Caching is a last resort

cache 應該視為最後的王牌

cache 並不是效能的同義詞 , 在使用 cache之前先最佳化你的程式碼。
View Engines

Remove unused View Engines

移除不必要的 view 引擎

MVC 雖然有使用 Razor , 使是預設還是 Web Forms view 第一, 所以在global.asax 用
                            ViewEngines.Engines.Clear();
                            ViewEngines.Engines.Add(new RazorViewEngine());
                        
for MVC
Debug

Use Microsoft's PDBs to debug or profile external assemblies or libraries

工具 -> 選項 -> 偵錯 -> 符號 -> Microsoft符號伺服器 (不知道這個有何效用)

To accurately debug or profile an external assembly or library (i.e. one you’re not directly compiling), you need the PDB files that accompany each of the DLLs. These files give your debugger or profiler access to information such as function names, line numbers, and other related metadata. One thing that sucks in particular is debugging and profiling native Microsoft .NET assemblies without this kind of information. Fortunately, there’s a solution for this very issue. With a little-known feature in Visual Studio 2012 (and 2010 too!), you can connect to Microsoft’s Symbol Servers and obtain most of the debugging symbols for their assemblies and libraries. Just go to Tools –> Options –> (expand) Debugging –> Symbols, and select the Microsoft Symbol Servers as your source for Symbols. Getting the symbols from Microsoft every time you debug or profile is slow and painful. It’ll even give you a pop-up saying as much once you check the Microsoft Symbol Servers, so be sure to specify a directory under “Cache symbols in this directory”. It will keep a local copy of the PDBs and check for updates every so often. As a result, you get your regular debugging/profiling AND you can see the function names of the Microsoft assemblies.
http compress

Make sure HTTP compression is turned on for any uncompressed content.

開啟 HTTP 壓縮

http cache

Always set the CacheControlMaxAge attribute in web.config to a high number (a year is good).

在web.config裡設最大cache時間, 建議一年

這個要看狀況, 並不一定所有網站都適合這樣做
MVC cache

Make use of the OutputCache annotation on MVC controllers.

在 MVC controllers 設 OutputCache 宣告

ORM
  • Always profile your ORM database hits with SQL Profiler during development. ORMs get away from you very quickly. Before you know it, you’ve run a query 2000 times in a loop, when you could have retrieved all your data with a single database hit.

  • Watch out for lazy loading in ORMs. You shouldn’t lazy load any entities that could be retrieved with a single database hit.

Implement different database queries in different contexts. In the API and on a webpage, you'll inevitably require different entity properties, so don't load things you don’t need just because it's convenient to reuse a query.

類型不一樣的SQL查詢應該在實做在不同的method下. 在API及在webpage要取得的資料不會相同, 不要為了便利...... (這個不一定, 有時候為了便利......所以犠牲一點效能)

????

Get MiniProfiler and configure it to always run when you hit your site (just don't enable it for the general public). You'll get detailed execution times and a big red warning if the same database query is running multiple times.

Make sure paging is conducted at the database layer

在資料處理的時候就分頁,而不是每次回傳全部資料,然後在換頁時再取一次全部資料。

validate及 js 外掛
  • For a snappy user experience, always validate on the client

    在前端做 validate 的工作 (後端也必須做最後一次把關的動作)

    snappy user experience 意指漂亮時髦的使用者經驗嗎?
  • Always perform validation on the server as well

    後端的驗證也需做好 (比較像是安全性的議題)

  • Review what client scripts you are using

    用別人的 script 也要稍微 review 一下

Reduce memory leaks dramatically with the "using" statement

如果一個物件有實做 IDisposable, 最保險的方法就是使用 "using"" statement, 在最後時它自動會 disposes 物件.

Reduce the data sent across the network

指的是css或javascript可以minification (壓縮)或綁在一起送出

Avoid running sites in debug mode

避免網站在偵錯模式下運行

When it comes to ASP.NET, one of the most common performance blunders I see on a regular basis is accidentally or intentionally running sites in debug mode. Language-level optimizations, such as using StringBuilders, Arrays instead of Lists, Switch instead of If-Then-Else, and so on, are popular, but when you measure their real impact, they usually pale in comparison to optimizations at the framework level.

When in production, carefully consider what you need to log

在正式環境下 Log 只考慮必須要記的資訊 . ()測試機跟正式機要記的Log要有不同的配置)

In addition, you should check which targets you are outputting to, what archiving strategy you have, and whether your logging infrastructure allows for async logging.
A selection of tips
  • <img />裡要設高度及寬度, 因為在download之前空間可以先被配置
    Including height and width in < img /> tags will allow your page to render more quickly, because space can be allocated for the image before it is downloaded.
  • script 參考儘量配置在page的下方 (因為downloads halt在js解析的時候) , css及圖片可以 downloaded asynchronously
    個人是不喜歡這樣子,圖片的非同步下載是例外。
  • 使用CDN來載圖及script
  • Use image sprites (圖像拼合) to retrieve smaller images in one download.
  • Use AJAX to retrieve components asynchronously that may not be needed immediately, such as the content of a collapsed panel, content behind a tab, and so on.
  • Make sure you’ve removed HTTP modules that aren’t being used (Windows authentication, for example), and that you’ve disabled services such as FTP and SMTP, if you’re not using them.
????

Use the startMode attribute to reduce the load time for your ASP.NET site

Every time you update your site, IIS must recompile it during the first request, so the initial request takes significantly longer than subsequent ones. An easy solution is to tell IIS to automatically recompile your site as part of the update process. This can be done using the startMode attribute in the ApplicationHost.config file. You can even specify a custom action to run on start-up, such as pre-populating a data cache.

Don't underestimate the value of the UI when tackling performance problems

在處理效能問題時, 別低估了UI的影響

Simple UI tricks, such as progress bars, redirecting user's attention using animation, or placing slower loading sections at the bottom of a page or offscreen, can often 'fix' a performance problem without the need to tune the underlying code. These UI tricks are an important tool to have in your performance tuning toolbox and can be much quicker and easier than addressing the underlying issue. They can act as a holdover until you have the time to devote to the core problem.
是說可以運用一些簡單的小技巧在頁面上, 像是progress bars , 動畫....來引導、減低使用者對於"等待"這檔事的不耐煩感覺。 (其實講的是感覺, 當某些事在當下不可為時, 用另外的方法減少這樣的感覺是一種借力使力的好方法)

Throw hardware at the problem, not developers

有時候更換設備遠比去 troubleshoot, diagnose and 修正更深層的效能問題來的便宜。

As developers, we often want to fix problems with code, but don't be afraid to 'put the compiler down' and throw some hardware at the problem. Performance problems caused by disk I/O bottlenecks or paging out of RAM can often be solved by a faster hard drive or more RAM. CPUbound bottlenecks can often be solved by a new machine with a faster processor. As counterintuitive as it sounds, addressing problems by buying a new machine or upgrading an aging one is often much cheaper than having a developer troubleshoot, diagnose, and correct a deep performance problem. And the rest of your website will get a performance kick to boot!

Don't assume that problems can only arise from business logic

When beginning to diagnose performance problems, we often assume the problem is in our business logic. Don't forget that the areas of our code that provide infrastructure can cause problems as well. Areas such as HttpHandlers, HtmlHelpers, mapping, logging, or IoC frameworks are increasingly at the root of performance problems. While business logic still causes its share of problems, infrastructure code is quickly gaining in the performance problem race.

Before tackling any website performance issue, first verify the problem isn't on the client

在處理及釐清效能議題時, 首先確認問題不是發生在client端的部份(指的是那些js frameworks所產生的問題)

Static collections

If a collection is static, make sure it only contains the objects you need. If the collection is iterated over often, then the performance can be slow if you don't remove unnecessary objects. Objects in a collection will be held in memory, even if they have been disposed of, which can also lead to a memory leak.
Know your loops for 是最快的, foreach 次之, LINQ 是最慢的. (但好用啊! 無奈!)
Seven handy ViewState tips
  1. 如果沒有必要,把 viewState關掉吧!
  2. 在 TextBox 上如果沒必要(例如Text_Changed事件需要時),可以單獨關閉 (控制項也有EnableViewState=false)
  3. Repeaters, ListViews 也會產生巨大的ViewState資料,所以......可也以單獨關閉它。
  4. Data在post時需要重新載入的話,就一定要關掉此控制項的ViewState
  5. BasePage可以這樣全部關掉
    protected override void OnPreInit(EventArgs e)
    {
        // Ensure that ViewState is turned off for every page inheriting this BasePage
        base.EnableViewState = false;
        base.OnPreInit(e);
    }
Avoid using session state

Take advantage of .NET 4.5 async constructs

4.5 的非同步化更好寫了,這樣的CODE可以舒緩IO,DB,網路操作......

StringBuilder is NOT the answer for all string concatenation scenarios; String.Join could be

ORM Tips
T-SQL Tips
  • SELECT * 並不全然是一件壞事,不過如果能針對必要欄位去 select 可以減少一些效能的耗損。
  • 針對小型且經常存取的資料集 (例如字典表),實作Cache在記憶體會更有效率。
  • 確認variables及parameters跟欄位的型態是相同的。implicit跟explicit轉換會導致table scan跟糟糕的效能。
Index Tips
  • You get exactly one clustered index on a table. Ensure you have it in the right place. First choice is the most frequently accessed column, which may or may not be the primary key. Second choice is a column that structures the storage in a way that helps performance. This is a must for partitioning data.
  • Performance is enhanced when indexes are placed on columns used in WHERE, JOIN, ORDER BY, GROUP, and TOP. Always test to ensure that the index does help performance.