阿不

不抛弃,不放弃

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  158 随笔 :: 0 文章 :: 2109 评论 :: 70 引用

大家好像都有一种同感,使用了asp.net ajax的网站的速度好像都不是特别快。目前维护的网站,页面执行时间在0.1秒上下,页面本身的HTML也在50K左右,经常都是页面标题已经显示出来一段时间了,但是页面还是空白的。可以说页面本身已经相当快了,但就是在加载脚本的时间花了比较长的时间。而通常情况下脚本的加载本身就是串行的下载方式,简单来说,当页面执行到脚本引用的位置,只有等到脚本下载完后,之后的HTML或javascript代码才会继续执行和呈现。而一般情况下,asp.net ajax注册的脚本都是在页面的HTML代码之前,又受到浏览器并行连接数的限制,使得多个脚本的下载更是雪上加霜。使得页面的展示只有等到asp.net ajax脚本加载完后才呈现出来。所以速度慢的体验就更加明显了。(更多关于脚本下载的优化建议可以参见JeffreyZhao《挣脱浏览器的束缚》系列文章)

到目前为止,我也不是特别确定,究竟就是由于下载慢,还是脚本多,初始化也需要比较多的时间。这种初始化不一定是load事件的初始化,还包括定义的类型的解析,如果类型的上下文解析也需要时间的话,那肯定就相当麻烦了。因为asp.net ajax几个核心脚本库,再加上如果你使用了Ajaxcontroltoolkit的话,那需要下载和初始化的脚本数量就非常多了,里面定义的函数和类数量也比javascript核心的还多。当然,这只是一种担忧,事实上可能并不这样的。我们还应该把目光集中脚本的加载上。

我想大多数使用者都不去关心asp.net ajax脚本的注册方式,通常情况下,我们只会关心脚本能否正常加载,正常执行。而不会去关心它是使用何种方式加载的。默认情况下,asp.net ajax都是加载脚本资源(程序集中的脚本资源文件)的方式(使用ScriptResource.axd加一段查询参数)来下载脚本。这种方式显然是非常方便,不需要我们手工指定或引用脚本,一切都交给ScriptManager来帮我们完成。殊不知,这里也会存在一些问题,那就是同一个程序,同个程序集资源,每次重启后都会得到不同的ScriptResource.axd的查询参数。也就是说,如果用户此次下载的脚本,也缓存在客户端了。但是当我们重启服务器后,客户端缓存的脚本就不再有效,就又必须再次下载新的脚本资源了。这样就造成了大量的资源浪费了。在这种情况下,最好的方式当然是以直接引用文件的会更好了。这时,我们就应该想起,在ScriptManager中,提供了一个ScriptPath属性,平常这是一个相当不起眼的属性,但是可别小瞧了它了。利用它我们就可以来实现我们目的。

先来说说ScriptPath这个属性的作用吧,它就是用来指定asp.net ajax的客户端脚本文件的路径。只要指定它的值,ScriptManager就去引用这个目录下的脚本文件,来代替程序集脚本资源。这样有一个好处就是方便我们可以修改asp.net ajax脚本资源(当然最好别去改它),另一好处就是如上所述的目的。指定了ScriptPath,它是如何引用脚本的?也就是如何确定脚本路径的?使用了ScriptPath,那么它的脚本文件必须放在ScriptPath目录下的 程序集名称/版本号/脚本资源名称 ,如:使用Javascript\System.Web.Extensions\1.0.61025.0\MicrosoftAjax.js ,来加载MicrosoftAjax.js。

这个ScriptPath,同时也对AjaxControlToolkit生效的,这时,我们可以把AajaxControlToolkit的脚本都放在:JavaScript\AjaxControlToolkit\1.0.10618.0 下文件的形式来引用。

通过使用ScriptPath,不管网站再如何重启,加载的都是同一份的脚本,这样就可以充分利用客户端缓存的功能。同时如果文章开头部分所述,我们还可以再使用一个优化,修改ScriptManager的行为,将脚本的注册放在HTML之后。当然这样可能会有一些不可预料的行为发生,比如脚本的加载事件不能被正确执行。这个修改就必须要因地制宜,或者说根据你当前的实际需求而定了。

阿不

阿不 http://hjf1223.cnblogs.com
posted on 2007-11-22 20:36 阿不 阅读(2846) 评论(20)  编辑 收藏 所属分类: JavaScript相关技术

评论

#1楼  2007-11-22 21:20 Jeffrey Zhao      
其实重启了也就下载一次,关系没差太多,呵呵。
  回复  引用  查看    

#2楼  2007-11-22 21:49 Cat Chen      
ScriptPath的原本用意是版本控制。
  回复  引用  查看    

#3楼  2007-11-22 22:18 浪子      
不知道为什么,始终觉得有点慢,呵呵.

可能自己用惯了轻量级的实现
  回复  引用  查看    

#4楼 [楼主] 2007-11-23 08:50 阿不      
@Jeffrey Zhao
程序一般会一天,两天重启一次吧?那这样每个用户相当于每天都要下一个新的脚本文件了。
  回复  引用  查看    

