記一次ASP.NET MVC效能優化(實際專案中)

風靈使發表於2018-05-27

前言

在開發中為了緊趕專案進度而未去關注效能的問題,在專案逐漸穩定下來後發現效能令人感到有點憂傷,於是開始去關注這方面,本篇為記錄在開發中遇到的問題並解決,不喜勿噴。注意:以下問題都是在移動端上出現,無法確定在網站中是否也同樣會出現。

卡頓問題

請求方式

專案屬於移動端,在手機上檢視某一列表時並進行向下滑動時經常性卡頓問題,滾動的外掛採用的是iscroll,當然懷疑是不是這個外掛問題,但是很快就排除了這個問題,在其他頁面未出現這個問題,後來接著想因為在指令碼中進行Ajax請求超時時間設定為30秒,是不是有可能請求介面耗時導致的呢,經過測試並檢視日誌檔案也不是這個問題,於是我開始檢視寫的指令碼檔案,嚇我一跳,在請求獲取資料列表時,請求方式居然寫的POST,這是同事所為,我改為GET後這樣的問題得到了大大的改善,我詢問同事為什麼用POST而不用GET,他說了一句進行GET請求有問題出現錯誤,這時我才明白他指的是什麼,在MVC中在進行GET請求獲取JSON資料時,需要進行如下設定:

 return Json("",JsonRequestBehavior.AllowGet);

建議:在進行Ajax請求時,是什麼請求方式,請採取對應的方式來進行請求,要不然給出其他請求方式幹嘛,吃飽了撐著嗎!

路徑問題

通過上述請求方式改善後問題得到一定的改善(評論也有指出不是這個導致快慢的問題,同意評論觀點,應該是其他原因導致,還是覺得對應的請求採取對應的方式才是),但是還是存在問題,我們繼續檢視指令碼,我們可能會經常這樣做:我們將需要用到的一些指令碼方法,比如格式日期轉換,獲取cookie等封裝在一個公用指令碼中來方便呼叫。下面我們進行演示下。

在指令碼中進行請求時我們一般進行如下:

        $(function () {
                type: 'get',
                url: "/home/Info",
                data: {},
                success: function () { },
                dataType: "application/json"
            });
        });

但是同事卻是這樣做的,將請求路徑寫在公用指令碼中如下:

var path = "/"

此時我們的請求就變成了這樣:

       $(function () {
            $.ajax({
                type: 'get',
                url: path + "home/Info",
                data: {},
                success: function () { },
                dataType: "json"
            });
        });

這樣寫肯定沒錯,但是事實時當我們改成了第一種時效率馬上提上來了,而用第二種方式時會請求很長時間,方式不同,但是貌似沒什麼區別,至於原因我也不明白,為什麼如同事那樣寫不行。

建議:當進行請求時,請直接寫路徑而不要上述那樣,有時候在你看來,方式一樣,卻導致了不同的結果。

至此也就大致上解決了在手機上滑動時卡頓的問題,當然也不排除指令碼寫的有問題的情況。

快取問題

在頁面請求時為了那些不會改變的指令碼或者資料從而加快頁面載入速度,我們通常使用快取來解決。

指令碼、樣式快取

在進行請求時,有些不會改變的指令碼我們需要進行快取,而不是每請求一次而又重新載入一次,當然此時就有人想到了怎麼樣去快取指令碼的問題,比如如下:

 <script src="~/Scripts/video.js?2016040901"></script>

在指令碼檔案後加上一段數字就ok了,是的確實是這麼簡單,當我們對指令碼檔案進行了修改再去改變下後面的數字即可,但是你有沒有想過,如果專案中指令碼檔案多的數不勝數而且一旦你修改了大量的指令碼檔案,你還去頁面中進行大量的更改,你不累嗎,反正我會累死。而我想到的是將那些一些引入的指令碼在後面直接加上數字肯定是沒問題,因為這樣的指令碼我們基本不會去動了,例如引入jquery指令碼(有些人可能會鑽空子了,去修改也是有可能的),好吧,那我們統一一點諾:我們在配置檔案中可以將其後面的數字作為我們去要修改的指令碼,當我們修改了指令碼直接改變配置檔案中的版本不就得了,這樣方便管理,一勞永逸,何樂而不為。我們下面來看看。

(1)我們在配置檔案中新增修改的指令碼版本(當然你可以隨便寫一串數字,下次修改了指令碼直接改變其數字即可)

  <add key="version" value="2016040901"/>

(2)接著我們寫一個HtmlHelper的擴充套件方法,如下:

    public static class FileHtmlHelper
    {
        private static readonly string s_version = ConfigurationManager.AppSettings["version"].ToString();
        private static readonly string s_root = HttpRuntime.AppDomainAppPath.TrimEnd('\\');
        public static MvcHtmlString RefFileHtml(this HtmlHelper htmlHelper, string path)
        {

            string filePath = s_root + path.Replace("/", "\\");
            return new MvcHtmlString(string.Format("<script type=\"text/javascript\" src=\"{0}?{1}\"></script>\r\n", path, s_version));
        }
    }

(3)此時我們在MVC檢視頁面進行如下呼叫指令碼:

  @Html.RefFileHtml("/Scripts/video.js")

這樣我們就解決了指令碼快取以及方便管理的問題。

建議:在進行指令碼快取為了方便管理可以通過配置檔案讀取修改的版本進行管理指令碼檔案的快取。樣式快取也是如此。

頁面輸出快取

在MVC中我們可以對Action快取,如下:

        [OutputCache(Duration = 30)]
        public ActionResult Cache()
        {
            return View();
        }

那要是當我們有引數來達到快取時,又該如何做呢?直接對整個頁面所有請求的引數進行快取,如下:

        [OutputCache(Duration = 30,VaryByParam="*")]
        public ActionResult Cache()
        {
            return View();
        }

此上對JsonResult也是如此,當我們通過引數來篩選不變的列表時,此時我們完全可以將其進行快取,此時我們明確的引數型別也就是自定義快取。

我們通過配置檔案來進行配置即可,如下:

     <caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="customProfile" duration="900" location="Server" varyByParam="UserId" />
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

在上述還有許多引數供你選擇,選擇你需要的快取引數即可。

在控制器中我們只需新增自定義快取名稱即可:

        [OutputCache(CacheProfile="customProfile"]
        public JsonResult Info()
        {
            return Json(new { result = "ok" }, JsonRequestBehavior.AllowGet);
        }

注意:上述caching節點是位於system.Web節點下,而非system.webServer節點下。

配置檔案修改以及其他

(1)刪除不需要的httpModules,如下:

<httpModules>
    <remove name="Session"/>
    <remove name="RoleManager"/>
    <remove name="PassportAuthentication"/>
    <remove name="Profile"/>
    <remove name="ServiceModel"/>
</httpModules>

(2)由於利用表單驗證,也可以刪除如下httpModules

<httpModules>
    <remove name="WindowsAuthentication"/>
    <remove name="FileAuthorization"/>
</httpModules>

(3)在IIS上啟用壓縮,壓縮響應結果減少網路傳輸時間。

蘋果日期問題注意

當資料進行資料庫儲存時發現在安卓上儲存成功,而在蘋果上儲存失敗,這個問題糾結了很久,並檢視日誌檔案最終發現蘋果上對日期有特殊的格式傳遞,否則為空,於是利用js中的replace方法來進行替換。

 date.replace("-", "/");

此時發現利用replace方法只能替換第一個橫線,最終採用正規表示式全部替換並解決

 date.replace(/-/g, "/");

注意:在蘋果上日期進行傳遞時必須是如”2016/04/09”而不能為”2016-04-09”。

相關文章