做web前段也有一段时间了,对于web中js文件的加载有些体会想跟大家一起分享一下。

1.首先说说js文件的合并和压缩吧

为了便于集中式管理js的合并和压缩我们创建一个Js.ashx文件来专门处理合并压缩

代码如下:

public class Js : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/javascript";
HttpRequest request = context.Request;
HttpResponse response = context.Response;
if (!request.QueryString.AllKeys.Contains("href"))
{
response.Write("No Content");
}
else
{
string href = context.Request.QueryString["href"].Trim();
string[] files = href.Split(new string[] { ",", ",?" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string fileName in files)
{
string filePath = context.Server.MapPath(fileName);
if (File.Exists(filePath))
{
string content = File.ReadAllText(filePath, Encoding.UTF8);
content = JavaScriptCompressor.Compress(content);
response.Write(content);
}
}
}
} public bool IsReusable
{
get
{
return false;
}
}
}

返回结果如图:

但是在实际开发中很多项目为了最求js的合并和压缩,开发很不友好把js的引用放在一个地方,写了很长的一串啊,如上面js引用。
下面说说如何改善吧:

public static class Extensions
{
const string jsFileKey = "JSFileKey";
static string jshandlerUrl = string.Empty;
public static string JsHandlerUrl
{
get
{
if (string.IsNullOrEmpty(jshandlerUrl))
{
jshandlerUrl = ConfigurationManager.AppSettings["jsHandlerUrl"] ?? string.Empty;
}
return jshandlerUrl;
}
} public static void AppendJsFile(this HtmlHelper htmlHelper, string jsFile, int group = 1)
{
NameValueCollection jsFiles = null;
if (htmlHelper.ViewContext.HttpContext.Items.Contains(jsFileKey))
{
jsFiles = htmlHelper.ViewContext.HttpContext.Items[jsFileKey] as NameValueCollection;
}
else
{
jsFiles = new NameValueCollection();
htmlHelper.ViewContext.HttpContext.Items.Add(jsFileKey, jsFiles);
}
if (jsFiles.AllKeys.Contains(group.ToString()))
{
string fileUrl = jsFiles[group.ToString()];
if (!fileUrl.Contains(jsFile))
jsFiles.Add(group.ToString(), jsFile);
}
else
{
jsFiles.Add(group.ToString(), jsFile);
} htmlHelper.ViewContext.HttpContext.Items[jsFileKey] = jsFiles;
} public static MvcHtmlString RenderJsFile(this HtmlHelper htmlHelper)
{
NameValueCollection jsFiles = null;
StringBuilder content = new StringBuilder();
if (htmlHelper.ViewContext.HttpContext.Items.Contains(jsFileKey))
{
jsFiles = htmlHelper.ViewContext.HttpContext.Items[jsFileKey] as NameValueCollection;
List<string> jsKeys = jsFiles.AllKeys.OrderBy(x => x).ToList<string>(); string jsFormat = "<script type="text/javascript" src="{0}"></script>";
foreach (string key in jsKeys)
{
string jsFile = jsFiles[key];
content.AppendFormat(jsFormat, JsHandlerUrl + jsFile);
//htmlHelper.ViewContext.HttpContext.Response.Write(string.Format(jsFormat, JsHandlerUrl + jsFile));
}
}
return new MvcHtmlString(content.ToString());
}
}

这样在开发的时候我们书写代码就很方便了如:
[csharp]
@{Html.AppendJsFile("Scripts/jquery.lazyload.js");}
下面我们来看看js的延迟加载,为了实现js延迟加载我们需要引用相关的js,在这里我用的是lazyload.js,具体请参考http://www.2cto.com/kf/201205/130023.html
延迟加载后的效果

在文档加载前只加载了一个2.2k的lazyload.js文件,其他的js文件都在ready后加载。
下面再来看看js的缓存吧,缓存涉及到要做服务端和客户端缓存

修改后的代码:

