ASP. NET 페이지 최적화, 불 러 오 는 속도 향상
34985 단어 asp.net
namespace ASPNETCode.HttpModules
{
public class CommonModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += Application_BeginRequest;
}
private void Application_BeginRequest(object sender, EventArgs e)
{
var context = HttpContext.Current;
var request = context.Request;
var url = request.RawUrl;
var response = context.Response;
var path = GetPath(url);
var file = new FileInfo(path);
if (DateTime.Now.Subtract(file.LastWriteTime).TotalDays < 7)
{
response.TransmitFile(path);
response.End();
return;
}
try
{
var stream = file.OpenWrite();
response.Filter = new CommonFilter(response.Filter, stream);
}
catch (Exception)
{
//Log.Insert("");
}
}
public void Dispose()
{
}
private static string GetPath(string url)
{
var hash = Hash(url);
string fold = HttpContext.Current.Server.MapPath("~/Temp/");
return string.Concat(fold, hash);
}
private static string Hash(string url)
{
url = url.ToUpperInvariant();
var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
var bs = md5.ComputeHash(Encoding.ASCII.GetBytes(url));
var s = new StringBuilder();
foreach (var b in bs)
{
s.Append(b.ToString("x2").ToLower());
}
return s.ToString();
}
}
}
2. 페이지 GZIP 압축 페이지 GZIP 압축 은 거의 모든 편 에서 고성능 WEB 프로그램 을 설명 하 는 몇 가지 방법 중 하나 이다. GZIP 압축 을 사용 하면 서버 가 보 내 는 바이트 수 를 낮 출 수 있 고 고객 에 게 웹 페이지 의 속도 가 빠 르 고 대역 폭 에 대한 사용 상황 도 줄 일 수 있 기 때문이다.물론 클 라 이언 트 의 브 라 우 저가 지원 하 는 지 여부 도 존재 한다.따라서 우리 가 해 야 할 일 은 클 라 이언 트 가 GZIP 을 지원 하면 GZIP 압축 된 내용 을 보 내 고 지원 하지 않 으 면 정적 파일 의 내용 을 직접 보 내 는 것 입 니 다.다행히 현대 브 라 우 저 IE 6.7.8.0, 파이 어 폭 스 등 은 GZIP 을 지원 한다.이 기능 을 실현 하기 위해 서 는 위의 application 을 고 쳐 써 야 합 니 다.BeginRequest 이벤트:
private void Application_BeginRequest(object sender, EventArgs e)
{
var context = HttpContext.Current;
var request = context.Request;
var url = request.RawUrl;
var response = context.Response;
var path = GetPath(url);
var file = new FileInfo(path);
//
ResponseCompressionType compressionType = this.GetCompressionMode(request);
if (compressionType != ResponseCompressionType.None)
{
response.AppendHeader("Content-Encoding", compressionType.ToString().ToLower());
if (compressionType == ResponseCompressionType.GZip)
{
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else
{
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
}
if (DateTime.Now.Subtract(file.LastWriteTime).TotalMinutes < 5)
{
response.TransmitFile(path);
response.End();
return;
}
try
{
var stream = file.OpenWrite();
response.Filter = new CommonFilter(response.Filter, stream);
}
catch (Exception)
{
//Log.Insert("");
}
}
private ResponseCompressionType GetCompressionMode(HttpRequest request)
{
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding))
return ResponseCompressionType.None;
acceptEncoding = acceptEncoding.ToUpperInvariant();
if (acceptEncoding.Contains("GZIP"))
return ResponseCompressionType.GZip;
else if (acceptEncoding.Contains("DEFLATE"))
return ResponseCompressionType.Deflate;
else
return ResponseCompressionType.None;
}
private enum ResponseCompressionType
{
None,
GZip,
Deflate
}
3. OutputCache 프로 그래 밍 방식 으로 페이지 캐 시 를 출력 합 니 다. ASP. 내 장 된 OutputCache 캐 시 는 내용 을 세 곳 에 캐 시 할 수 있 습 니 다. 웹 서버, 프 록 시 서버 와 브 라 우 저 입 니 다.사용자 가 OutputCache 로 설 정 된 페이지 에 접근 할 때 ASP. NET 은 MSIL 이후 에 결 과 를 output cache 캐 시 에 기록 한 다음 브 라 우 저 에 보 냅 니 다. 사용자 가 같은 경로 의 페이지 에 접근 할 때 ASP. NET 은. aspx 컴 파일 및 MSIL 을 실행 하 는 과정 을 거치 지 않 고 Cache 의 내용 을 직접 보 냅 니 다. 따라서 프로그램 자체 의 효율 이 향상 되 지 않 았 지만,하지만 페이지 불 러 오 는 속 도 는 향상 되 었 다.이 기능 을 실현 하기 위해 서, 우 리 는 위의 응용 프로그램 을 계속 고 쳐 씁 니 다BeginRequest 이벤트, TransmitFile 이후 이 경로 의 페이지 를 OutputCache 프로 그래 밍 방식 으로 캐 시 합 니 다.
private void Application_BeginRequest(object sender, EventArgs e)
{
if (DateTime.Now.Subtract(file.LastWriteTime).TotalMinutes < 5)
{
response.TransmitFile(path);
// OutputCache ,
response.Cache.SetExpires(DateTime.Now.AddMinutes(5));
response.Cache.SetCacheability(HttpCacheability.Public);
response.End();
return;
}
}
4. CommonFilter 류 필터 ViewState, 필터 Naming Container, 공백 문자열, 그리고 디스크 를 생 성 하 는 캐 시 파일 을 실현 합 니 다. response. Filter 의 Stream 대상 을 CommonFilter 류 에 전달 합 니 다. 우선, 우 리 는 먼저 Stream 의 Write 방법 으로 디스크 의 캐 시 파일 을 생 성 합 니 다. 코드 는 다음 과 같 습 니 다. 이 코드 에서 구조 함수, Write 방법 만 초기 화 합 니 다.Close 방식 은 유용 합 니 다. 그 중에서 FileStream 필드 는 정적 파일 을 만 드 는 작업 대상 입 니 다.
namespace ASPNETCode.HttpModules
{
public class CommonFilter : Stream
{
private readonly Stream _responseStream;
private readonly FileStream _cacheStream;
public override bool CanRead
{
get
{
return false;
}
}
public override bool CanSeek
{
get
{
return false;
}
}
public override bool CanWrite
{
get
{
return _responseStream.CanWrite;
}
}
public override long Length
{
get
{
throw new NotSupportedException();
}
}
public override long Position
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
public CommonFilter(Stream responseStream, FileStream stream)
{
_responseStream = responseStream;
_cacheStream = stream;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long length)
{
throw new NotSupportedException();
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override void Flush()
{
_responseStream.Flush();
_cacheStream.Flush();
}
public override void Write(byte[] buffer, int offset, int count)
{
_cacheStream.Write(buffer, offset, count);
_responseStream.Write(buffer, offset, count);
}
public override void Close()
{
_responseStream.Close();
_cacheStream.Close();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_responseStream.Dispose();
_cacheStream.Dispose();
}
}
}
}
그리고 우 리 는 정규 를 이용 하여 ViewState 를 완전히 삭제 합 니 다.
// ViewState
private string ViewStateFilter(string strHTML)
{
string matchString1 = "type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\"";
string matchString2 = "type=\"hidden\" name=\"__EVENTVALIDATION\" id=\"__EVENTVALIDATION\"";
string matchString3 = "type=\"hidden\" name=\"__EVENTTARGET\" id=\"__EVENTTARGET\"";
string matchString4 = "type=\"hidden\" name=\"__EVENTARGUMENT\" id=\"__EVENTARGUMENT\"";
string positiveLookahead1 = "(?=.*(" + Regex.Escape(matchString1) + "))";
string positiveLookahead2 = "(?=.*(" + Regex.Escape(matchString2) + "))";
string positiveLookahead3 = "(?=.*(" + Regex.Escape(matchString3) + "))";
string positiveLookahead4 = "(?=.*(" + Regex.Escape(matchString4) + "))";
RegexOptions opt = RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant | RegexOptions.Compiled;
Regex[] arrRe = new Regex[] {
new Regex("\\s*<div>" + positiveLookahead1 + "(.*?)</div>\\s*", opt),
new Regex("\\s*<div>" + positiveLookahead2 + "(.*?)</div>\\s*", opt),
new Regex("\\s*<div>" + positiveLookahead3 + "(.*?)</div>\\s*", opt),
new Regex("\\s*<div>" + positiveLookahead3 + "(.*?)</div>\\s*", opt),
new Regex("\\s*<div>" + positiveLookahead4 + "(.*?)</div>\\s*", opt)
};
foreach (Regex re in arrRe)
{
strHTML = re.Replace(strHTML, "");
}
return strHTML;
}
다음은 페이지 공백 을 삭제 하 는 방법 입 니 다.
//
private Regex tabsRe = new Regex("\\t", RegexOptions.Compiled | RegexOptions.Multiline);
private Regex carriageReturnRe = new Regex(">\\r\
<", RegexOptions.Compiled | RegexOptions.Multiline);
private Regex carriageReturnSafeRe = new Regex("\\r\
", RegexOptions.Compiled | RegexOptions.Multiline);
private Regex multipleSpaces = new Regex(" ", RegexOptions.Compiled | RegexOptions.Multiline);
private Regex spaceBetweenTags = new Regex(">\\s<", RegexOptions.Compiled | RegexOptions.Multiline);
private string WhitespaceFilter(string html)
{
html = tabsRe.Replace(html, string.Empty);
html = carriageReturnRe.Replace(html, "><");
html = carriageReturnSafeRe.Replace(html, " ");
while (multipleSpaces.IsMatch(html))
html = multipleSpaces.Replace(html, " ");
html = spaceBetweenTags.Replace(html, "><");
html = html.Replace("//<![CDATA[", "");
html = html.Replace("//]]>", "");
return html;
}
다음은 ASP. NET 컨트롤 의 쓰레기 UniqueID 이름 을 삭제 하 는 방법 입 니 다.
// NamingContainer
private string NamingContainerFilter(string html)
{
RegexOptions opt =
RegexOptions.IgnoreCase |
RegexOptions.Singleline |
RegexOptions.CultureInvariant |
RegexOptions.Compiled;
Regex re = new Regex("( name=\")(?=.*(" + Regex.Escape("$") + "))([^\"]+?)(\")", opt);
html = re.Replace(html, new MatchEvaluator(delegate(Match m)
{
int lastDollarSignIndex = m.Value.LastIndexOf('$');
if (lastDollarSignIndex >= 0)
{
return m.Groups[1].Value + m.Value.Substring(lastDollarSignIndex + 1);
}
else
{
return m.Value;
}
}));
return html;
}
마지막 으로, 우 리 는 상기 여과 방법 을 CommonFilter 류 의 Write 방법 에 통합 시 켰 다.
public override void Write(byte[] buffer, int offset, int count)
{
// buffer
byte[] data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
string html = System.Text.Encoding.UTF8.GetString(buffer);
//
html = NamingContainerFilter(html);
html = ViewStateFilter(html);
html = WhitespaceFilter(html);
byte[] outdata = System.Text.Encoding.UTF8.GetBytes(html);
//
_cacheStream.Write(outdata, 0, outdata.GetLength(0));
_responseStream.Write(outdata, 0, outdata.GetLength(0));
}
5. 캐 시 파 괴 는 상기 프로그램의 실현 을 거 쳐 웹 페이지 는 클 라 이언 트 에 고속 캐 시 되 었 습 니 다. 만약 에 사용자 가 사이트 가 캐 시 된 페이지 를 방문 하면 페이지 는 0 요청 속도 로 페이지 를 불 러 옵 니 다.그러나 배경 에 일부 데 이 터 를 업데이트 하면 프론트 사용 자 는 최신 데 이 터 를 제때에 볼 수 없 기 때문에 이러한 상황 을 바 꾸 려 면 캐 시 를 파괴 해 야 합 니 다.위의 프로그램 에 따 르 면 캐 시 를 파괴 하려 면 2 단계 만 해 야 합 니 다. 서버 에 있 는 임시 파일 을 업데이트 하고 OutputCache 가 지나 간 페이지 를 삭제 합 니 다.서버 에 있 는 파일 을 업데이트 하려 면 이 파일 만 삭제 하면 됩 니 다. 사용자 가 이 페이지 를 처음 방문 할 때 자동 으로 생 성 됩 니 다. 물론 프로그램 으로 먼저 삭제 한 후에 생 성 할 수도 있 습 니 다.
//
foreach ( var file in Directory.GetFiles( HttpRuntime.AppDomainAppPath + "Temp" ) ) {
File.Delete( file );
}
OutputCache 와 연 결 된 캐 시 항목 을 삭제 하려 면 코드 는 다음 과 같 습 니 다. 우 리 는 이 방법의 매개 변수 만 확보 해 야 합 니 다. 페이지 의 절대 경로 가 정확 하고 경 로 는 사용 할 수 없습니다.. / 이러한 상대 경 로 를 말 합 니 다.
//
HttpResponse.RemoveOutputCacheItem( "/Default.aspx" );
최적화 가 끝나 지 않 았 습 니 다. 전 투 는 계속 되 고 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
작업 중 문제 해결 - (win 2003 asp. net) Session 과 페이지 전송 방법 으로 해결 방안 을 정상적으로 사용 할 수 없습니다.또한 F 는 처음에 우리 의 BP & IT 프로젝트 팀 이 Forms 폼 검증 을 사용 했다 고 판단 할 수 있 습 니 다. 페이지 를 뛰 어 넘 는 것 은http://hr.bingjun.cc/MyTask/MyTas...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.