Bài này hướng dẫn các bạn Remove các khoảng trắng trong html trước khi tra dữ liệu về client.
Tại sao lại nên làm điều này. Chẳng hạn việc loại bỏ các khoảng trắng bạn giảm dung lượng được 27kb cho mỗi request:
1 view = 27kb
10 views = 270kb
100 views = 2.7mb
1000 views = 27mb
10000 views = 270mb

using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using Nasa8x.Core;
namespace Nasa8x.Mvc.Attributes
{
public sealed class RemoveHtmlWhiteSpace : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var response = filterContext.HttpContext.Response;
response.Filter = new MinifiedStream(response.Filter);
}
public class MinifiedStream : MemoryStream
{
private static readonly Regex _JAVASCRIPT_TAGS = new Regex(@"<script\s[^>]*>([\w\W]*?)</script>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex _REGEX_BETWEEN_TAGS = new Regex(@">\s+<", RegexOptions.Compiled);
private static readonly Regex _LINE_BREAKS = //new Regex(@"([\n\s])+?(?<= {2,})",RegexOptions.Compiled);//new Regex(@"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/",RegexOptions.Compiled); //
new Regex(@"(?<=[^])\t{2,}|(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,11}(?=[<])|(?=[\n])\s{2,}", RegexOptions.Compiled);
//new Regex(@"([\r\n])|([\t])|([\n\s])+?(?<= {2,})", RegexOptions.Compiled);
private static readonly Regex _HTML_COMMENT = new Regex(@"<!--([\w\W]*?)-->", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex _DISABLE_TAGS = new Regex(@"(<textarea\s[^>]*>([\w\W]*?)</textarea>)|(<pre\s[^>]*>([\w\W]*?)</pre>)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private readonly Stream _output;
public MinifiedStream(Stream stream)
{
_output = stream;
}
public override void Write(byte[] buffer, int offset, int count)
{
var html = Encoding.UTF8.GetString(buffer);
html = _JAVASCRIPT_TAGS.Replace(html, JavaScriptMatch);
html = _REGEX_BETWEEN_TAGS.Replace(html, "> <");
html = _HTML_COMMENT.Replace(html, string.Empty);
if (!_DISABLE_TAGS.IsMatch(html))
{
html = _LINE_BREAKS.Replace(html, string.Empty);
}
_output.Write(Encoding.UTF8.GetBytes(html), offset, Encoding.UTF8.GetByteCount(html));
}
private static string JavaScriptMatch(Match _m)
{
if (_m.Groups[1].Success && !string.IsNullOrEmpty(_m.Groups[1].Value))
return _m.ToString().Replace(_m.Groups[1].Value, string.Format("/*<![CDATA[*/{0}/*]]>*/", new ScriptPacker(ScriptPacker.PackerEncoding.None, true, false).Pack(_m.Groups[1].Value)));
return _m.ToString();
}
}
}
}