在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 Select(单选) 模拟插件 V1.3.62 改进版
Jul 17 Javascript
Jquery中&quot;$(document).ready(function(){ })&quot;函数的使用详解
Dec 30 Javascript
jquery 中的each()跳出循环的语句
May 23 Javascript
js实现编辑div节点名称的方法
Dec 17 Javascript
基于jQuery的JavaScript模版引擎JsRender使用指南
Dec 29 Javascript
JavaScript通过this变量快速找出用户选中radio按钮的方法
Mar 23 Javascript
a标签置灰不可点击的实现方法
Feb 06 Javascript
基于JavaScript实现复选框的全选和取消全选
Feb 09 Javascript
webpack+react+antd脚手架优化的方法
Apr 02 Javascript
微信小程序下拉框组件使用方法详解
Dec 28 Javascript
面试题:react和vue的区别分析
Apr 08 Javascript
ES6 Iterator接口和for...of循环用法分析
Jul 31 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
一个程序下载的管理程序(四)
2006/10/09 PHP
PHP编程之高级技巧——利用Mysql函数
2006/10/09 PHP
php xml常用函数的集合(比较详细)
2013/06/06 PHP
使用PHP编写的SVN类
2013/07/18 PHP
php 检查电子邮件函数(自写)
2014/01/16 PHP
php源码的使用方法讲解
2019/09/26 PHP
跨浏览器的 mouseenter mouseleave 以及 compareDocumentPosition的使用说明
2010/05/04 Javascript
JS 树形递归实例代码
2010/05/18 Javascript
Jquery下判断Id是否存在的代码
2011/01/06 Javascript
jQuery 重复加载错误以及修复方法
2014/12/16 Javascript
在Ubuntu系统上安装Ghost博客平台的教程
2015/06/17 Javascript
如何用JS判断两个数字的大小
2016/07/21 Javascript
浅谈js的html元素的父节点,子节点
2016/08/06 Javascript
如何学JavaScript?前辈的经验之谈
2016/12/28 Javascript
利用javascript实现的三种图片放大镜效果实例(附源码)
2017/01/23 Javascript
Vue.js实战之Vuex的入门教程
2017/04/01 Javascript
vue2 mint-ui loadmore实现下拉刷新,上拉更多功能
2018/03/21 Javascript
VUE 全局变量的几种实现方式
2018/08/22 Javascript
Django+Vue实现WebSocket连接的示例代码
2019/05/28 Javascript
浅谈小程序globalData的那些事儿
2019/11/01 Javascript
vue 返回上一页,页面样式错乱的解决
2019/11/14 Javascript
[01:06:12]VP vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python聊天程序实例代码分享
2013/11/18 Python
利用python微信库itchat实现微信自动回复功能
2017/05/18 Python
python实现京东秒杀功能
2018/07/30 Python
浅谈Python脚本开头及导包注释自动添加方法
2018/10/27 Python
Python函数装饰器常见使用方法实例详解
2019/03/30 Python
Python中字符串String的基本内置函数与过滤字符模块函数的基本用法
2019/05/27 Python
pytorch中的自定义反向传播,求导实例
2020/01/06 Python
python tkinter实现下载进度条及抖音视频去水印原理
2021/02/07 Python
澳大利亚百货公司:David Jones
2018/02/08 全球购物
大学毕业寄语大全
2014/04/10 职场文书
企业文化标语大全
2014/06/10 职场文书
三人合伙协议书范本
2014/10/29 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
CSS实现背景图片全屏铺满自适应的3种方式
2022/07/07 HTML / CSS