让javascript跑得更快

上传人:宝路 文档编号:23585254 上传时间:2017-12-02 格式:DOC 页数:10 大小:70.01KB
返回 下载 相关 举报
让javascript跑得更快_第1页
第1页 / 共10页
让javascript跑得更快_第2页
第2页 / 共10页
让javascript跑得更快_第3页
第3页 / 共10页
让javascript跑得更快_第4页
第4页 / 共10页
让javascript跑得更快_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《让javascript跑得更快》由会员分享,可在线阅读,更多相关《让javascript跑得更快(10页珍藏版)》请在金锄头文库上搜索。

1、让 javascript 跑得更快下一代 web 应用让 javascript 和 css 得堪大用。我们会告诉你怎样使这些应用又快又灵。建立了号称“Web 2.0” 的应用,也实现了富内容(rich content)和交互,我们期待着 css 和 javascript 扮演更加重要的角色。为使应用干净利落,我们需要完善那些渲染页面的文件,优化其大小和形态,以确保提供最好的用户体验在实践中,这就意味着一种结合:使内容尽可能小、下载尽可能快,同时避免对未改动资源不必要的重新获取。由于 css 和 js 文件的形态,情况有点复杂。跟图片相比,其源代码很有可能频繁改动。而一旦改动,就需要客户端重新下

2、载,使本地缓存无效(保存在其他缓存里的版本也是如此) 。在这篇文章里,我们将着重探讨怎样使用户体验最快:包括初始页面的下载,随后页面的下载,以及随着应用渐进、内容变化而进行的资源下载。我始终坚信这一点:对开发者来说,应该尽可能让事情变得简单。所以我们青睐于那些能让系统自动处理优化难题的方法。只需少许工作量,我们就能建立一举多得的环境:它使开发变得简单,有极佳的终端性能,也不会改变现有的工作方式。好大一沱老的思路是,为优化性能,可以把多个 css 和 js 文件合并成极少数大文件。跟十个5k 的 js 文件相比,合并成一个50k 的文件更好。虽然代码总字节数没变,却避免了多个 HTTP 请求造成

3、的开销。每个请求都会在客户端和服务器两边有个建立和消除的过程,导致请求和响应 header 带来开销,还有服务器端更多的进程和线程资源消耗(可能还有为压缩内容耗费的 cpu 时间) 。(除了 HTTP 请求, )并发问题也很重要。默认情况下,在使用持久连接(persistent connections)时,ie和 firefox 在同一域名内只会同时下载两个资源(在 HTTP 1.1规格书中第8.1.4节的建议) (htmlor 注:可以通过修改注册表等方法改变这一默认配置) 。这就意味着,在我们等待下载2个 js 文件的同时,将无法下载图片资源。也就是说,这段时间内用户在页面上看不到图片。(

4、虽然合并文件能解决以上两个问题, )可是,这个方法有两个缺点。第一,把所有资源一起打包,将强制用户一次下载完所有资源。如果(不这么做,而是)把大块内容变成多个文件,下载开销就分散到了多个页面,同时缓解了会话中的速度压力(或完全避免了某些开销,这取决于用户选择的路径) 。如果为了随后页面下载得更快而让初始页面下载得很慢,我们将发现更多用户根本不会傻等着再去打开下一个页面。第二(这个影响更大,一直以来却没怎么被考虑过) ,在一个文件改动很频繁的环境里,如果采用单文件系统,那么每次改动文件都需要客户端把所有 css 和 js 重新下载一遍。假如我们的应用有个100k 的合成的js 大文件,任何微小的

5、改动都将强制客户端把这100k 再消化一遍。分解之道(看来合并成大文件不太合适。 )替代方案是个折中的办法:把 css 和 js 资源分散成多个子文件,按功能划分、保持文件个数尽可能少。这个方案也是有代价的,虽说开发时代码分散成逻辑块(logical chunks)能提高效率,可在下载时为提高性能还得合并文件。不过,只要给 build 系统(把开发代码变成产品代码的工具集,是为部署准备的)加点东西,就没什么问题了。对于有着不同开发和产品环境的应用来说,用些简单的技术可以让代码更好管理。在开发环境下,为使条理清晰,代码可以分散为多个逻辑部分(logical components) 。可以在 Sm

6、arty(一种 php 模板语言)里建立一个简单的函数来管理 javascript 的下载:foobar.js,bar.js = foobar.js,baz.js = baz.js,);function smarty_insert_js($args)if ($GLOBALSconfigis_dev_site)$files = explode(, $argsfiles);else$files = array(); foreach (explode(, $argsfiles) as $file)$files$GLOBALSconfigjs_source_map$file+;$files = arr

7、ay_keys($files);foreach ($files as $file)echo n;OUTPUT:模板里的源代码没必要为了分别适应开发和产品阶段而改动,它帮助我们在开发时保持文件分散,发布成产品时把文件合并。想更进一步的话,可以把合并过程(merge process)写在 php 里,然后使用同一个(合并文件的)配置去执行。这样就只有一个配置文件,避免了同步问题。为了做的更加完美,我们还可以分析 css 和 js 文件在页面中同时出现的几率,以此决定合并哪些文件最合理(几乎总是同时出现的文件是合并的首选) 。对 css 来说,可以先建立一个主从关系的模型,它很有用。一个主样式表控制

