為客戶在SharePoint的基礎上搭建了一個門戶,但是客戶又反映說首頁打開太慢,通過Fillder工具檢視,頁面打開速度大概在5秒左右。
其實對于一個SharePoint站點來講,打開速度在3-4秒還是一個可以接受的範圍,但是我們的首頁放了太多的内容,包括圖檔、Flash、還有N多個WebPart,以至于要不斷的從資料庫互動。
首先想到的解決方案是在頁面上加Cache,從Web層到資料層都可以考慮加Cache,但是這個方法很快就被否決了。因為SharePoint2007還不支援對自定義的頁面加載Cache。
第二個解決方案,生成靜态頁面,當使用者通路時,讓其通路靜态頁面。
關于生成靜态頁面,方法還是很多的,簡單列舉下:
1、ASP.NET下Page的RenderControl方法本身就是傳回生成的HTML代碼,該方法在前面的随筆中有提到;
2、Page.Server.Execute(url,stringwriter)方法,隻對該方法做了測試,有時間再深刻鑽研;
簡單代碼:
public bool ExecAspxToHtml()
{
StringWriter strWriterHTML = new StringWriter();
System.Web.UI.Page aspxPage = new System.Web.UI.Page();
aspxPage.Server.Execute(strAspxUrl, strWriterHTML);//将aspx頁執行産生的html輸出到StringWriter中
StreamWriter streamWriter = new StreamWriter(strHtmlFile, true, System.Text.Encoding.GetEncoding("GB2312"));
streamWriter.Write(strWriterHTML.ToString());
strWriterHTML.Close();
streamWriter.Close();
return true;
}
3、模拟HttpWebRequest,擷取HttpWebResponse,采用這種方式來生成。
簡單說頁面運作的機制:當我們在位址欄裡輸入網址後,第一次向伺服器抛Request,用戶端擷取到該Request産生的Response後,對其内部的Html代碼分析,對src,href等連結的檔案則繼續抛Request,擷取Response,知道頁面中需要的檔案都下載下傳到用戶端,頁面才能完全打開。
決定了用第三種方案,對頁面生成的HTMl代碼,需要将其生成如 src 引用的連結檔案同時下載下傳到本地,對href引用的連結需要将其更改為絕對路徑。需要考慮的問題:
1、對頁面内src 的Url進行分析,繼續繼續抛HttpWebRequest擷取該檔案,儲存到本地,同僚更改其src屬性為本地相對路徑。
2、對頁面的href 的url進行分析,在其url前加上網站的伺服器名,成為絕對路徑。
最主要的是這兩個問題,當然還有像Background中連結的圖檔。對于這些url,我都采用了 Regex的比對以及替換的方法。感覺正規表達式還是很強大的。
代碼:
//URL,使用者名都是寫在配置檔案中的
public void ExecuteAspxToHtml()
DistributeRequest(CreateWebRequest(strAspxUrl));
}
private HttpWebRequest CreateWebRequest(string url)
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "GET";
request.Credentials = CreateCredential();
return request;
private ICredentials CreateCredential()
ICredentials credential;
//擷取配置檔案中的值
if (!string.IsNullOrEmpty(GetAppValue("Domain")))
credential = new NetworkCredential(GetAppValue("UserName"), GetAppValue("Password"), GetAppValue("Domain"));
else
credential = new NetworkCredential(GetAppValue("UserName"), GetAppValue("Password"));
return credential;
private void DistributeRequest(HttpWebRequest request)
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
if (Directory.Exists(strHtmlPath))
Directory.CreateDirectory(strHtmlPath);
BinaryReader rsReader = new BinaryReader(response.GetResponseStream());
byte[] buffer = rsReader.ReadBytes((int)response.ContentLength);
//對其内部URl進行分析,擷取檔案
GetContainUrl(response.ContentType, ref buffer);
if (!CompareFile(buffer))
FileStream fStream = new FileStream(strHtmlPath + strHtmlFile, FileMode.Create, FileAccess.Write);
fStream.Write(buffer, 0, buffer.Length);
fStream.Close();
response.Close();
private void DistributeRequest(HttpWebRequest request, string filePath, string fileName)
try
if (Directory.Exists(filePath))
FileStream fStream = new FileStream(filePath + fileName, FileMode.Create, FileAccess.Write);
catch(Exception ex)
Console.WriteLine(ex.Message);
Console.WriteLine(request.RequestUri.ToString());
Console.WriteLine("URI錯誤");
private void GetContainUrl(string ContentType, ref byte[] buffer)
Encoding encode = System.Text.Encoding.GetEncoding("UTF-8");
string strbuffer = encode.GetString(buffer);
strbuffer = HandleSrc(strbuffer);
strbuffer = HandleHref(strbuffer);
buffer = encode.GetBytes(strbuffer);
/// <summary>
/// 對以src=""形式的連結,擷取其檔案儲存到本地
/// </summary>
/// <param name="strBuffer"></param>
/// <returns></returns>
private string HandleSrc(string strBuffer)
Console.WriteLine("Handle the src property to get file");
Console.WriteLine("*************************************");
Regex regex = new Regex(srcRegex, RegexOptions.IgnoreCase);
MatchCollection matchs = regex.Matches(strBuffer);
foreach (Match item in matchs)
if (item.Success)
string matchContent = item.Value;
string filePathName = GetFilePathName(matchContent);
string fileUrl = GetFileUrl(matchContent);
string filePath = filePathName.Substring(0,filePathName.LastIndexOf('\\'));
if (!Directory.Exists(strHtmlPath + filePath))
Directory.CreateDirectory(strHtmlPath + filePath);
//if (!IsUrlFileExist(strHtmlPath, filePathName))
//{
DistributeRequest(CreateWebRequest(fileUrl), strHtmlPath, filePathName);
//}
Console.WriteLine("*************************************************");
Console.WriteLine("Handle the src property and get file completed");
Console.WriteLine();
//上邊的循環可以放在進行中再抛Request,這裡還沒有改回來
return regex.Replace(strBuffer, new MatchEvaluator(SrcMatchHandle));
private string HandleHref(string strBuffer)
Console.WriteLine("Handle the href property to change the relative link to absolute link");
Console.WriteLine("************************************************************************");
Regex regex = new Regex(hrefRegex, RegexOptions.IgnoreCase);
//MatchCollection matchs = regex.Matches(strBuffer);
return regex.Replace(strBuffer, new MatchEvaluator(HrefMatchHandle));
//傳回要替換的字元串,即本地的相對路徑
//該方法在替換時也是周遊執行的,是以可以在該方法裡擷取檔案
private string SrcMatchHandle(Match match)
if (match.Success)
return GetFileRelatvePath(match.Value);
return match.Value;
private string HrefMatchHandle(Match match)
return match.Value.Insert(match.Value.IndexOf('/'), strAspxPath);
其實還是投機了,因為客戶看中的隻是首頁,如果要讓我去做所有頁面的靜态化,那可真是頭疼,涉及到的各種各樣的連結都需要考慮。
現在開發工作已經完成,打算做成一個Windos服務部署到伺服器,定時更新頁面。還是第一次,正在研究,有經驗的朋友可以探讨下。
目标是為了解決SharePoint首頁反應慢的,不過技術全是.Net的技術。
本文轉自左正部落格園部落格,原文連結:http://www.cnblogs.com/soundcode/archive/2010/12/24/1916391.html,如需轉載請自行聯系原作者