#5楼 [楼主] 2007-11-23 08:51 阿不      
@ Cat Chen
版本控制?它所引用的脚本都是与程序集的版本相关的
  回复  引用  查看    

#6楼  2007-11-23 08:53 Clark Zheng      
我负责的站点每周luck一次
  回复  引用  查看    

#7楼  2007-11-23 08:56 4x4y.com [未注册用户]
不是有点,确实是很慢,用过几次,放弃。做内部系统可能合适,做网站。。我选择坚决放弃这玩意儿
  回复  引用    

#8楼 [楼主] 2007-11-23 08:59 阿不      
@ 浪子
是啊,如果现在让我再次选择。我不定会再使用这个了。
毕竟现在用的它的服务器控件少了,比如UpdatePanel。而脚本又特别多。不过asp.net ajax里面对于WebService的调用确实是非常好。
  回复  引用  查看    

#9楼  2007-11-23 11:11 Enzo      
我也发现这个问题,有时加载有点慢,不知道是布局不够合理,还是有什么其他原因
  回复  引用  查看    

#10楼  2007-11-23 11:28 Jeffrey Zhao      
一定要优化
  回复  引用  查看    

#11楼 [楼主] 2007-11-23 13:03 阿不      
非常有必要优化。
一个早上都在这事呢。
把脚本注册都页面最后,
但还是由于执行顺序的原因,MicrosoftAjax.js。这个文件一定要在页面之前加载。(也是系统默认的),而其它的脚本可以使用LoadScriptsBeforeUI="false",来让它晚加载,比如AJAXControlToolkit.
另外使用文件引用,还需要注意那些资源文件字符串的定义。为了支持本地化,这个资源文件字符串,都是在脚本资源文件读取的时候才被添加到脚本里的。所以此时如果直接引用原始的脚本文件,会找不到这个字符串的定义。
  回复  引用  查看    

#12楼  2007-11-23 13:55 浪子      
其实衡量一下,你到底用了多少asp.net ajax多少功能,如果让你重新切换框架会花去多少力气,而你花在优化上的时间支出和效果又会如何。

综合一下,进行一个适当的取舍。

好比我当初一样,最终还是放弃了asp.net ajax ,感觉现在舒心多了,起码一切都在自己的控制之内^_^

--引用--------------------------------------------------
阿不: @ 浪子
是啊,如果现在让我再次选择。我不定会再使用这个了。
毕竟现在用的它的服务器控件少了,比如UpdatePanel。而脚本又特别多。不过asp.net ajax里面对于WebService的调用确实是非常好。
--------------------------------------------------------

  回复  引用  查看    

#13楼 [楼主] 2007-11-23 14:24 阿不      
@浪子
现在再去换,也不合算了。反正优化到一定的效果。还是觉得可以接受了。
使用文件引用,再加上gzip压缩。应该还行吧现在。
  回复  引用  查看    

#14楼  2007-11-23 17:28 随风流月      
俺的项目的首页只有 6k 左右。用了很多 js 特效。hoho。
  回复  引用  查看    

#15楼  2007-11-24 07:33 Cat Chen      
@阿不
不是用于引用别人的js,而是用于引用你自己的。例如你自己的网站每天build的,就好像Microsoft那样有一个build号,那么你可以让build的脚本每天改变ScriptPath为最新的build号。为什么这样做呢?

假设你做一个ASP.NET代码不怎么改动的网站,但js天天都更新,如果某一天的build出现问题了,怎么办?当然是roll back啦。如何roll?如果你放在/js下面,那么你就手动把/js/*.js手动删除,然后把上一个版本的.js重新放进去,那么中间那几秒这些js是不存在的。而ScriptPath就是让你轻松roll back的,你改一个值就能够让js都回到昨天的版本。
  回复  引用  查看    

#16楼 [楼主] 2007-11-24 08:29 阿不      
@Cat Chen
但是对于System.Web.Externsions来说,它的版本号基本是固定的。而且ScriptPath属性作用于类似Ajaxcontroltollkit这样的从asp.net ajax extend而来的控件上。我们网站的每天build出来的版本号,根本与这不搭边呀。
  回复  引用  查看    

#17楼  2007-11-24 08:50 Hafeyang      
我觉得要看你做什么项目了
时间紧,对项目速度要求不高的时候 用用也无妨
不过性能确实让人担忧
  回复  引用  查看    

#18楼  2007-11-24 22:59 Jeffrey Zhao      
@阿不
对于版本号不变的程序集,自然不用变了。
  回复  引用  查看    

#19楼 [楼主] 2007-11-24 23:16 阿不      
@Jeffrey Zhao
确实是不用变,呵呵。
  回复  引用  查看    

#20楼 [楼主] 2007-11-28 13:39 阿不      
通过YSlow,让自己注意到了平常一般都没有注意的细节。那就是给客户端缓存的文件指定一个过期时间。通过情况如果没有指定过期时间的话,缓存只对当前请求有效,下次再访问的情况又得重新下载缓存的文件了。所以指定比较长的过期时间对客户端缓存才比较有意义。所以一定要指定一个比较长的过期时间。一旦过期时间过长的话,版本更新对脚本修改就必须要有一个比较好的控制了,此时,Cat Chen提到的版本控制就有它的意义了。
  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: