在JavaScript应用中使用RequireJS来实现延迟加载


Posted in Javascript onJuly 01, 2015

无论简单还是复杂的Web应用,都由一些HTML、JavaScript、CSS文件组成。通常开发者会通过JQuery、Knockout、Underscore等等这样的第三方JavaScript框架来提高开发速度。由于这些JavaScript框架都针对特定的用途开发而且已经得到了“验证”,所以直接使用它们就比自己从头实现所需要的功能显得更为合适。然而,伴随着应用的复杂度不断上升,写出干净、低耦合、可维护的代码变得越来越重要。在这篇文章里,我将解释 RequireJS框架如何帮助应用开发者写出更加模块化的代码,以及它是如何通过延迟加载JavaScript文件来提高应用性能的。

开始的部分我们先不用RequireJS框架,然后在下一个章节用RequireJS来重构它。

下面的这个HTML页面包含了一个id为“message”的<p>元素。当用户访问这个页面的时候,它将展示订单Id和客户姓名信息。

Common.JS文件包含了两个模块的定义——Order和Customer。函数showData和页面的body结合在一起,它通过调用write函数来把要输出的信息放入页面中。作为示例,我在showData函数里硬编码了Id为1,客户姓名为Prasad。
 

<!DOCTYPE html>
<html>
<head>
<title>JavaScript NonRequireJS</title>
<script src="common.js" type="text/javascript"></script>
</head>
<body>
<strong>Display data without RequireJS</strong>
<p id="message" />
<script type="text/javascript">
showData();
</script>
</body>
</html>
Common.JS
 
function write(message) {
  document.getElementById('message').innerHTML += message + '</br>';
}
 
function showData() {
  var o = new Order(1, "Prasad");
  write("Order Id : " + o.id + " Customer Name : " + o.customer.name);
}
 
function Customer(name) {
  this.name = name;
  return this;
}
 
function Order(id, customerName) {
  this.id = id;
  this.customer = new Customer(customerName);
  return this;
}

在浏览器中打开这个页面,你将看到如下的信息。

在JavaScript应用中使用RequireJS来实现延迟加载

虽然上面的代码能够显示输出,但是它仍有一些问题:

  •     Common.JS文件包含了所有需要定义的函数(write,showData),而且模块(Order,Customer)很难维护和复用。假如你想在其它页面里复用write函数并引用了上面的JavaScript文件,那么你也导入了这个页面可能不需要的其它函数和模块。
  •     Order模块(或者在面向对象中叫做“类”)在初始化过程中创建了一个Customer模块的实例。这意味着Order模块依赖于Customer模块。这些模块间的紧耦合使得将来在优化时很难重构与维护。
  •     每当客户端请求这个页面时,Common.JS文件就会被载入DOM。在上面这个例子中,尽管我们只需要在页面上输出信息,但我们仍把那些不需要的模块(Customer,Order)载入了内存。载入不必要的应用资源(JavaScript、CSS、图片文件等等)会降低应用的性能。
  •     Common.JS文件里的模块可以被分离到不同的JavaScript文件里,但是当应用变得越来越复杂时,很难判断JavaScript文件之间的依赖关系与需要被加载的文件的加载顺序。

RequireJS框架处理了JavaScript文件间的依赖关系,并且根据需要按顺序加载它们。

用RequireJS搭建应用

现在让我们看看重构过的代码。下面的HTML代码引用了Require.JS文件。data-main属性定义了这个页面的唯一入口点。在下面这个场景中,它告诉了RequireJS在启动的时候加载Main.js。
 

<!DOCTYPE html>
<html>
<head>
<title>JavaScript RequireJS</title>
<script src="Require.Js" type="text/javascript" data-main="Main.js"></script>
</head>
<body>
<strong>Display data using RequireJS</strong>
<p id="message" />
</body>
</html>

Main.JS

由于这个文件已经通过data-main属性指定,RequireJS将会尽快的加载它。这个文件使用了RequireJS框架的函数来确定和定义对于其它JavaScript文件的依赖关系。在下面的代码片段里,第一个参数表示依赖关系(依赖Order.JS文件),第二个参数为一个回调函数。RequireJS分析所有的依赖关系并载入它们,然后执行这个回调函数。请注意,第一个参数的值(Order)必须和文件名一致(Order.JS)。
 

require(["Order"], function (Order) {
  var o = new Order(1, "Prasad");
  write(o.id + o.customer.name);
});

Order.JS

RequireJS框架提供了一个定义和维护JavaScript文件间依赖关系的简便途径。下面代码中的define函数声明了Customer.JS必须在处理Order回调函数前载入。
 

define(["Customer"],
function (Customer) {
function Order(id, custName) {
this.id = id;
this.customer = new Customer(custName);
}
return Order;
}
);
Customer.JS

