使用lazyload 异步加载css js 文件. 提升页面初始化的速度,减少卡顿时间 ,
下面是 使用方法 与 lazyload.js 源码 (中文注释)
调用方法后. 会追加到 head 标签末尾
会按照 数组中的地址顺序 进行加载文件
加载成功后有 console.log().进行日志打印
不需要的话,可以删除. 有兴趣的可以看看注释, 研究一下LazyLoad.js 的 实现方式.

完整例子

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>test</title>
<meta name="Keywords" content="">
<meta name="Description" content="">
<!--先 引入lazyload 再调用方法-->
<script src="/js/JsTool/CssJsFileLazyLoad/lazyload.js"></script>
<script async="async">
var cssFile = [
'/css/backstage/1.css',
'/css/backstage/2.css',
'/css/backstage/3.css',
'/css/backstage/4.css',
'/css/backstage/5.css',
'/css/backstage/6.css'
];
//调用方法后. 会追加到 head 标签末尾
//会按照 数组中的顺序 进行加载文件
LazyLoad.css(cssFile, function () {
console.log("css加载完成...");
}); </script>
</head>
<body class="bg_0">
<div>内容</div> <script async="async">
var jsFile = [
'/js/backstage/jquery/1.js',
'/js/backstage/jquery/2.js',
'/js/backstage/jquery/3.js',
'/js/backstage/jquery/4.js',
'/js/backstage/jquery/5.js',
'/js/backstage/jquery/6.js'
];
//调用方法后. 会追加到 head 标签末尾
LazyLoad.js(jsFile, function () {
console.log("js加载完成...");
});
</script>
</body>
</html>

新建文件 LazyLoad.js 内容如下

