首先感谢某某作者写的文章:http://www.jb51.net/article/12793.htm

直接上代码,注意文件名为env.js

原理如下:

一次批量加要加载的文件存入数组,采用Ajax方式异步载入各个文件,然后采用循环方式逐个执行下载下来的Js或者Css文件,如果已经被缓存(localStorage)的则省略下载过程。

由于JS采用的是单线程模式运行,在执行某一个js时会阻塞其它并发的js执行,所以会按顺序执行各个js。在执行完所有的脚本之后,图片会被浏览器接着加载,所以第一次加载速度略慢,后面就会比较快了。在JQuery Mobile 1.4.5+FireFox/微信浏览器下实测效果不错,IE就被省略了,我主要是要在微信浏览器下使用。

//需要引用别的js的时候,就加上如Env.require("cookie.js"),或Env.require("/common/cookie.js"),是用相对路径还是绝对路径就看喜好了。
//Env.require可用在页面模板中,也可用在js文件中,但一定要保证执行时env.js被显式引入。
//多次Env.require同一个js(不管用相对还是绝对),只有第一次会加载,所以不会重复。//程序最后发行的版本,用于作为缓存键的前缀,快速更新缓存
var envLastVer = '2014_11_17_17_03';//用于存放通道名称及通信对象的类,这样可以通过不同通道名称来区分不同的通信对象
function HttpRequestObject() {this.chunnel = null;this.instance = null;
}//用于获取的脚本或css文件保存对象
function HttpGetObject() {this.url = null;        //要下载的文件路径this.cache_key = null;  //缓存键this.chunnel = null;    //通道名this.type = null;       //类型,js或cssthis.is_fill = false;   //内容是否被填充this.is_exec = false;   //内容是否已被执行,防止分几大块载入后重复执行
}//通信处理类,可以静态引用其中的方法
var Request = new function () {//通信类的缓存  this.httpRequestCache = new Array();//创建新的通信对象 this.createInstance = function () {var instance = null;if (window.XMLHttpRequest) {//mozilla  instance = new XMLHttpRequest();//有些版本的Mozilla浏览器处理服务器返回的未包含XML mime-type头部信息的内容时会出错。//因此,要确保返回的内容包含text/xml信息  if (instance.overrideMimeType) {instance.overrideMimeType = "text/xml";}}else if (window.ActiveXObject) {//IE  var MSXML = ['MSXML2.XMLHTTP.5.0', 'Microsoft.XMLHTTP', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];for (var i = 0; i < MSXML.length; i++) {try {instance = new ActiveXObject(MSXML[i]);break;}catch (e) {}}}return instance;}/**  * 获取一个通信对象  * 若没指定通道名称,则默认通道名为"default"  * 若缓存中不存在需要的通信类,则创建一个,同时放入通信类缓存中  * @param _chunnel:通道名称,若不存在此参数,则默认为"default"  * @return 一个通信对象,其存放于通信类缓存中  */this.getInstance = function (_chunnel) {var instance = null;var object = null;if (_chunnel == undefined)//没指定通道名称
        {_chunnel = "default";}var getOne = false;for (var i = 0; i < this.httpRequestCache; i++) {object = HttpRequestObject(this.httpRequestCache[i]);if (object.chunnel == _chunnel) {if (object.instance.readyState == 0 || object.instance.readyState == 4) {instance = object.instance;}getOne = true;break;}}if (!getOne) //对象不在缓存中,则创建
        {object = new HttpRequestObject();object.chunnel = _chunnel;object.instance = this.createInstance();this.httpRequestCache.push(object);instance = object.instance;}return instance;}/**  * 客户端向服务端发送请求  * @param _url:请求目的  * @param _data:要发送的数据  * @param _processRequest:用于处理返回结果的函数,其定义可以在别的地方,需要有一个参数,即要处理的通信对象  * @param _chunnel:通道名称,默认为"default"  * @param _asynchronous:是否异步处理,默认为true,即异步处理* @param _paraObj:相关的参数对象 */this.send = function (_url, _data, _processRequest, _chunnel, _asynchronous, _paraObj) {if (_url.length == 0 || _url.indexOf("?") == 0) {alert("由于目的为空,请求失败,请检查!");return;}if (_chunnel == undefined || _chunnel == "") {_chunnel = "default";}if (_asynchronous == undefined) {_asynchronous = true;}var instance = this.getInstance(_chunnel);if (instance == null) {alert("浏览器不支持ajax,请检查!")return;}if (_asynchronous == true && typeof (_processRequest) == "function") {instance.onreadystatechange = function () {if (instance.readyState == 4) // 判断对象状态
                {if (instance.status == 200) // 信息已经成功返回,开始处理信息
                    {_processRequest(instance, _paraObj);}else {alert("您所请求的页面有异常,请检查!");}}}}//_url加一个时刻改变的参数,防止由于被浏览器缓存后同样的请求不向服务器发送请求  if (_url.indexOf("?") != -1) {_url += "&requestTime=" + (new Date()).getTime();}else {_url += "?requestTime=" + (new Date()).getTime();}if (_data.length == 0) {instance.open("GET", _url, _asynchronous);instance.send(null);}else {instance.open("POST", _url, _asynchronous);instance.setRequestHeader("Content-Length", _data.length);instance.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");instance.send(_data);}if (_asynchronous == false && typeof (_processRequest) == "function") {_processRequest(instance, _paraObj);}}
}var Env = new function () {this.needLoadObject = new Array();//获取env.js文件所在路径this.envPath = null;this.getPath = function () {this.envPath = document.location.pathname;this.envPath = this.envPath.substring(0, this.envPath.lastIndexOf("/") + 1);var _scripts = document.getElementsByTagName("script");var _envPath = null;var _scriptSrc = null;for (var i = 0; i < _scripts.length; i++) {_scriptSrc = _scripts[i].getAttribute("src");if (_scriptSrc && _scriptSrc.indexOf("env.js") != -1) {break;}}if (_scriptSrc != null) {if (_scriptSrc.charAt(0) == '/') {this.envPath = _scriptSrc.substr(0, _scriptSrc.length - 6);}else {this.envPath = this.envPath + _scriptSrc.substr(0, _scriptSrc.length - 6);}}}this.getPath();//获取文件后缀名this.getFileExt = function (fileUrl) {var d = /\.[^\.]+$/.exec(fileUrl);return d.toString().toLowerCase();}//依次放入要载入的文件this.pushNeedLoad = function (url) {var _absUrl = null;if (url.charAt(0) == '/')_absUrl = url;else_absUrl = this.envPath + url;var object = new HttpGetObject();object.url = _absUrl;object.cache_key = envLastVer + _absUrl;    //利用版本号+绝对路径生成缓存键object.chunnel = 'ch' + (this.needLoadObject.length + 1);object.type = this.getFileExt(_absUrl);//尝试从缓存获取var cacheContent = localStorage.getItem(object.cache_key);if (cacheContent) { object.is_fill = true; }this.needLoadObject.push(object);return this;}//依次装载要处理的文件this.batchLoad = function () {for (var i = 0; i < this.needLoadObject.length; i++) {var item = this.needLoadObject[i];var processGet = function (_instance, _paraObj) {localStorage.setItem(_paraObj.cache_key, _instance.responseText);    //缓存文件_paraObj.is_fill = true;}if (item.is_fill == false) {Request.send(item.url, "", processGet, item.chunnel, false, item);  //采用同步方式载入
            }}return this;}//依次执行要处理的文件this.batchExec = function () {var runCss = function (_css) { document.write('<style type="text/css">' + _css + '</style>'); }var runJs = function (_js) {if (window.execScript)window.execScript(_js);elsewindow.eval(_js);}//依次执行,由于js为单线程执行,每执行一个js都会阻塞其它,所以可以保证顺序执行for (var i = 0; i < this.needLoadObject.length; i++) {var item = this.needLoadObject[i];if (item.is_exec == false) {if (item.type == '.js') {runJs(localStorage.getItem(item.cache_key));item.is_exec = true;  //标记已执行,下次不会再执行
                }else if (item.type == '.css') {runCss(localStorage.getItem(item.cache_key));item.is_exec = true;  //标记已执行,下次不会再执行
                }}}}
}

下面是调用方法:

Env.pushNeedLoad("jquery.mobile-1.4.5/jquery.min.js").pushNeedLoad("jquery.mobile-1.4.5/jquery.mobile-1.4.5.min.css").pushNeedLoad("/plus_in/weixin/procedure/scripts/task.util.js").pushNeedLoad("/plus_in/weixin/procedure/scripts/emcp.mobile.js").pushNeedLoad("/plus_in/weixin/procedure/scripts/common.index.js").pushNeedLoad("jquery.mobile-1.4.5/jquery.mobile-1.4.5.min.js").pushNeedLoad("mobiscroll.2.6/css/mobiscroll.custom-2.6.2.min.css").pushNeedLoad("mobiscroll.2.6/js/mobiscroll.custom-2.6.2.min.js").pushNeedLoad("/plus_in/weixin/procedure/style/base.css").batchLoad().batchExec();

通过火狐F12观察,发现上面的脚本第一次会被加载,后面将会直接从localstorage中读取,节省了很多,将js用于微信浏览器后,也节省了很多带宽。不过第一次加载还是有些慢的,毕竟还是有那么多数据。

原文地址:http://www.cnblogs.com/wubin264/p/load_js_css_into_localstorage.html

转载于:https://www.cnblogs.com/7qin/p/9702624.html

