技术开发 频道

项目分析:原生对象前端加载数据性能PK

  【IT168技术详细分析

  1. 首先,创建一系列的实体类:

/// <summary>
/// 用户信息
/// </summary>
public class UserInfo
{
    
public int UserId { get; set; }

    
public string UserName { get; set; }

    
public string Email { get; set; }

    
public Class Class { get; set; }

    
public List<UserRight> UserRightList { get; set; }
}

/// <summary>
/// 班级信息
/// </summary>
public class Class
{
    
public int ClassId { get; set; }

    
public string ClassName { get; set; }
}

/// <summary>
/// 用户权限信息
/// </summary>
public class UserRight
{
    
public int RightId { get; set; }

    
public string RightName { get; set; }
}

  其中包括用户信息类、班级信息类、用户权限类。

  2. 在Web.config配置一个appsettings节点

<appSettings>
    
<add key="DataCount" value="3000"/>
</appSettings>

  表示一次加载的数据量(用户信息数)为3000。

  并且将compilation节点的dubug属性设置为false。

  3. JSON加载数据测试

  1)首先先测试 WebService客户端调用并且最后返回JSON加载数据:

  代码

function bindDataWebServiceJson() {

  var watch
= new Stopwatch();

  watch.start();

  JsonService.GetUserList(

  
function(data) {

  var builder
= new Sys.StringBuilder();

  
for (var i = 0, length = data.length; i < length; i++) {

  builder.append(
String.format("

UserId:{
0}, UserName:{1}, Email:{2}
", data[i].UserId, data[i].UserName, data[i].Email));


  }

  $(
"#msg2").html(builder.toString());

  watch.stop();

  $(
"#time2").html("用时:" + watch.ms + "毫秒.");

  });

  }

  通过代码,我们可以看到它调用了JsonService.asmx中Web服务的GetUserList方法:

  代码

[WebMethod]

  
public List GetUserList()

  {

  
int count = Convert.ToInt32(ConfigurationManager.AppSettings["DataCount"]);

  List list
= new List();

  
for (int i = 0; i < count; i++)

  {

  list.Add(
new UserInfo { UserId = i, UserName = "leepy" + i, Email = "sunleepy" + i + "@gmail.com" });

  }

  return list;

  }

    返回了一个3000条记录的UserInfo实体列表,而前端页面通过对列表返回客户端时的Json对象,进行Html字符串拼接,最后通过jQuery的Dom元素html(‘…’)方法赋值。运行加载结果为:

  目前我的项目大多数就是采用这样的模式。

  2)接着,如果使用jQuery的$.ajax调用并且最后JSON加载数据:

  代码

function bindDatajQueryAjaxJson() {

  var watch
= new Stopwatch();

  watch.start();

  $.ajax({

  url:
"JsonHandler.ashx",

  dataType:
'json',

  cache:
false,

  success:
function(data) {

  var builder
= new Sys.StringBuilder();

  
for (var i = 0, length = data.length; i < length; i++) {

  builder.append(
String.format("

UserId:{
0}, UserName:{1}, Email:{2}
", data[i].UserId, data[i].UserName, data[i].Email));

  }

  $(
"#msg4").html(builder.toString());

  watch.stop();

  $(
"#time4").html("用时:" + watch.ms + "毫秒.");

  }

  });

  }

 

    通过JsonHandler.ashx的页面处理程序执行返回数据:

  代码

public void ProcessRequest (HttpContext context) {

  context.Response.ContentType
= "application/x-javascript";

  
int count = Convert.ToInt32(ConfigurationManager.AppSettings["DataCount"]);

  List list
= new List();

  
for (int i = 0; i < count; i++)

  {

  list.Add(
new UserInfo { UserId = i, UserName = "leepy" + i, Email = "sunleepy" + i + "@gmail.com" });

  }

  StringBuilder builder
= new StringBuilder();

  
string data = "[";

  
for (int i = 0, length = list.Count; i < length; i++)

  {

  data
+= "{" + string.Format("'UserId':'{0}','UserName':'{1}', 'Email':'{2}'", list[i].UserId, list[i].UserName, list[i].Email) + "},";

  }

  data
= data.TrimEnd(',') + "]";

  context.Response.Write(data);

  }

 

  也是3000条用户数据,运行加载结果为:

  比WebService快了一些。

  3)接着,使用$.getJSON来调用并且JSON加载数据:

  代码

function bindDatajQueryGetJson() {

  var watch
= new Stopwatch();

  watch.start();

  $.getJSON(
"JsonHandler.ashx", function(data) {

  var builder
= new Sys.StringBuilder();

  
for (var i = 0, length = data.length; i < length; i++) {

  builder.append(
String.format("

UserId:{
0}, UserName:{1}, Email:{2}
", data[i].UserId, data[i].UserName, data[i].Email));

  }

  $(
"#msg5").html(builder.toString());

  watch.stop();

  $(
"#time5").html("用时:" + watch.ms + "毫秒.");

  });

  }

 

  同样通过JsonHandler.ashx的页面处理程序执行返回数据,运行加载结果为:

  和$.ajax相差无几,实际从jQuery代码中可以看出实际上$.getJSON调用的就是$.ajax函数:

  代码

get: function(url, data, callback, type)

  {

  
// shift arguments if data argument was ommited

  
if (jQuery.isFunction(data))

  {

  callback
= data;

  data
= null;

  }

  return jQuery.ajax({

  type:
"GET",

  url: url,

  data: data,

  success: callback,

  dataType: type

  });

  },

  getJSON:
function(url, data, callback)

  {

  return jQuery.get(url, data, callback,
"json");

  }

 

  4)接着,使用xmlHttp.js的原生对象调用并且JSON加载数据:

  代码

function bindDataPrototypeAjaxJson() {

  var watch
= new Stopwatch();

  watch.start();

  Request.sendGET(
"JsonHandler.ashx", false, function(data) {

  var jsonData
= JSON.parse(data, null);

  var builder
= new Sys.StringBuilder();

  
for (var i = 0, length = jsonData.length; i < length; i++) {

  builder.append(
String.format("

UserId:{
0}, UserName:{1}, Email:{2}
", jsonData[i].UserId, jsonData[i].UserName, jsonData[i].Email));


  }

  $(
"#msg11").html(builder.toString());

  watch.stop();

  $(
"#time11").html("用时:" + watch.ms + "毫秒.");

  });

  }

 

  其中var jsonData = JSON.parse(data, null); 用到了一个json2.js 的开源JSON解析组件,将data的字符串转换为一个JSON对象。运行结果为:

  和jQuery的$.ajax函数也是基本相差无几。

  测试说明:$.ajax,$.getJSON,原生对象返回JSON加载数据的效率基本一样,比WebService的效率好些。

  4. Html字符串加载数据测试

  1)WebService客户端调用返回Html字符串加载数据:

  代码

function bindDataWebServiceHtml() {

  var watch
= new Stopwatch();

  watch.start();

  HtmlService.GetUserListHtml(

  
function(data) {

  $(
"#msg1").html(data);

  watch.stop();

  $(
"#time1").html("用时:" + watch.ms + "毫秒.");

  });

  }

 

  通过代码,我们可以看到它调用了HtmlService.asmx中Web服务的GetUserListHtml方法:

  代码

[WebMethod]

  
public string GetUserListHtml() {

  List list
= GetUsers();

  StringBuilder builder
= new StringBuilder();

  
for (int i = 0, length = list.Count; i < length; i++)

  {

  builder.AppendFormat(
"

UserId:{
0}, UserName:{1}, Email:{2}
", list[i].UserId, list[i].UserName, list[i].Email);


  }

  return builder.ToString();

  }

 

    将前端页面对于Html字符串拼接的工作放在WebService中(或者相关后台代码)中去执行,最后通过jQuery的Dom元素html(‘…’)方法赋值。运行加载结果为:

  2)jQuery的$.ajax调用返回Html字符串加载数据:

  代码

function bindDatajQueryAjaxHtml() {

  var watch
= new Stopwatch();

  watch.start();

  $.ajax({

  type:
"get",

  url:
"HtmlHandler.ashx",

  cache :
false,

  success:
function(data) {

  $(
"#msg3").html(data);

  watch.stop();

  $(
"#time3").html("用时:" + watch.ms + "毫秒.");

  }

  });

  }

  通过HtmlHandler.ashx的页面处理程序执行返回数据:

  代码

public void ProcessRequest (HttpContext context) {

  
int count = Convert.ToInt32(ConfigurationManager.AppSettings["DataCount"]);

  List list
= new List();

  
for (int i = 0; i < count; i++)

  {

  list.Add(
new UserInfo { UserId = i, UserName = "leepy" + i, Email = "sunleepy" + i + "@gmail.com" });

  }

  StringBuilder builder
= new StringBuilder();

  
for (int i = 0, length = list.Count; i < length; i++)

  {

  builder.AppendFormat(
"

UserId:{
0}, UserName:{1}, Email:{2}
", list[i].UserId, list[i].UserName, list[i].Email);



  }

  context.Response.Write(builder.ToString());

  }

 

  运行加载结果为:

  比WebService也快了一些。

  3)原生Ajax调用返回Html字符串加载数据:

  代码

function bindDataPrototypeAjaxHtml() {

  var watch
= new Stopwatch();

  watch.start();

  Request.sendGET(
"HtmlHandler.ashx", false, function(data) {

  $(
"#msg6").html(data);

  watch.stop();

  $(
"#time6").html("用时:" + watch.ms + "毫秒.");

  });

  }

 

  运行加载结果为:

  和jQuery的$.ajax函数也是基本相差无几。

  测试说明:$.ajax,$.getJSON,原生对象返回返回Html字符串加载数据的效率基本一样,比WebService的效率好些;并且通过3和4的比较,说明通过在后台拼接Html字符串,比在前台来拼接的过程来得更高效。

  5. 在我的实例中,大家也许注意到了有“原生Html赋值”和“jQuery Dom赋值”的单选按钮,这是什么呢?很简单,前者就是形如document.getElementById(‘…’),后者就是我们项目中使用的$('#…’).html(‘…’)这样的形式。这两种创建DOM元素上有什么差别吗?用测试说话。

  我任意挑选几张对比截图:

  测试说明:使用原生对象Html赋值比jQuery的Html赋值性能上提升了许多;换句话,就是尽量多使用document.getElementById(‘…’)这样来赋值。

  6. 最后我们通过cs代码隐藏文件加载数据

  代码

protected void Page_Load(object sender, EventArgs e)

  {

  Stopwatch watch
= new Stopwatch();

  watch.Start();

  
int count = Convert.ToInt32(ConfigurationManager.AppSettings["DataCount"]);

  List list
= new List();

  
for (int i = 0; i < count; i++)

  {

  list.Add(
new UserInfo { UserId = i, UserName = "leepy" + i, Email = "sunleepy" + i + "@gmail.com" });

  }

  StringBuilder builder
= new StringBuilder();

  
for (int i = 0, length = list.Count; i < length; i++)

  {

  builder.AppendFormat(
"

UserId:{
0}, UserName:{1}, Email:{2}
", list[i].UserId, list[i].UserName, list[i].Email);


  }

  msg7.InnerHtml
= builder.ToString();

  time7.Text
= "用时:" + watch.ElapsedMilliseconds + "毫秒.";

  }

  
public int GetDataCount()

  {

  return Convert.ToInt32(ConfigurationManager.AppSettings[
"DataCount"]);

  }

 

  运行结果为:

  使用后台代码进行页面上的业务逻辑实现是相当高效的。

  测试说明:在页面第一次加载的时候,尽量能够在服务端后台代码对服务器控件进行数据绑定,也就是说多使用runat=”server”这样的服务端控件,特别可以充分使用repeater控件的优势来进行数据绑定。

  总结

  再把前面的测试结果列举一下:

  1. .ajax,$.getJSON,原生对象返回JSON加载数据的效率基本一样,比WebService的效率好些。

  2. $.ajax,$.getJSON,原生对象返回返回Html字符串加载数据的效率基本一样,比WebService的效率好些;

  3. 通过测试3和测试4的比较,说明通过在后台拼接Html字符串,比在前台来拼接的过程来得更高效。

  4. 使用原生对象Html赋值比jQuery的Html赋值性能上提升了许多;换句话,就是尽量多使用document.getElementById(‘…’)这样来赋值。

  5. 在页面第一次加载的时候,尽量能够在服务端后台代码对服务器控件进行数据绑定,也就是说多使用runat=”server”这样的服务端控件,特别可以充分使用repeater控件的优势来进行数据绑定。

  这是我对于前端页面加载数据时,通过几种方式测试得出来的结果以及结论,如果不妥的地方,希望大家能够提出,欢迎交流,谢谢指教:)

0
相关文章