/**
* 异步加载css 与 js 文件
* xue
*
*/
LazyLoad = (function (doc) {
/**
* 如何使用:
*
* CSS:
*
var cssFile = [
'/css/backstage/1.css',
'/css/backstage/2.css',
'/css/backstage/3.css',
'/css/backstage/4.css',
'/css/backstage/5.css',
'/css/backstage/6.css'
];
//可以使用数组的形式,加载多个css文件. 也可以传入一个字符串,加载一个css
LazyLoad.css(cssFile, function () {
console.log("css加载完成...");
}); *
*JS:
var jsFile = [
'/js/backstage/jquery/1.js',
'/js/backstage/jquery/2.js',
'/js/backstage/jquery/3.js',
'/js/backstage/jquery/4.js',
'/js/backstage/jquery/5.js',
'/js/backstage/jquery/6.js'
];
//可以使用数组的形式,加载多个js文件. 也可以传入一个字符串,加载一个js
LazyLoad.js(jsFile, function () {
console.log("js加载完成...");
}); */ // Private Property -------------------------------------------------------- var env,
head,
pending = {},
pollCount = 0,
queue = { css: [], js: [] },
styleSheets = doc.styleSheets,
startTime,
endTime; // Private Methods -------------------------------------------------------- /**
创建并返回具有指定名称和属性的HTML元素。 @method createNode
@param {String} name 元素名
@param {Object} attrs 元素属性的 名称/值 映射
@return {HTMLElement}
@private
*/
function createNode(name, attrs) {
var node = doc.createElement(name), attr; for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
} return node;
} /**
当指定类型的当前挂起资源完成时调用装载。执行关联的回调(如果有)并加载下一个回调队列中的资源。 @method finish
@param {String} type 资源类型 ('css' or 'js')
@private
*/
function finish(type) {
var p = pending[type], callback, urls; if (p) {
callback = p.callback;
urls = p.urls; urls.shift();
pollCount = 0; // 如果这是最后一个挂起的url,则执行回调和
// 启动队列中的下一个请求(如果有)。
if (!urls.length) {
callback && callback.call(p.context, p.obj);
pending[type] = null;
queue[type].length && load(type);
}
}
} /**
填充 <code>env</code> 变量带有用户代理和特性测试信息。 @method getEnv
@private
*/
function getEnv() {
var ua = navigator.userAgent; env = {
//如果此浏览器支持动态禁用异步模式,则为True
//创建脚本节点
async: doc.createElement('script').async === true
}; (env.webkit = /AppleWebKit\//.test(ua))
|| (env.ie = /MSIE|Trident/.test(ua))
|| (env.opera = /Opera/.test(ua))
|| (env.gecko = /Gecko\//.test(ua))
|| (env.unknown = true);
} /**
加载指定的资源或指定类型的下一个资源
如果没有指定资源,则在队列中。如果指定的资源
类型已加载,新请求将排队,直到
第一个请求已经完成。 当指定资源url数组时,将加载这些url
如果可能的话,在保持执行顺序的同时并行执行。所有
浏览器支持CSS的并行加载,但只支持Firefox和Opera
支持脚本的并行加载。在其他浏览器中,脚本将是
排队并一次加载一个,以确保正确的执行顺序。 @method load
@param {String} type 资源类型 ('css' or 'js')
@param {String|Array} urls (optional) 要加载的URL或URL数组
@param {Function} callback (optional) 回调函数
@param {Object} obj (optional) 对象传递给回调函数
@param {Object} context (optional) 如果提供,则回调函数将在这个对象的上下文中执行
@private
*/
function load(type, urls, callback, obj, context) {
//开始计时
startTime = new Date().getTime(); var _finish = function () { finish(type); },
isCSS = type === 'css',
nodes = [],
i, len, node, p, pendingUrls, url; env || getEnv(); if (urls) {
//如果url是字符串,则将其包装在数组中。否则假设它是
//数组并创建它的副本,这样就不会对其进行修改
urls = typeof urls === 'string' ? [urls] : urls.concat(); // 为每个URL创建一个请求对象。如果指定了多个url,
// 回调只会在加载所有url之后执行。
//
//遗憾的是,Firefox和Opera是唯一能够加载的浏览器
//脚本并行,同时保持执行顺序。在所有其他
//浏览器,脚本必须顺序加载。
//
//所有浏览器都根据链接的顺序尊重CSS的特性
// DOM中的元素,而不考虑样式表的顺序
//实际上是下载的。
if (isCSS || env.async || env.gecko || env.opera) {
// 并行加载
queue[type].push({
urls: urls,
callback: callback,
obj: obj,
context: context
});
} else {
// 加载顺序。
for (i = 0, len = urls.length; i < len; ++i) {
queue[type].push({
urls: [urls[i]],
callback: i === len - 1 ? callback : null, // 回调只添加到最后一个URL
obj: obj,
context: context
});
}
}
} //如果之前的这种类型的加载请求正在进行中,那么我们将
//轮到我们了。否则,获取队列中的下一项。
if (pending[type] || !(p = pending[type] = queue[type].shift())) {
return;
}
//获取head标签
head || (head = doc.head || doc.getElementsByTagName('head')[0]);
pendingUrls = p.urls.concat(); for (i = 0, len = pendingUrls.length; i < len; ++i) {
url = pendingUrls[i];
//开始拼接 标签
if (isCSS) {
node = env.gecko ? createNode('style') : createNode('link', {
href: url,
rel: 'stylesheet'
});
} else {
node = createNode('script', { src: url });
node.async = false;
} node.className = 'lazyload';
node.setAttribute('charset', 'utf-8'); if (env.ie && !isCSS && 'onreadystatechange' in node && !('draggable' in node)) {
node.onreadystatechange = function () {
if (/loaded|complete/.test(node.readyState)) {
node.onreadystatechange = null;
_finish();
}
};
} else if (isCSS && (env.gecko || env.webkit)) {
// Gecko和WebKit不支持链接节点上的onload事件。
if (env.webkit) {
//在WebKit中,我们可以轮询对文档的更改。样式表
//确定样式表何时加载。
p.urls[i] = node.href; //解析相对url(或轮询不起作用)
pollWebKit();
} else {
//在Gecko中,我们可以将请求的URL导入到<style>节点中
//轮询node.sheet.cssRules是否存在。
node.innerHTML = '@import "' + url + '";';
pollGecko(node);
}
} else {
node.onload = node.onerror = _finish;
} nodes.push(node);
} for (i = 0, len = nodes.length; i < len; ++i) {
head.appendChild(nodes[i]);
//控制台日志部分(不需要可以删除)
//start
var url = pendingUrls[i];
if (/.js/.exec(url)) {
console.log((i + 1) + "--> js成功: " + url);
} else if (/.css/.exec(url)) {
console.log((i + 1) + "--> css成功: " + url);
} else {
console.log("error: " + url);
}
//end
} //结束计时
endTime = new Date().getTime();
//控制台日志部分(不需要可以删除)
//(startTime (在此方法开头),endTime(在此行代码上方) 都可以删除 )
console.log("执行时间: " + (endTime - startTime) + " ms ------- end时间戳:" + endTime);
} /**
开始轮询,以确定指定的样式表何时完成加载
轮询在加载所有挂起的样式表或加载10个样式表之后停止
秒(防止停顿)。 @method pollGecko
@param {HTMLElement} node 样式节点。
@private
*/
function pollGecko(node) {
var hasRules; try {
//我们不需要存储这个值,也不需要再次引用它,但是
//如果我们不存储它,闭包编译器会认为代码是无用的
//删除它。
hasRules = !!node.sheet.cssRules;
} catch (ex) {
// 异常意味着样式表仍在加载。
pollCount += 1; if (pollCount < 200) {
setTimeout(function () { pollGecko(node); }, 50);
} else {
//我们已经轮询了10秒钟,什么都没有发生。
//停止轮询并完成挂起的请求,以避免进一步阻塞请求。
hasRules && finish('css');
} return;
} // 到这里,样式表已经加载。
finish('css');
} /**
开始轮询,以确定挂起的样式表何时完成加载
在WebKit。轮询在加载所有挂起的样式表或加载10个样式表之后停止
秒(防止停顿)。 @method pollWebKit
@private
*/
function pollWebKit() {
var css = pending.css, i; if (css) {
i = styleSheets.length; // 查找与挂起的URL匹配的样式表。
while (--i >= 0) {
if (styleSheets[i].href === css.urls[0]) {
finish('css');
break;
}
} pollCount += 1; if (css) {
if (pollCount < 200) {
setTimeout(pollWebKit, 50);
} else {
//我们已经轮询了10秒钟,什么都没有发生
//表示样式表已从文档中删除
//在它有机会装载之前。停止轮询并完成挂起
//请求以防止阻止进一步的请求。
finish('css');
}
}
}
} // Public Methods --------------------------------------------------------
return {
/**
请求指定的CSS URL或URL并执行指定的
当它们完成加载时回调(如果有的话)。如果一个url数组是
指定后,样式表将与回调并行加载
将在所有样式表加载完成后执行。 @method css
@param {String|Array} urls CSS URL或要加载的CSS URL数组
@param {Function} callback (optional) 回调函数
@param {Object} obj (optional) 对象传递给回调函数
@param {Object} context (optional) 如果提供,回调函数将在这个对象的上下文中执行吗
@static
*/
css: function (urls, callback, obj, context) {
load('css', urls, callback, obj, context);
}, /**
请求指定的JavaScript URL并执行指定的
当它们完成加载时回调(如果有的话)。如果一个url数组是
指定并得到浏览器的支持后,脚本将被加载进来
并将在所有脚本完成后执行回调
完成加载。 目前,只有Firefox和Opera支持同时并行加载脚本
保存执行顺序。在其他浏览器中,脚本将是
排队并一次加载一个,以确保正确的执行顺序 @method js
@param {String|Array} urls JS URL或要加载的JS URL数组
@param {Function} callback (optional) 回调函数
@param {Object} obj (optional) 对象传递给回调函数
@param {Object} context (optional) 如果提供,回调函数将在这个对象的上下文中执行吗
@static
*/
js: function (urls, callback, obj, context) {
load('js', urls, callback, obj, context);
}
};
})(this.document);

js文件 与 css文件 异步加载的更多相关文章

  1. 网页性能优化之异步加载js文件

    一个网页的有很多地方可以进行性能优化,比较常见的一种方式就是异步加载js脚本文件.在谈异步加载之前,先来看看浏览器加载js文件的原理. 浏览器加载 JavaScript 脚本,主要通过<scri ...

  2. Javascript 文件的同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面b ...

  3. JS异步加载的三种方案

    js加载的缺点:加载工具方法没必要阻塞文档,个别js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载. 一.def ...

  4. javascript 同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值. defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面 ...

  5. angularJS1笔记-(19)-angular异步加载包的方式

    我们平时写的导入包的方式都是同步方式,有时候会显得过于卡顿,这样我们就可以使用异步加载的方式. script.js方式: 执行结果为: 异步加载还可以加载多个即为script([,,,],functi ...

  6. 如何调试异步加载的js文件(浏览器调试动态加载js)

    描述 1:jQuery->var obj= new $.js_Obj():等异步加载js文件,执行方法. obj.method(): 2:页面估计不变,通过声明不同的js文件,进行页面内容的转换 ...

  7. 使用getScript()方法异步加载并执行js文件

    使用getScript()方法异步加载并执行js文件 使用getScript()方法异步请求并执行服务器中的JavaScript格式的文件,它的调用格式如下所示: jQuery.getScript(u ...

  8. 如何使用 require.js ,实现js文件的异步加载,避免网页失去响应,管理模块之间的依赖性,便于代码的编写和维护。

    一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...

  9. angularLoad(用以异步加载js文件)

    angularLoad(用以异步加载js文件) 使用方法: 1.执行命令 下载 lib npm install angular-load --save 2.index.html引用js <scr ...

随机推荐

  1. ASP.NET EF实体主外键关系

    其他解释 https://www.cnblogs.com/wuhenke/archive/2010/08/11/1797307.html 主键.外键 需要删除完外键表才能删除主键表 一对一关系peop ...

  2. ChipGenius 识别U盘主控信息

    ChipGenius 识别U盘主控信息 ================== End

  3. iOS - 适配iOS 11

    http://www.10tiao.com/html/330/201707/2653579210/1.html 存档 导语:iOS 11 为整个生态系统的 UI 元素带来了一种更加大胆.动态的新风格. ...

  4. 【转载】C#中string类使用Substring方法截取字符串

    在C#的字符串操作过程中,截取字符串是一种常见的字符串操作,可使用string类的Substring方法来完成字符串的截取操作,该方法支持设定截取的开始位置以及截取的字符串长度等参数,Substrin ...

  5. 【转载】C#使用Math.Sqrt方法进行开平方操作

    在C#的数学数值运算中,有时候需要进行对数值进行开平方操作,C#的数值计算类Math类中内置了开平方操作的方法Sqrt,直接调用此方法可计算出相应的平方值,Math.Sqrt方法签名为:double ...

  6. C++线程同步之事件(生产者与消费者问题)

    #include <windows.h> #include <stdio.h> HANDLE g_hSet = NULL; HANDLE g_hClear = NULL; HA ...

  7. Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))

    off by one(栈)? 将源字符串复制到目标缓冲区可能会导致off by one 1.源字符串长度等于目标缓冲区长度. 当源字符串长度等于目标缓冲区长度时,单个NULL字节将被复制到目标缓冲区上 ...

  8. C#入门概述

    ASP.NET 则是一种技术. Main方法 代码编写规范 命名规范

  9. HTML&CSS基础-伪元素选择器

    HTML&CSS基础-伪元素选择器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.html源代码 <!DOCTYPE html> <html> ...

  10. 科普文:Node.js 如何上传文件到后端服务【转】

    原文链接 https://www.yuque.com/egg/nodejs/httpclient-upload 背景 互联网时代,无数服务是基于 HTTP 协议进行通信的. 除了常见的 前端浏览器 - ...