在JavaScript应用中实现延迟加载的方法


Posted in Javascript onJune 25, 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应用中实现延迟加载的方法

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

  •     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框架是如何处理JavaScript文件间的依赖关系并根据需要载入它们的。它能够帮助开发者写出更松耦合、更模块化且更具有可维护性的代码。

谢谢

下载源代码: Lazy Loading using RequireJS (Prasad Honrao, Codetails)

Javascript 相关文章推荐
IE中jscript/javascript的条件编译
Sep 07 Javascript
jquery如何通过name名称获取当前name的value值
Dec 20 Javascript
jQuery动画特效实例教程
Aug 29 Javascript
Javascript中arguments对象详解
Oct 22 Javascript
28个常用JavaScript方法集锦
Jan 14 Javascript
JS判断输入字符串长度实例代码(汉字算两个字符,字母数字算一个)
Aug 02 Javascript
URL的参数中有加号传值变为空格的问题(URL特殊字符)
Nov 04 Javascript
Ajax基础知识详解
Feb 17 Javascript
jQuery Ajax向服务端传递数组参数值的实例代码
Sep 03 jQuery
使用js获取伪元素的content实例
Oct 24 Javascript
微信小程序中换行空格(多个空格)写法详解
Jul 10 Javascript
layui富文本编辑器前端无法取值的解决方法
Sep 18 Javascript
Underscore.js 1.3.3 中文注释翻译说明
Jun 25 #Javascript
深入分析JSON编码格式提交表单数据
Jun 25 #Javascript
jquery移动点击的项目到列表最顶端的方法
Jun 24 #Javascript
jquery使整个div区域可以点击的方法
Jun 24 #Javascript
jQuery寻找n以内完全数的方法
Jun 24 #Javascript
js实现仿阿里巴巴城市选择框效果实例
Jun 24 #Javascript
Javascript常用小技巧汇总
Jun 24 #Javascript
You might like
服务器web工具 php环境下
2010/12/29 PHP
symfony2.4的twig中date用法分析
2016/03/18 PHP
CI框架源码解读之URI.php中_fetch_uri_string()函数用法分析
2016/05/18 PHP
php 中奖概率算法实现代码
2017/01/25 PHP
PHP面向对象程序设计之多态性的应用示例
2018/12/19 PHP
Ajax+PHP实现的删除数据功能示例
2019/02/12 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
2019/05/08 PHP
php实现JWT验证的实例教程
2020/11/26 PHP
PNG背景在不同浏览器下的应用
2009/06/22 Javascript
javascript parseInt与Number函数的区别
2010/01/21 Javascript
很好用的js日历算法详细代码
2013/03/07 Javascript
jQuery根据纬度经度查看地图处理程序
2013/05/08 Javascript
兼容主流浏览器的iframe自适应高度js脚本
2014/01/10 Javascript
JavaScript格式化日期时间的方法和自定义格式化函数示例
2014/04/04 Javascript
深入理解JavaScript系列(17):面向对象编程之概论详细介绍
2015/03/04 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
2016/06/16 Javascript
Nodejs高扩展性的模板引擎 functmpl简介
2017/02/13 NodeJs
微信小程序实现保存图片到相册功能
2018/11/30 Javascript
javascript实现对话框功能警告(alert 消息对话框)确认(confirm 消息对话框)
2019/05/07 Javascript
基于Vue sessionStorage实现保留搜索框搜索内容
2020/06/01 Javascript
python实现在windows下操作word的方法
2015/04/28 Python
Python3处理文件中每个词的方法
2015/05/22 Python
如何在python中处理配置文件代码实例
2020/09/27 Python
python按照list中字典的某key去重的示例代码
2020/10/13 Python
HTML5 canvas基本绘图之图形变换
2016/06/27 HTML / CSS
美国知名男士服饰品牌:Brooks Brothers(布克兄弟)
2016/08/25 全球购物
美国修容界大佬创建的个人美妆品牌:Kevyn Aucoin Beauty
2018/12/12 全球购物
Foot Locker英国官网:美国知名运动产品零售商
2019/02/21 全球购物
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
学年自我鉴定范文
2013/10/01 职场文书
护理专业个人求职简历的自我评价
2013/10/13 职场文书
主持词开场白
2014/03/17 职场文书
汉语言文学毕业生自荐信范文
2014/03/24 职场文书
信电学院毕业生自荐书
2014/05/24 职场文书
报表员工作失误检讨书范文
2014/09/19 职场文书
班子四风对照检查材料思想汇报
2014/09/29 职场文书