MVC页面加载速度优化小记
| ?前言: |
????? 最近做一個(gè)地圖展示頁面,業(yè)務(wù)初期沒什么問題,運(yùn)行一陣后報(bào)錯:
Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.
Google 了一下,原來是由于業(yè)務(wù)數(shù)據(jù)的增多, ajax 后臺返回時(shí)報(bào)錯,參考網(wǎng)上的方法,在返回時(shí)設(shè)置一下 MaxJsonLength
var jsonResult = Json(jsonString);jsonResult.MaxJsonLength = int.MaxValue;return jsonResult;
報(bào)錯的問題是解決了,可還有一個(gè)問題就是頁面加載時(shí)間過長。為了地圖展示的效果,不能進(jìn)行數(shù)據(jù)分頁。
期間嘗試了很多方法,記錄如下:
| ?列表與地圖同步: |
?????? 頁面的布局是左邊顯示數(shù)據(jù)列表,右邊顯示 GoogleMap 。剛開始拼列表的 html 和地圖的初始化、加載是在同一個(gè)方法里面執(zhí)行的,這樣的效果就是列表和地圖同時(shí)顯示,由于地圖的初始化、加載比較耗時(shí),就想讓列表先顯示,地圖初始化完后再顯示。也就是列表顯示和地圖初始化同步執(zhí)行,改后代碼:
if(pageData.length>0){SetListHtml(1);$("#loadGif").hide();setTimeout(function () {SetMap();}, 0);}else{$("#loadGif").hide();}
?
| ?存儲過程和緩存: |
?????? 列表與地圖同步可以讓用戶的體驗(yàn)好一些,但是頁面加載時(shí)間還是過長,于是就把后臺取數(shù)據(jù)改成存儲過程、把一些不是經(jīng)常改變的數(shù)據(jù)做成緩存。在做緩存的過程中,由于不是經(jīng)常改變的數(shù)據(jù)有時(shí)也會改變,因此緩存依賴要設(shè)成 SqlCacheDependency 。具體方法網(wǎng)上有很多。
public DataTable GetCacheGpsBoundary(){string cacheKey = "dtCustomerBoundary";DataTable dtCustomerBoundary = (DataTable)HttpRuntime.Cache.Get(cacheKey);if (dtCustomerBoundary == null){log.Debug("dtCustomerBoundary從數(shù)據(jù)庫中獲取");dtCustomerBoundary = new DataTable();string sql = "";SqlCacheDependency sqlCacheDependency = null;string connectionString = ConfigurationManager.AppSettings[""];using (SqlConnection cn = new SqlConnection(connectionString)){using (SqlCommand cmd = cn.CreateCommand()){cn.Open();cmd.CommandText = sql;sqlCacheDependency = new SqlCacheDependency(cmd);//當(dāng)有DML操作時(shí),onChange事件會接收來自Sql Server通過sq_DispatcherProc存儲過程發(fā)送給應(yīng)用程序的消息。using (SqlDataAdapter adapter = new SqlDataAdapter()) //查詢數(shù)據(jù) {adapter.SelectCommand = cmd;adapter.Fill(dtCustomerBoundary);}}}HttpContext.Current.Cache.Insert(cacheKey, dtCustomerBoundary, sqlCacheDependency);}else{log.Debug("dtCustomerBoundary從緩存中獲取");}return dtCustomerBoundary;}View Code
?
| ?GZip壓縮: |
?????? 存儲過程和緩存在本機(jī)測試的確加快了頁面加載速度,可是發(fā)布到服務(wù)器后頁面加載速度還是不理想。想分析具體原因在哪里,在網(wǎng)上找到一個(gè)工具:
HttpWatch Basic 9.2
Copyright: Copyright 2002 -2014 Simtec Limited
Version: 9.2.6?????
先看下圖例顏色的意義:
我理解 Wait 就是服務(wù)器執(zhí)行用時(shí), Receive 就是傳輸用時(shí)。
沒有加存儲過程和緩存:
再來看下改成存儲過程和加緩存后
最后是啟用 GZip 后的圖
通過 HttpWatch 我們可以看出壓縮后數(shù)據(jù)的大小 853424 ,為壓縮前 4309641 的 19.80% 、用時(shí)也由 8.623 縮短到 3.119 ,由于服務(wù)器當(dāng)前資源、網(wǎng)絡(luò)情況等每次時(shí)間會有所不同。
啟用 GZip 壓縮后,服務(wù)器和客戶端 CPU 負(fù)擔(dān)會加大,但對頁面加載速度效果還是很明顯的,剛開始通過 HttpWatch 看出是由于傳輸數(shù)據(jù)過大使頁面加載時(shí)間過長時(shí),就想到要用壓縮,可在后臺 ajax 方法中對返回的 Json 字符串 采用?GZipStream 壓縮后,在前臺 JavaScript 一直找不到好的方法去解壓,嘗試了很多加解壓算法 Zlib、LZString 等等,加解壓的時(shí)間都太長了,沒什么效果。
看了 單程列車 博客上 .NET MVC 簡單實(shí)現(xiàn)GZIP? 后在后臺添加一個(gè) Filter 就可以實(shí)現(xiàn)服務(wù)端 gzip 壓縮,客戶端會自動解壓,客戶端 ajax 時(shí)可能要加一句
headers: { "Accept-Encoding" : "gzip" } ,其實(shí)我覺得 ajax 就是異步的去打開某一網(wǎng)頁。
| ?總結(jié): |
?????? 分析、看清問題,找到問題真實(shí)原因,才有可能找到好的解決方法;
?????? 剛開始想在取數(shù)據(jù)這塊優(yōu)化,看 sql 的執(zhí)行計(jì)劃看的一頭霧水,今年要買些數(shù)據(jù)庫優(yōu)化方法的書補(bǔ)補(bǔ);
?????? 對 JavaScript、HTTP、C#、MVC、SQL 等等掌握的是否系統(tǒng)、全面在綜合運(yùn)用時(shí)起著決定性的作用
?????? 解決一個(gè)問題的時(shí)候還是很高興的。
| ?參考: |
?http://stackoverflow.com/questions/5692836/maxjsonlength-exception-in-asp-net-mvc-during-javascriptserializer
http://www.cnblogs.com/zhaojingjing/archive/2011/01/20/1940357.html
http://www.cnblogs.com/willick/p/3331520.html
HTTP權(quán)威指南
?
轉(zhuǎn)載于:https://www.cnblogs.com/cg6811568/p/3594149.html
總結(jié)
以上是生活随笔為你收集整理的MVC页面加载速度优化小记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 亚龙湾坐几路公交能到
- 下一篇: 男性不育治疗药物