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

无论简单还是复杂的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文件间的依赖关系并根据需要载入它们的。它能够帮助开发者写出更松耦合、更模块化且更具有可维护性的代码。

谢谢

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

(0)

相关推荐

  • JavaScript异步加载浅析

    前言 关于JavaScript脚本加载的问题,相信大家碰到很多.主要在几个点-- 1> 同步脚本和异步脚本带来的文件加载.文件依赖及执行顺序问题 2> 同步脚本和异步脚本带来的性能优化问题 深入理解脚本加载相关的方方面面问题,不仅利于解决实际问题,更加利于对性能优化的把握并执行.   先看随便一个script标签代码-- 复制代码 代码如下: <script src="js/myApp.js"></script> 如果放在<head>上面

  • javascript图片预加载实例分析

    本文实例讲述了javascript图片预加载的方法.分享给大家供大家参考.具体如下: lightbox类效果为了让图片居中显示而使用预加载,需要等待完全加载完毕才能显示,体验不佳(如filick相册的全屏效果).javascript无法获取img文件头数据,真的是这样吗?本文通过一个巧妙的方法让javascript获取它. 这是大部分人使用预加载获取图片大小的例子: var imgLoad = function (url, callback) { var img = new Image(); i

  • 关于延迟加载JavaScript

    JavaScript的延迟加载是那些在web上,能让你想抓狂地去寻找解决方案的问题之一. 很多人说"那就用defer"或"async",甚至有些人说"那就将你的javascript代码放在页面代码底部". 上述方法都不能解决在web页面完全加载后,再加载外部js的问题.上述方法也会偶尔让你收到Google页面速度测试工具的"延迟加载javascript"警告.所以这里的解决方案将是来自Google帮助页面的推荐方案. 如何延迟

  • javascript顺序加载图片的方法

    本文实例讲述了javascript顺序加载图片的方法.分享给大家供大家参考.具体如下: javascript监听一个图片是否加载完毕 如果加载完成再加载下一张,不是一次性从服务器加载 减少服务器压力, 可用到的地方:比如制作类似google地图的应用,可以使小图一张一张的加载 function Load_pic(arr){ this.loop_f=function(i,o_file,len,f,obj){ if(i<len-1){ i=i+1; f(i,o_file,len,obj); } };

  • 关于Javascript加载执行优化的研究报告

    本人做前端开发一年多了,对前端的见解还是多多少少有一点的,今天特拿出来跟大家分享分享. 做前端开发少不了各种利器.比如我习惯用的还是Google浏览器和重型武器Fiddller. 一: 原始情况 首先大家看看如下的代码: 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JsLoad.Def

  • 异步安全加载javascript文件的方法

    本文实例讲述了异步安全加载javascript文件的方法.分享给大家供大家参考.具体如下: 使用方法: (function() { __safeLoadScript("http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js", function() { alert(jQuery); }); })(); JavaScript实现代码: window.__safeLoadScript = function(src, c

  • javascript文件加载管理简单实现方法

    本文实例讲述了javascript文件加载管理简单实现方法.分享给大家供大家参考.具体如下: 这里介绍超级简单的进行javascript的文件(模块)的加载管理, 实现sea.js或者require.js核心功能,用一行 <script src="js/light/light.js"></script> 加载所有的js文件. //按照lightJs的顺序,让网页加载js文件: var lightJs = [ "./js/light/pre/jquery

  • JavaScript动态加载样式表的方法

    本文实例讲述了JavaScript动态加载样式表的方法.分享给大家供大家参考.具体如下: 如果需要更换皮肤,我们可以通过JS代码动态加载皮肤的样式表,下面的代码就可以做到,非常简单,你只需要把这段代码做成函数动态调用即可. var el = document.createElement('link'); el.rel = 'stylesheet'; el.type = 'text/css'; el.href = 'http://www.jb51.net/...' + 'styles.css';

  • javascript实现动态加载CSS

    复制代码 代码如下: <script type="text/javascript">             function addStyle(stylePath) {                 var container = document.getElementsByTagName("head")[0];                 var addStyle = document.createElement("link"

  • JavaScript 动态加载脚本和样式的方法

    一 动态脚本 当网站需求变大,脚本的需求也逐步变大;我们不得不引入太多的JS脚本而降低了整站的性能; 所以就出现了动态脚本的概念,在适时的时候加载相应的脚本; 1.动态引入js文件 var flag = true; if(flag){ loadScript('browserdetect.js'); // 调用函数,引入路径; } function loadScript(url){ var script = document.createElement('script'); // 创建script

随机推荐