class CacheItem
{
public string Content { set; get; }
public DateTime Expires { set; get; }
}
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/javascript";
HttpRequest request = context.Request;
HttpResponse response = context.Response;
if (!request.QueryString.AllKeys.Contains("href"))
{
response.Write("No Content");
}
else
{
string href = context.Request.QueryString["href"].Trim();
string[] files = href.Split(new string[] { ",", ",?" }, StringSplitOptions.RemoveEmptyEntries);
CacheItem item = null;
object obj = HttpRuntime.Cache.Get(href);//服t务?端?缓o存?
if (null == obj)
{
StringBuilder allText = new StringBuilder();
foreach (string fileName in files)
{
string filePath = context.Server.MapPath(fileName);
if (File.Exists(filePath))
{
string content = File.ReadAllText(filePath, Encoding.UTF8);
content = JavaScriptCompressor.Compress(content);
//response.Write(content);
allText.Append(content);
}
else
{
// response.Write("rn未找到源文件"+filePath+"rn");
allText.Append("rn未找到源文件" + filePath + "rn");
}
}//end foreach
item = new CacheItem() { Content = allText.ToString(), Expires = DateTime.Now.AddHours(1) };
HttpRuntime.Cache.Insert(href, item, null, item.Expires, TimeSpan.Zero);
}
else
{
item = obj as CacheItem;
}
if (request.Headers["If-Modified-Since"] != null && TimeSpan.FromTicks(item.Expires.Ticks - DateTime.Parse(request.Headers["If-Modified-Since"]).Ticks).Seconds < 100)
{
response.StatusCode = 304;
// response.Headers.Add("Content-Encoding", "gzip");
response.StatusDescription = "Not Modified";
}
else
{
response.Write(item.Content);
SetClientCaching(response, DateTime.Now);
}
}//end else href
}
private void SetClientCaching(HttpResponse response, DateTime lastModified)
{
response.Cache.SetETag(lastModified.Ticks.ToString());
response.Cache.SetLastModified(lastModified);
//public 以指定响应能由客户端和共享(代理)缓存进行缓存。
response.Cache.SetCacheability(HttpCacheability.Public);
//是允许文档在被视为陈旧之前存在的最长绝对时间。
response.Cache.SetMaxAge(new TimeSpan(7, 0, 0, 0));
//将缓存过期从绝对时间设置为可调时间
response.Cache.SetSlidingExpiration(true);
}

}

运行效果如图:


代码下载地址:http://www.2cto.com/uploadfile/2012/0503/20120503021534861.zip

js文件合并,压缩,缓存,延迟加载的更多相关文章

  1. gulp 之一 安装及简单CSS,JS文件合并压缩

    最近研究了一下gulp构建工具,发现使用起来比grunt顺手一些.(个人感受),以下是grunt和gulp构建方式和原理: grunt 基于文件方式构建,会把文件先写到临时目录下,然后进行读文件,修改 ...

  2. 使用System.Web.Optimization对CSS和JS文件合并压缩

    在ASP.NET MVC 中JS/CSS文件动态合并及压缩通过调用System.Web.Optimization定义的类ScriptBundle及StyleBundle来实现. 大致步骤如下: 1.A ...

  3. AngularJS结合RequireJS做文件合并压缩的那些坑

    我在项目使用了AngularJS框架,用RequireJS做异步模块加载(AMD),在做文件合并压缩时,遇到了一些坑,有些只是解决了,但不明白原因. 那些坑 1. build.js里面的paths必须 ...

  4. 【JS代码压缩】使用YUI Compressor对js文件进行压缩处理

    概述 在使用html5开发Hybird APP的时候,可能会引入大量的js包,另外对于一些核心的js文件,进行一些特殊的处理, 如压缩和加密就显得很重要了,YUI Compressor就是这样一个用于 ...

  5. 编写gulpfile.js文件:压缩合并css、js

    使用gulp一共有四个步骤: 1. 全局安装 gulp: $ npm install --global gulp 2. 作为项目的开发依赖(devDependencies)安装: $ npm inst ...

  6. 前端js文件合并三种方式

    最近在思考前端js文件该如何合并,当然不包括不能合并文件,而是我们能合并的文件,想了想应该也只有三种方式. 三个方式如下: 1. 一个大文件,所有js合并成一个大文件,所有页面都引用它. 2. 各个页 ...

  7. CSS 和 JS 文件合并工具

    写 CSS 和 JavaScript 的时候, 我们会遇到一个两难的局面: 要么将代码写在一个大文件, 要么将代码分成多个文件. 前者导致文件难以管理, 代码复用性差, 后者则因为需要在载入多个文件令 ...

  8. RequireJS 文件合并压缩

    RequireJS的define 以及require 对于我们进行简化JavaScript 开发,进行模块化的处理具有很大的帮助 但是请求加载的js 文件会有一些影响,一般的处理是对于文件进行压缩,但 ...

  9. uglifyjs 合并压缩 js, clean-css 合并压缩css

    本文主要介绍如何通过CLI命令行(也就是终端或者cmd打开的那个shell窗口)实现 js和 css 的合并压缩. uglifyjs 合并压缩 js: 1.安装node 这一步就不多说了,下载node ...

