Javascript模块化编程,本站使用 require.js 优化JS加载, require.js下载
require.js 是非常优秀、流行的异步并且有顺序(依赖)加载的一个组件。对于站点使用很多 Javascript 的站长来说,无疑是福音。
首先这个站是个工具类型站点,每个页面加载的 Javascript 非常多,虽然本站用了 CDN 加速,但是每次打开页面都需要做同步的加载N多JS,导致速度减慢,影响用户体验,其实还影响 SEO ,因为爬虫来爬取内容的时候,很多超时的现象。
前段时间和群里的一个 SEO 大牛交流,一针见血的指出了这个问题,我下决心要改,但是由于各种设计,再加上防止别人拔站,所以JS里做了很多验证,导致难度系数大大提升。
选型 require.js ,保证JS
异步加载,并且模块化使用,这对于本站是JS
几乎是重构。但是坚持下去就能完美解决。那么下面来说下 require.js 吧。
一、我为什么要用require.js
这只是一部分,这么多?页面一加载全部得加载,要不然页面就一直等着响应。而且不同的页面需要引入的JS
,有相同的,有不同的,从管理上来说,乱的很。
二、require.js 加载。
<script src="js/require.js" data-main="js/main" defer="true" async="true"></script>
data-main="js/main":是加载完毕 require.js 后,调用的js
为js/main.js
,认定js/main.js
为主模块,因为require.js
默认结尾就是js
,所以main
不用写.js
的后缀。
async:异步加载
defer:是 IE 浏览器不支持async
,但是支持defer
。
三、主模块main.js代码。
console.log("init main");
当 require.js 加载完毕后,会在控制台输出“init main”
,这表示加载是成功的 。但是我们想要的不只是那么一点,我们要的很多,要依次加载N
多js
。
那我们来看下我们需要的。首先要输出一个模块定义,其实就是需要加载的js
用别名表示一下,定义一下。
使用require.config()
方法,我们可以对模块的加载行为进行自定义。require.config()
就写在主模块(main.js
)的最上面。参数就是一个对象,这个对象的paths
属性指定各个模块的加载路径。
require.config({
paths: {
"a": "a",
"b": "b"
}
});
paths:是配置js文件和别名指定,如 "a":"a"
表示配置了一个a.js
,并且别名指定为a
。同理b
也是。
key
表示别名,value
表示js
文件,可以不用写“.js”
,默认结尾就是“.js”
,如果有路径带上路径。如:
require.config({
paths: {
"a": "/js/common/a",
"b": "/js/common/b"
}
});
如果路径一致:也就是a.js
和b.js
是在相同文件下,那么可以这样写:
require.config({
baseUrl: "js/common",
paths: {
"a": "a",
"b": "b"
}
});
都是一个意思。就是减少了代码量。
如果是远程地址,直接写上远程地址即可:
require.config({
paths: {
"a": "http://open.sojson.com/common/js/a",
"b": "b"
}
});
配置已经定义好映射关系了,这时就要使用AMD规范定义的的require()
函数加载 Javascript 文件了。
require(['a', 'b'], function (a, b){
console.log(a,b )
});
这个时候我是先记载a.js
,然后再加载b.js
,然后输出。
require()
函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是['a', 'b']
,即主模块依赖这二个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。
require()
异步加载a,b,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。
下面来一个真实的栗子:
require.config({
baseUrl: "js/common",
paths: {
"jquery": "jquery/jquery1.8.3.min",
"cookie": "jquery.cookies.min"
}
});
require(['jquery', 'cookie'], function ($, c){
//do something
});
这个定义了一个baseUrl
,而 jquery 还是写了路径,表示在这个baseUrl
下,再衍生路径,而jquery.cookie
没有前面加路径,因为他就在js/common
下。
那么jquery.cookie
依赖 jquery ,所以 jquery 要放到前面,依次加载成功后,调用回调方法,返回2个参数,第一个是 jquery ,第二个是jquery.cookie
。
四、AMD模块写法。
require.js 加载的模块,采用AMD
规范。也就是说,模块必须按照AMD
的规定来写。
具体来说,就是模块必须采用特定的define()
函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。
假定现在有一个math.js
文件,它定义了一个math模块。那么,math.js
就要这样写:
define(function (){
var add = function (x,y){
return x+y;
};
return {
add: add
};
});
记载调用的方法如下:
require(['math'], function (math){
console.log(math.add(1,1));
});
这个时候,控制台会输出“2”。如果有多个,在第一个参数里写多个就可以了,第一个参数刚刚上面说了是个数组,支持多个。
五、加载非规范的模块
理论上, require.js 加载的模块,必须是按照AMD规范、用define()
函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如 jQuery )符合AMD规范,更多的库并不符合。那么, require.js 是否能够加载非规范的模块呢?那必须是可以的。
这样的模块在用require()
加载之前,要先用require.config()
方法,定义它们的一些特征。
require.config()
接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim
属性,专门用来配置不兼容的模块。具
体来说,每个模块要定义
(1)exports值(输出的变量名),表明这个模块外部调用时的名称;
(2)deps数组,表明该模块的依赖性。
require.config({
shim: {
'jquery.scroll': {
deps: ['jquery'],
exports: 'jQuery.fn.scroll'
},
'jquery.cookie': {
deps: ['jquery'],
exports: 'jquery.cookie'
}
//多个往后面添加。
}
});
require.js 提供了很多插件,具体请看这里:https://github.com/requirejs/requirejs/wiki/Plugins
require.js
下载请看附件;
版权所属:SO JSON在线解析
原文地址:https://www.sojson.com/blog/175.html
转载时必须以链接形式注明原始出处及本声明。
如果本文对你有帮助,那么请你赞助我,让我更有激情的写下去,帮助更多的人。