已有树状列表控件分析发现问题
近期发现有人在ASP.NET项目开发中使用一种叫dtree的树状列表组件加载缓慢。这也是笔者撰写本章的动机。毛主席教导我们,做事要发现问题,分析问题和解决问题。首先我们发现了已有的树状列表WEB控件加载缓慢的问题,接下来就很自然的是分析问题了。
下图就是dtree 运行界面的例子
分析问题
现在我们分析问题,对使用dtree生成树状列表的程序代码的分析,可以了解程序运行过程如下图所示
在这样的程序中,首先服务器端的C#代码查询数据库,然后根据查询所得数据拼凑出一个Javascript代码字符串,然后发往客户端,客户端浏览器获得这个Javascript代码字符串并开始执行它,而在Javascript脚本中也是字符串拼凑出一段HTML代码字符串,然后使用浏览器提供的 document.write方法或obj.innerHTML属性将生成的HTML字符串填充到HTML页面中进行展示。
这是是分析了dtree的流程,但使用其他的一些树状列表控件也大体如此。
现在我们根据这个流程图来判断是哪个环节速度缓慢。基本上数据库本身查询速度是没问题;将查询结果传递到C#程序中问题也不大,因为一般的数据库服务器和ASP.NET程序是在一台电脑上或者同一个高速局域网中;C#程序生成Javascript字符串的过程也是没多大问题,因为C#运行速度是相当的快的,而且还有StringBuilder来加速字符串拼凑操作,因此只要逻辑算法没有问题,速度是有保障的。总体来说服务器端内部是没有速度问题。
将Javascript字符串通过网络从服务器端发送到客户端,所花的的时间是字符串长度除以网络传输速度,若WEB系统运行在高速的局域网中,则速度没多大问题,但若WEB程序运行在缓慢的广域网或英特网中,则Javascript字符串长度会比较大的影响程序运行速度。由于公司系统主要运行在局域网中,因此网络传输速度不是主要问题。
在客户端浏览器中,浏览器接受并执行Javascript脚本代码,在Javascript脚本中使用字符串拼凑来生成用于展现树状列表的HTML 字符串。Javascript代码是解释方式执行的,速度相当慢,而字符串拼凑操作也是比较缓慢的操作,Javascript中没有任何手段来优化字符串拼凑操作。因此由Javascript代码生成HTML字符串的过程是缓慢的,这是一个速度瓶颈。
Javascript代码还调用浏览器提供的document.write函数或innerHTML属性将生成的HTML字符串填充到页面中,浏览器会解析这个HTML代码并展现出树状列表。由于document.write或innerHTML是运行在浏览器内部的,外部程序无法控制,而且速度也不算慢,因此这里也就没有什么好优化的。
经过上述分析,可以看到整个展现树状列表的过程中最缓慢的环节就是使用Javascript脚本来生成HTML代码字符串,其次就是数据从服务器端发送到客户端的过程。若一个树状列表要显示数千个节点,则Javascript脚本将拼凑出几百K甚至过MB的HTML字符串,这个过程是相当缓慢的,很容易导致IE浏览器由于脚本运行过于缓慢而提示用户是否继续执行脚本。
因此Javascript脚本生成HTML字符串将是我们主要的优化环节,也是新开发的树状列表控件的重点关注部分。