8、应用的所有样式表,多个子样式表控制不同的应用区域。采用这个方法,大多数页面只需下载两个 css 文件,而其中一个(指主样式表)在页面第一次请求时就会缓存。对没有太多 css 和 js 资源的应用来说,这个方法在第一次请求时可能比单个大文件慢,但如果保持文件数量很少的话,你会发现其实它更快,因为每个页面的数据量更小。让人头疼的下载花销被分散到不同的应用区域,因此并发下载数保持在一个最小值,同时也使得页面的平均下载数据量很小。压缩谈到资源压缩,大多数人马上会想到 mod_gzip(但要当心,mod_gzip 实际上是个魔鬼,至少能让人做恶梦) 。它的原理很简单:浏览器请求资源时,会发送一个 hea

9、der 表明自己能接受的内容编码。就像这样:;close F;$data = s!/*(.*?)*/!g; # 去掉注释$data = s!s+! !g; # 压缩空格$data = s! !n!g; # 在结束大括号后添加换行$data = s!n$!; # 删除最后一个换行$data = s! ! !g; # 去除开始大括号后的空格$data = s!; !g; # 去除结束大括号前的空格 print $data;然后,就可以把单个的 css 文件传给脚本去压缩了。命令如下:press.css 做完这些简单的纯文本优化工作后,我们就能减少数据传输量多达50%了(这个量取决于你的代码格式,可

10、能更多) 。这带来了更快的用户体验。不过我们真正想做的是,尽可能避免用户请求的发生除非确实有必要。这下 HTTP 缓存知识派上用场了。缓存是好东西当用户代理(如浏览器)向服务器请求一个资源时,第一次请求过后它就会缓存服务器的响应,以避免重复之后的相同请求。缓存时间的长短取决于两个因素:代理的配置和服务器的缓存控制 header。所有浏览器都有不同的配置选项和处理方式,但大多数都会把一个资源至少缓存到会话结束(除非被明确告知) 。为了不让浏览器缓存改动频繁的页面,你很可能已经发送过 header 不缓存动态内容。在 php 中,以下两行命令可以做到:或标记向服务器发送一个请求,说明哪个页面要加载

11、这些文件。这时候就可以用服务器的响应来通知客户端这些文件有了改动。有点含糊,说得再详细点就是:如果改变 css 和 js 文件内容的同时,也改变它们的文件名,就可以告诉客户端对 url全都永久缓存因为每个 url 都是唯一的。假如能确定一个资源永不更改,我们就可以发出一些霸气十足的缓存 header(htmlor 注:这句也很有气势吧) 。在 php 里,两行就好:/images/foo.gif/css/main.v1.27.css - /css/main.css/javascript/md5.v6.js - /javascript/md5.js 使用这条规则,就可以做到不改变文件路径而更改

12、url(因为版本号变了) 。由于 url 变了,浏览器就认为它是另一个资源(会重新下载) 。想更进一步的话,可以把我们之前说的脚本编组函数结合起来,根据需要生成一个带有版本号的标记列表。说到这里,你可能会问我,为什么不在 url 结尾加一个查询字符串(query string)呢(如/css/main.css?v=4)?根据 HTTP 缓存规格书所说,用户代理对含有查询字符串的 url 永不缓存。虽然 ie 跟 firefox 忽略了这点,opera 和 safari 却没有为了确保所有浏览器都缓存你的资源,还是不要在 url 里用查询字符串的好。现在不移动文件就能更改 url 了,如果能让

13、url 自动更新就更好了。在小型的产品环境下(如果有大型的产品环境,就是开发环境了) ,使用模板功能可以很轻易的实现这点。这里用的是 smarty,用其他模板引擎也行。PHP:function smarty_version($args)$stat = stat($GLOBALSconfigsite_root.$argssrc);$version = $statmtime;echo preg_replace(!.(a-z+?)$!, .v$version.$1, $argssrc);OUTPUT:对每个链接到的资源文件,我们得到它在磁盘上的路径,检查它的 mtime(文件最后修改的日期和时间)

14、,然后把这个时间当作版本号插入到 url 中。对于低流量的站点(它们的 stat 操作开销不大)或者开发环境来说,这个方案不错,但对于高容量的环境就不适用了因为每次 stat 操作都要磁盘读取(导致服务器负载升高) 。解决方案相当简单。在大型系统中每个资源都已经有了一个版本号,就是版本控制的修订号(你们应该使用了版本控制,对吧?) 。当我们建立站点准备部署的时候,可以轻易的查到每个文件的修订号,写在一个静态配置文件里。2.1,/css/main.css = 1.27,/javascript/md5.js = 6.1.4,); 当我们发布产品时,可以修改模板函数来使用版本号。?php funct

15、ion smarty_version($args)if ($GLOBALSconfigis_dev_site)$stat = stat($GLOBALSconfigsite_root.$argssrc);$version = $statmtime;else$version = $GLOBALSconfigresource_versions$argssrc;echo preg_replace(!.(a-z+?)$!, .v$version.$1, $argssrc); 就这样,不需要改文件名,也不需要记住改了哪些文件当文件有新版本发布时它的 url 就会自动更新有意思吧?我们就快搞定了。只欠东风之前谈到为静态文件发送超长周期(very-long-period)的缓存 header 时曾说过,如果不用 php 输出,就不能轻易的发送缓存 header。很显然,有两个办法可以解决:用 php 输出,或者让 apache 来做。php 出马,手到擒来。我们要做的仅仅是改变 rewrite 规则,把静态文件指向 php 脚本,用 php 在输出文件内容之前发送 header。?php Apache:RewriteRul

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号