前言
在開發中為了緊趕項目進度而未去關注性能的問題,在項目逐漸穩定下來后發現性能令人感到有點憂傷,於是開始去關注這方面,本篇為記錄在開發中遇到的問題並解決,不喜勿噴。注意:以下問題都是在移動端上出現,無法確定在網站中是否也同樣會出現。
卡頓問題
請求方式
項目屬於移動端,在手機上查看某一列表時並進行向下滑動時經常性卡頓問題,滾動的插件采用的是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"。
結語
部分參考來源:《不修改代碼就能優化ASP.NET網站性能的一些方法》。
通過對問題的出現以及解決花費了一點時間,最終使得在手機上請求數據耗時得到大大的改善、頁面加載的速度提高了許多以及滑動數據順暢而由此告一段落。
有些細小的問題平時不太注意,感覺各種方式都能實現,殊不知這樣做的結果是否是一樣,實現的結果一樣,但是呈現出的效果卻是天壤之別,實際開發中發現一些小的細節對整個項目的成敗是多么的重要。