随机推荐

  1. Transactional replication-如何跳过一个事务

    在transactional replication, 经常会遇到数据同步延迟的情况.有时候这些延迟是由于在publication中执行了一个更新,例如update ta set col=? Wher ...

  2. [.NET领域驱动设计实战系列]专题六:DDD实践案例:网上书店订单功能的实现

    一.引言 上一专题已经为网上书店实现了购物车的功能了,在这一专题中,将继续对网上书店案例进行完善,本专题将对网上书店订单功能的实现进行介绍,现在废话不多说了,让我们来一起看看订单功能是如何实现的吧. ...

  3. XSS零碎指南

    该文章是本人两天的学习笔记,共享出来,跟大家交流.知识比较零散,但是对有一定 JS 基础的人来说,每个小知识都有助于开阔你的 Hack 视角.首先声明,本文只是 XSS 攻击的冰山一角,读者自行深入研 ...

  4. Android多线程分析之四:MessageQueue的实现

    Android多线程分析之四:MessageQueue的实现 罗朝辉 (http://www.cnblogs.com/kesalin/) CC 许可,转载请注明出处 在前面两篇文章<Androi ...

  5. winform 通过webservice向服务器提交图片需要注意的地方

    最近一个winform项目中需要通过拍照或者上传本地文件或者截图的方式把产品图片上传到服务器,最后选择了服务器部署webservice的方式来进行.其中遇到了一些问题记录下来. 不多说,直接上服务端代 ...

  6. java线程与并发(二)

    一般而言,线程通常有以下的这么几个状态: 创建状态:准备好了一个多线程操作对象 就绪状态:调用了start()方法,等待CPU调度 运行状态:执行run()方法,正在运行 阻塞状态:暂时停止执行,把资 ...

  7. 虚拟化平台cloudstack(5)——参考资料

    虚拟化的几种方式 完全虚拟化: 半虚拟化: 硬件辅助虚拟化: 详细的内容可以看: http://pan.baidu.com/share/link?shareid=4134188256&uk=2 ...

  8. jdk研究——java.lang

    jdk研究 volatile 是什么意思? 如何看jdk源码? 如何调试源码!---------仔细解读关键类,关键代码,常用的api的解释! 自己有疑问的不懂地方-------- 不懂的太多怎么办. ...

  9. Java程序员的日常 —— 《编程思想》持有对象

    集合框架可以说是Java里面必备的知识点了,日常的使用中也会遇到各种情况需要使用到集合.下面就简单介绍下各种集合的使用场景: List List可以看做是数组,实现的方式有两种: ArrayList ...

  10. Storm 实战:构建大数据实时计算

    Storm 实战:构建大数据实时计算(阿里巴巴集团技术丛书,大数据丛书.大型互联网公司大数据实时处理干货分享!来自淘宝一线技术团队的丰富实践,快速掌握Storm技术精髓!) 阿里巴巴集团数据平台事业部 ...