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的更多相关文章

  1. asp.net使用httphandler打包多CSS或JS文件以加快页面加载速度

    介绍 使用许多小得JS.CSS文件代替一个庞大的JS或CSS文件来让代码获得更好的可维 护性,这是一个很好的实践.但这样做反过来却损失了网站的性能.虽然你应该将你的Javascript代码写在小文件中 ...

  2. django 解决css,js文件304导致无法加载显示问题

    这种情况一般会在windows系统下出现 1.前台.后台如果无法加载css等样式.(建议通过此办法来解决) 这是因为你安装的某些IDE 或者其他更改了注册表导致的系统的注册表\HKEY_CLASSES ...

  3. jq常用事件(on,blur,focus,change),js/jq等待图片(页面)加载完毕事件,js读取文件

    jq常用事件(on,blur,focus,change) // 方法一(推荐) $('.box').on( "click",function() {} ) $('.box').on ...

  4. Pace.js – 超赞的页面加载进度自动指示和 Ajax 导航效果

    在页面中引入 Pace.js  和您所选择主题的 CSS 文件,就可以让你的页面拥有漂亮的加载进度和 Ajax 导航效果.不需要挂接到任何代码,自动检测进展.您可以选择颜色和多种效果,有简约,闪光灯, ...

  5. 【ASP.NET MVC】提高页面加载速度:脚本优化

    在这里我们说一下脚本优化的三个方法: 一.在我们做Web开发的时候,当我们引用Js文件的时候,我们一般会将js文件放在文档的head标签中,这时当页面加载的时候,浏览器会按着由上到下的顺序,当浏览器遇 ...

  6. JS文件延迟和异步加载:defer和async属性

    -般情况下,在文档的 <head> 标签中包含 JavaScript 脚本,或者导入的 JavaScript 文件.这意味着必须等到全部 JavaScript 代码都被加载.解析和执行完以 ...

  7. jquery和js的几种页面加载函数的方法以及执行顺序

    参考博客:http://www.cnblogs.com/itslives-com/p/4646790.html    https://www.cnblogs.com/james641/p/783837 ...

  8. webpack打包时排除其中一个css、js文件,或单独打包一个css、js文件

    在项目中经常会需要将一些接口的配合文件或者某些样式文件,分离出来单独打包,便于后期改动,这里我以css文件为例,介绍实现两种方法: 项目目录: 如上图所示,现在我需要将项目中的scBtn.css文件单 ...

  9. Maven使用yuicompressor-maven-plugin打包压缩css、js文件

    最近项目想使用在maven打包的时间压缩js,css文件,采用yuicompressor-maven-plugin插件进行压缩,但只是压缩减小大小,提高请求速度,并没有对js进行混淆.下面就写一下这个 ...

随机推荐

  1. 为在Windows Azure上的网站配置自定义域名

    本篇体验给Windows Azure上的网站自定义域名,首先"CNAME"和"A记录"是必须了解的概念. 假设,在Windows Azure上的网站域名是:x. ...

  2. Android Service总结02 service介绍

    Android Service总结02 service介绍 版本 版本说明 发布时间 发布人 V1.0 介绍了Service的种类,常用API,生命周期等内容. 2013-03-16 Skywang ...

  3. mongodb如何设置主键自增

    function getNextSequence(name){ var ret = db.counters.findAndModify({ query: { _id: name}, update:{ ...

  4. bat调用TexturePacker更新SpriteSheet

    一款游戏会用到很多图片资源,通常我们会使用TexturePacker工具进行图片的拼接.压缩,为了考虑性能问题,单个SpriteSheet的尺寸不会设置的太大(最大1024 * 1024),这样就可能 ...

  5. TextView 中文文档

    属性名称 描述 android:autoLink 设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web/email/phone/map/all) ...

  6. 《RESTful Web APIs中文版》

    <RESTful Web APIs中文版> 基本信息 原书名:RESTful Web APIs 原出版社: O'Reilly Media 作者: Leonard Richardson    ...

  7. javascript中使用new与不使用实例化对象的区别

    我们先来看个实例 function Me(name,age,job){ this.name = name; this.age = age; this.job = job; } 请问这以下两种实例化对象 ...

  8. emouse思·睿—评论与观点整理之三

    虽说我主要做的硬件,平时的兴趣爱好比较关注移动互联网,混迹于虎嗅.爱范儿.雷锋网.36Kr.cnBeta.瘾科技.i黑马.TechWeb等这类科技以及创业媒体,遗憾的是系统的去写的并不多,好在还算充分 ...

  9. 我眼中的SCRUM

    回顾一下我所认识的scrum,算是对自己知识的一个梳理. scrum到底是什么,书中都说,它不是方法学,不是过程,而是一个框架.我并没有太理解这句话,所以先把scrum中都有些什么来说一下(可跟前一篇 ...

  10. WinCE程序调试方法【转】

    刚刚接触WinCE编程,感觉大部分跟WinForm一样.刚开始的时候,不知道怎么进行断点调试,后来同事告诉我,可以直接连接进行断点调试,一试之下,果然好用,所以拿出来分享一下. 必备工具: Micro ...