这个文件不依赖于任何其它JavaScript文件,所以define函数的第一个参数的值是一个空数组。
 

define([],
function () {
function Customer(name) {
this.name = name;
}
return Customer;
}
);

好了,现在用你的浏览器打开这个应用,你将会看到如下的输出。要注意的是RequireJS只载入了必需的JavaScript文件。

在JavaScript应用中使用RequireJS来实现延迟加载

 总结

在这篇文章里,我们分析了RequireJS框架是如何处理JavaScript文件间的依赖关系并根据需要载入它们的。它能够帮助开发者写出更松耦合、更模块化且更具有可维护性的代码。

Javascript 相关文章推荐
jQuery fadeTo方法调整图片的透明度使用介绍
May 06 Javascript
jQuery实现Flash效果上下翻动的中英文导航菜单代码
Sep 22 Javascript
window.onload绑定多个事件的两种解决方案
May 15 Javascript
JS模拟的Map类实现方法
Jun 17 Javascript
大型JavaScript应用程序架构设计模式
Jun 29 Javascript
Javascript类型系统之undefined和null浅析
Jul 13 Javascript
jQuery实现可拖拽的许愿墙效果【附demo源码下载】
Sep 14 Javascript
解决AjaxFileupload 上传时会出现连接重置的问题
Jul 07 Javascript
详解VueJS 数据驱动和依赖追踪分析
Jul 26 Javascript
最简单的vue消息提示全局组件的方法
Jun 16 Javascript
JavaScript实现模态对话框实例
Jan 13 Javascript
js实现点赞按钮功能的实例代码
Mar 06 Javascript
使用RequireJS优化JavaScript引用代码的方法
Jul 01 #Javascript
优化RequireJS项目的相关技巧总结
Jul 01 #Javascript
JavaScript的RequireJS库入门指南
Jul 01 #Javascript
Backbone.js的一些使用技巧
Jul 01 #Javascript
JavaScript框架是什么?怎样才能叫做框架?
Jul 01 #Javascript
javascript常用的方法分享
Jul 01 #Javascript
JavaScript数组去重的3种方法和代码实例
Jul 01 #Javascript
You might like
php常用正则函数实例小结
2016/12/29 PHP
JXTree对象,读取外部xml文件数据,生成树的函数
2007/04/02 Javascript
用js 让图片在 div或dl里 居中,底部对齐
2008/01/21 Javascript
js 代码集(学习js的朋友可以看下)
2009/07/22 Javascript
jQuery 1.5.1 发布,全面支持IE9 修复大量bug
2011/02/26 Javascript
jQuery获取节点和子节点文本的方法
2014/07/22 Javascript
js实现非常简单的焦点图切换特效实例
2015/05/07 Javascript
使用three.js 画渐变的直线
2016/06/05 Javascript
JavaScript中const、var和let区别浅析
2016/10/11 Javascript
sea.js常用的api简易文档
2016/11/15 Javascript
深入理解jQuery.data() 的实现方式
2016/11/30 Javascript
Vue 进阶教程之v-model详解
2017/05/06 Javascript
详解如何快速配置webpack多入口脚手架
2018/12/28 Javascript
vue cli安装使用less的教程详解
2019/07/12 Javascript
使用Phantomjs和Node完成网页的截屏快照的方法
2019/07/16 Javascript
JavaScript中使用Spread运算符的八种方法总结
2020/06/18 Javascript
vue element实现表格合并行数据
2020/11/30 Vue.js
解读Python中degrees()方法的使用
2015/05/18 Python
Python回调函数用法实例详解
2015/07/02 Python
Python切片知识解析
2016/03/06 Python
python中如何使用正则表达式的非贪婪模式示例
2017/10/09 Python
Python机器学习算法之k均值聚类(k-means)
2018/02/23 Python
python3使用腾讯企业邮箱发送邮件的实例
2019/06/28 Python
Pytorch抽取网络层的Feature Map(Vgg)实例
2019/08/20 Python
Python一行代码解决矩阵旋转的问题
2019/11/30 Python
python 多维高斯分布数据生成方式
2019/12/09 Python
html5.2 dialog简介详解
2018/02/27 HTML / CSS
中国宠物用品商城:E宠商城
2016/08/27 全球购物
美国女士泳装店:Swimsuits For All
2017/03/02 全球购物
光荣入党自我鉴定
2014/01/22 职场文书
餐饮企业总经理岗位职责范文
2014/02/18 职场文书
2015年公司保安年终工作总结
2015/05/14 职场文书
如何写新闻稿
2015/07/18 职场文书
遇事可以测出您的见识与格局
2019/09/16 职场文书
JS数组去重详情
2021/11/07 Javascript
「魔导具师妲莉亚永不妥协~从今天开始的自由职人生活~」1、2卷发售宣传CM公开
2022/03/21 日漫