在JavaScript应用中使用RequireJS来实现延迟加载
无论简单还是复杂的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; }
在浏览器中打开这个页面,你将看到如下的信息。
虽然上面的代码能够显示输出,但是它仍有一些问题:
- 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文件。
总结
在这篇文章里,我们分析了requirejs框架是如何处理javascript文件间的依赖关系并根据需要载入它们的。它能够帮助开发者写出更松耦合、更模块化且更具有可维护性的代码。
推荐阅读
-
在JavaScript应用中实现延迟加载的方法
-
在JavaScript应用中使用RequireJS来实现延迟加载
-
在JavaScript应用中使用RequireJS来实现延迟加载
-
在JavaScript应用中实现延迟加载的方法
-
在JavaScript应用中使用RequireJS来实现延迟加载
-
在JavaScript应用中使用RequireJS来实现延迟加载
-
在JavaScript应用中实现延迟加载的方法_基础知识
-
在JavaScript应用中使用RequireJS来实现延迟加载_基础知识
-
在JavaScript应用中使用RequireJS来实现延迟加载_基础知识
-
在JavaScript应用中实现延迟加载的方法_基础知识