【半原创】将js和css文件装入localStorage加速程序执行相关推荐

  1. js和css被屏蔽了,是否屏蔽蜘蛛抓取JS和CSS文件

    做网站的人都知道,在查看日志的时候,会发现JS.CSS文件被蜘蛛抓取的频率特别高,于是有人便考虑在robots.txt屏蔽蜘蛛抓取js和css文件,节省蜘蛛时间给其他页面.是否屏蔽蜘蛛抓取JS和CSS ...

  2. Visual Studio 编译任务压缩js和css文件

    如今网站都在说优化,压缩js和css文件就成了最基本的一种方法,js和css压缩有很多方法,很多网站也提供了这样的功能,也可以用YUI提供的包手动压缩,但是这都不效率啊,能不能在vs生成部署包的时候把 ...

  3. 通过minify将项目中js和css文件的打包

    减少http请求数,有三个好处,即减少DNS请求所耗费的时间..减少服务器压力.减少http请求头,因此这是我们前端性能优化的一个关键点. 对于我们前端来说,减少http请求数的一个途径就是合并js和 ...

  4. Django中载入js和css文件

    Django中载入js和css文件 项目的文件夹结构例如以下: mysite |-mysite |-|-static |-|---js和css文件 |-|-|-init.py |-| |-models ...

  5. JavaScript使用localStorage缓存Js和css文件

    对于WebApp来说,将js css文件缓存到localstorage区可以减少页面在加载时与HTTP请求的交互次数,从而优化页面的加载时间.特别是当移端信号不好高延迟时优化效果还是很显见的 下面的代 ...

  6. js或css文件后面的参数是什么意思?

    经常看到不少导航网站测样式或js文件后面加了一些参数,主要是一你为一些并不经常更新的页面重新加载新修改的文件. 经常遇到页面里加载的js与css文件带有参数,比如: <script type=& ...

  7. wordpress home.php,WordPress主题通过function.php来加载js和css文件

    WordPress主题开发的时候可以直接将需要的js或css写在head标签中,但是现在已经不主张这种加载方式了,现在WordPress主题通过function.php来加载js和css文件. 基本架 ...

  8. Asp.net中Js、Css文件压缩辅助类

    类名:WebCompressUtility.cs 代码如下: /// <summary> /// Js.Css文件压缩辅助类 /// Stone_W /// 2011.6.21 /// & ...

  9. php gizp压缩传输js和css文件 - PHP

    实例: <?php/*** 完整调用示例:* 1.combine.php?t=j&b=public&fs=jslib.jquery,function* * 该例子调用的是< ...

最新文章

  1. ATS cache中的几个数据结构图收集
  2. MySQL主从库--同步异常
  3. Linux学习——shell编程之变量
  4. logback输出日志到sentry
  5. JUC重要辅助类(同步组件及锁)
  6. 华为上机:求2的N次幂的值
  7. Angularjs controller之间的通信
  8. WordPress后台添加侧边栏菜单
  9. js地址栏获取参数的方法,解决中文乱码问题,能支持中文参数
  10. 关于win10用户使用protel99se可能出现的问题以及解决方法
  11. Spring 常用的注解
  12. 4.20 使用条件格式标识包含指定文本的单元格 [原创Excel教程]
  13. cad字体安装_CAD字体如何划分?资源去哪下载?上千种字体资源,免费分享赠送...
  14. matlab去除图片水印_一种基于MATLAB去图片水印方法
  15. 如何学习一门新技术(经验分享)
  16. OI游记——一个不配称为OIer的失败选手的自白
  17. 计算机毕业设计Java电影售票系统(源码+系统+mysql数据库+lw文档)
  18. python vue+flask 跨域请求
  19. 202五一杯数学建模ABC三题
  20. 联邦学习论文阅读:Variational Federated Multi-Task Learning

热门文章

  1. CheckBox的Attributes
  2. sketch设置字体技巧(二)---通过组合法重新组建字体
  3. 使用jquery-qrcode生成二维码
  4. jQuery Tips(5)----关于伪类选择符
  5. 在想的事情......
  6. 浏览器输入一个url会发生什么
  7. xcode高版本常见的RN本地启动报错
  8. Linux---基础指令
  9. 夜班工作有哪些优缺点?
  10. 如何拍好运动风人像?