ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler,
使用<link type="text/css" rel="Stylesheet" href="HttpCombiner.ashx?" />,具体的参数请参考程序中的介绍。附件
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Services; namespace SLTech.DST.Web.Application
{
/// <summary>
/// Summary description for $codebehindclassname$
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class HttpCombiner : IHttpHandler
{
private const bool DO_GZIP = true;
private readonly static TimeSpan CACHE_DURATION = TimeSpan.FromDays(30);
private const string DEFAULT_CSS = "decision-support-toolkit.css,controls/tab.css,controls/extension-button.css,"; public void ProcessRequest(HttpContext context)
{
var request = context.Request; // Read setName, contentType and version.
//All are required. They are used as cache key
var setName = request["s"] ?? string.Empty;
var contentType = request["t"] ?? string.Empty;
var version = request["v"] ?? string.Empty;
var files = request["f"] ?? string.Empty;
files = DEFAULT_CSS + files; // Decide if browser supports compressed response
var isCompressed = DO_GZIP && this.CanGZip(context.Request); // Response is written as UTF8 encoding.
var encoding = new UTF8Encoding(false); // If the set has already been cached, write the response directly from
// cache. Otherwise generate the response and cache it
if (!this.WriteFromCache(context, setName, version, isCompressed, contentType))
{
using (var memoryStream = new MemoryStream(5000))
{
// Decide regular stream or GZipStream based on whether the response
// can be cached or not
using (var writer = isCompressed ?
(Stream)(new GZipStream(memoryStream, CompressionMode.Compress)) :
memoryStream)
{
// Load the files defined and process each file
var fileNames = files.Split(new char[] { ',' },
StringSplitOptions.RemoveEmptyEntries); foreach (string fileName in fileNames)
{
var fileBytes = this.GetFileBytes(context,"css/"+fileName.Trim(), encoding);
writer.Write(fileBytes, 0, fileBytes.Length);
} writer.Close();
} var responseBytes = memoryStream.ToArray();
context.Cache.Insert(GetCacheKey(setName, version, isCompressed),
responseBytes, null, System.Web.Caching.Cache.NoAbsoluteExpiration,
CACHE_DURATION); // Generate the response
this.WriteBytes(responseBytes, context, isCompressed, contentType);
}
}
} private byte[] GetFileBytes(HttpContext context, string virtualPath, Encoding encoding)
{
if (virtualPath.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
{
using (var client = new WebClient())
{
return client.DownloadData(virtualPath);
}
}
else
{
var physicalPath = context.Server.MapPath(virtualPath);
var bytes = File.ReadAllBytes(physicalPath);
return bytes;
}
} private bool WriteFromCache(HttpContext context, string setName, string version,
bool isCompressed, string contentType)
{
var responseBytes = context.Cache[GetCacheKey(setName, version, isCompressed)] as byte[]; if (null == responseBytes || 0 == responseBytes.Length) return false; this.WriteBytes(responseBytes, context, isCompressed, contentType);
return true;
} private void WriteBytes(byte[] bytes, HttpContext context,
bool isCompressed, string contentType)
{
var response = context.Response; response.AppendHeader("Content-Length", bytes.Length.ToString());
response.ContentType = contentType;
if (isCompressed)
response.AppendHeader("Content-Encoding", "gzip"); context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.Add(CACHE_DURATION));
context.Response.Cache.SetMaxAge(CACHE_DURATION);
context.Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate"); response.OutputStream.Write(bytes, 0, bytes.Length);
response.Flush();
} private bool CanGZip(HttpRequest request)
{
var acceptEncoding = request.Headers["Accept-Encoding"];
return (!string.IsNullOrEmpty(acceptEncoding) &&
(acceptEncoding.Contains("gzip") || acceptEncoding.Contains("deflate")));
} private string GetCacheKey(string setName, string version, bool isCompressed)
{
return "HttpCombiner." + setName + "." + version + "." + isCompressed;
} public bool IsReusable
{
get
{
return false;
}
}
}
}
ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler的更多相关文章
-
asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度
介绍 使用许多小得JS.CSS文件代替一个庞大的JS或CSS文件来让代码获得更好的可维 护性,这是一个很好的实践.但这样做反过来却损失了网站的性能.虽然你应该将你的Javascript代码写在小文件中 ...
-
django 解决css,js文件304导致无法加载显示问题
这种情况一般会在windows系统下出现 1.前台.后台如果无法加载css等样式.(建议通过此办法来解决) 这是因为你安装的某些IDE 或者其他更改了注册表导致的系统的注册表\HKEY_CLASSES ...
-
jq常用事件(on,blur,focus,change),js/jq等待图片(页面)加载完毕事件,js读取文件
jq常用事件(on,blur,focus,change) // 方法一(推荐) $('.box').on( "click",function() {} ) $('.box').on ...
-
Pace.js – 超赞的页面加载进度自动指示和 Ajax 导航效果
在页面中引入 Pace.js 和您所选择主题的 CSS 文件,就可以让你的页面拥有漂亮的加载进度和 Ajax 导航效果.不需要挂接到任何代码,自动检测进展.您可以选择颜色和多种效果,有简约,闪光灯, ...
-
【ASP.NET MVC】提高页面加载速度:脚本优化
在这里我们说一下脚本优化的三个方法: 一.在我们做Web开发的时候,当我们引用Js文件的时候,我们一般会将js文件放在文档的head标签中,这时当页面加载的时候,浏览器会按着由上到下的顺序,当浏览器遇 ...
-
JS文件延迟和异步加载:defer和async属性
-般情况下,在文档的 <head> 标签中包含 JavaScript 脚本,或者导入的 JavaScript 文件.这意味着必须等到全部 JavaScript 代码都被加载.解析和执行完以 ...
-
jquery和js的几种页面加载函数的方法以及执行顺序
参考博客:http://www.cnblogs.com/itslives-com/p/4646790.html https://www.cnblogs.com/james641/p/783837 ...
-
webpack打包时排除其中一个css、js文件,或单独打包一个css、js文件
在项目中经常会需要将一些接口的配合文件或者某些样式文件,分离出来单独打包,便于后期改动,这里我以css文件为例,介绍实现两种方法: 项目目录: 如上图所示,现在我需要将项目中的scBtn.css文件单 ...
-
Maven使用yuicompressor-maven-plugin打包压缩css、js文件
最近项目想使用在maven打包的时间压缩js,css文件,采用yuicompressor-maven-plugin插件进行压缩,但只是压缩减小大小,提高请求速度,并没有对js进行混淆.下面就写一下这个 ...
随机推荐
-
Django的virtualenv环境搭建
安装virtualenv好处多多,可以让当前的项目使用单独的类库,实现系统类库的隔离,所以能够*地控制当前项目类库的版本,不受系统类库的影响:还有其他N多好处. 下面是安装说明和使用示例: 首先安装 ...
-
东京区域2012-2014主要消费产品价格参考表——Excel
声明: 1.本表格数据取自<日本の統計 2016>: 2.本表所有价格单位为人民币,其日元均以当年平均汇率兑换为此人民币价格: 3.其人民币—日元年均汇率数据取自IMF Data Exch ...
-
C的快速趋向实验 -->;
今天刚学到C的一个新玩法,非常有意思,叫趋向于,写作“-->”,比如说如果要实现一个倒数的程序,我们可以定义一个变量 counter,然后让它趋向于0... #include <stdio ...
-
bzoj 3999: [TJOI2015]旅游
Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...
-
iOS开发中一些有用的小代码
1.判断邮箱格式是否正确的代码: //利用正则表达式验证 -(BOOL)isValidateEmail:(NSString *)email { NSString *emailRegex = @&q ...
-
【NOI 2015】品酒大会
Problem Description 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品酒家"和" ...
-
PADS 脚本记录:关于 getObjects
PADS 脚本记录:关于 getObjects GetObjects(plogObjectTypeComponent, "ZBOM*", False) 返回的一个对象,所有 ZBO ...
-
C++解析(13):临时对象与const对象
0.目录 1.临时对象 2.const对象 3.类成员 4.小结 1.临时对象 一个有趣的问题--下面的程序输出什么?为什么? #include <stdio.h> class Test ...
-
ext:grid分页,列宽度自动填满grid宽度
var cm = new Ext.grid.ColumnModel([{ header : '编号', dataIndex : 'id' }, { header ...
-
【bzoj1579】[Usaco2009 Feb]Revamping Trails 道路升级 分层图最短路
题目描述 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 < ...