pre{
white-space:pre-wrap;
white-space:-moz-pre-wrap;
white-space:-pre-wrap;
white-space:-o-pre-wrap;
word-wrap:break-word;
}
Category Archives: Software Dev
如何进行Web应用的安全测试和输入校验
在Web应用占主流的今天,主流的黑客也都把攻击的目标转向了Web应用,SQL Injection, XSS… 各种攻击技术层出不穷,但是苍蝇不叮无缝的蛋,这么多种攻击技术无非都是把有毒的东西送到了蛋的内部。所以说只要输入校验做的好就可以阻止90%-95%的攻击。如何做输入校验才能尽可能的弥补所有的缝呢?下面这几个注意事项或许可以帮你一些
1. 找到Web应用所有的输入点,找到所有的能接受用户输入的地方,漏掉输入点也就漏掉了可能存在的缝。
2. 过滤每一个输入点,为每个输入点设定相应的校验规则和边界。
3. 不要忘记校验哪些隐藏域,cookie和url参数。
4. 验证从数据库里面得到的数据,这个是最容易忽视的地方,不要相信来自数据库里面的数据就是合法的数据。
5. 你是如何做输入校验的? javascript?如果只是用javascript做客户端校验, 风险还是很大的,一定要确保加上服务端的校验,否则如果客户端禁用了javascript或者客户端代码被人工修改,非法数据还是会进入系统内部的。
6. 隐藏异常信息,再周全的校验也不可能覆盖所有的case,如果非法数据造成了系统的异常,不要将详细的异常信息暴露给客户端,这些异常信息有可能成为系统的攻击入口。
在做输入校验的时候,从“什么样的输入才是合法的”入手会降低验证失效的风险,应该只为每个输入点的输入内容制定一个有限的,刚好够用的合法范围,除此之外的所有内容都当做是非法的。而从“什么样的输入是不合法的”入手则会增加验证失效的可能,因为你不可能穷举非法的输入。
如何让IIS支持JSON
ExtJs的树,一般是由JSON对象生成的。如果用Apache服务器是没什么问题,如果用IIS问题就来了,无法正常载入.json文件中的数据
问题总是会有解决办法的,设置如下
1. MIME设置:
在IIS的站点属性的HTTP头设置里,选MIME 映射中点击”文件类型”-”新类型”,添加一个文件类型:
关联扩展名:*.json
内容类型(MIME):application/x-javascript
2. Script Map Handler设置:
还是在IIS的站点属性里,”主目录”-”应用程序设置”-”配置”-”映射”-”添加”,会打开”添加/编辑应用程序扩展名映射”的设置页面
扩展名:.json
运行文件:C:\WINDOWS\system32\inetsrv\asp.dll
动作:GET,POST
3.保存,重启IIS,应该就可以访问了。如果不行,就重启一下机子看看。
Google Code是怎么实现页面加载速度提高30%-70%的
相信很多接触到Web开发方面的人都知道Yahoo Developer Network的一篇文章 “Best Practices for Speeding Up Your Web Site” 我觉得这篇文章称作Web开发的圣经也不算过分,他们的34条铁律我几乎每隔几天都要温习一下并努力实践到自己的工作中。没有看到过这篇文章的人可以赶快 看一下 Best Practices for Speeding Up Your Web Site
在High Performance Web Sites这本书里(我也没看过),作者写到只有10%-20%的页面加载时间是下载HTML,另外的80%-90%的时间都是在下载页面的其他元素,我 想应该是指Image, Javascript, CSS等等。因为这些元素都是有单独的HTTP Request来加载的。而Best Practices for Speeding Up Your Web Site这篇文章的第一条铁律就是最大限度减少HTTP Request.
Google Code就是把精力集中在了减少那些”其他元素”的数量和大小,也就是减少Http Requests的数量,以下是他们进行的几项改进:
1. 合并减少网站的JavaScript和CSS文件
下载Javascript和CSS文件会阻碍其他部分页面的生成,Google Code团队把常用的Javascript和CSS文件分别合并成了一个文件,这样就把原本的20个文件合并成了两个,HTTP request的数量也从20个减低到了两个,而且他们也去掉了javascript和css文件中的不必要的空格然后把function和变量的名字都 改的很短。这个我相信,大家到google首页上点击右键看看google的网页源代码就知道google为了性能有多不择手段了。
2. 把经常使用的图片合并成一个
Google Code网站上本来有七个全站使用的图片文件,包括google code的logo, 页脚的googley balls和其他小图片。
虽然浏览器会并发的下载这些图片,但是google code还是把这些图片合并成了一个,这样就只有一个HTTP request了。然后显示的时候只显示这个大图片的一部分。例如原来的代码如下:
<img src=”/images/plus.gif” />
他 们给改成了:<div style=”background-image:url(/images/sprites.gif); background-position:-28px -246px; width:9px; height:9px”>&</div></span>
我觉得他们真是绞尽脑汁了,而且也不知道这样做是不是起到了效果,感觉CSS定位要显示哪一部分也需要时间的吧。
3. 为Google AJAX API的加载模块(google.load)实现lazy loading
关于Google AJAX API可以参考我的另外一篇blog 借用Google的Javascript API Loader来加速你的网站
Google Code肯定用他们自己家的东西了,不过他们也挑出来了一些小毛病,在这些Google AJAX APIs(例如Jquery, prototype等等) 初始化和使用之前,需要首先加google loader模块 (google.load), 通常情况下,google.load可以通过在head之间加入一些代码加载:
<script type=”text/javascript” src=”http://www.google.com/jsapi”></script>
通 常情况下这段代码都是正常工作的,但是在他们优化静态内容显示的性能的时候,这段代码会阻碍页面其他部分页面的生成,只有这个script加载完毕以后, 其他页面才能显示出来,所以google code就实现了这段代码的lazy loading,也就是只有在需要的时候才加载这段脚本。他们的实现方法:
1) 在<head>标签内,使用DOM脚本来实现只有需要的情况下才加载google.load
if (needToLoadGoogleAjaxApisLoaderModule) {
// Load Google AJAX APIs loader module (google.load)
var script = document.createElement(‘script’);
script.src = ‘http://www.google.com/jsapi?callback=googleLoadCallback’;
script.type = ‘text/javascript’;
document.getElementsByTagName(‘head’)[0].appendChild(script);
}
通过Google Code做得测试,他们的页面加载速度大大提高了30%-70%, 惊奇!看来他们提供的这些方法并不是鸡蛋里面挑骨头,而是大有必要实施在我们的项目中的。
从校内网的网页源码学到一点东西
知道校内网的UI是用Struts做的,查看了一下他们的网页源码,觉得质量挺高,至少代码写得挺规范的,下面这些是从他们网页源码里面看到的一些东西。
<meta http-equiv=”X-UA-Compatible” content=”IE=EmulateIE7″ />
这句代码是为了使浏览器使用IE7的strict模式来工作, 因为IE8使用了新的layout渲染引擎,所以会对以前版本的浏览器不兼容,所以IE8通过这种方式是浏览器按照IE7的模式运行,具体的可以通过搜索引擎了解,也可以看看这个链接的介绍
http://blogs.msdn.com/ie/archive/2008/06/10/introducing-ie-emulateie7.aspx
<meta name=”Keywords” content=”Xiaonei,校内,校内,大学,同学,同事,白领,个人主页,博客,相册,群组,社区,交友,聊天,音乐,视频,校园” />
这句代码应该是给搜索引擎用的,看来我也要在我自己的网站上加上这个了。
<link href=”http://xnimg.cn/102778/csspro/base/layout.css” rel=”stylesheet” type=”text/css” media=”all” />
这句代码是载入CSS文件,可以看出css文件是保存在另外一个服务器上的,这样可以分担服务器的压力。
<script type=”text/javascript” src=”http://xnimg.cn/93572/jspro/xn.widgets.js”></script>
这句是载入javascript文件,也是保存在另外一个服务器上的,同样也是为了分担服务器压力。
<li><a href=”http://class.xiaonei.com” style=”background-image: url(http://app.xnimg.cn/application/20080812/19/30 /L065930831445JIA.gif);”>班级</a></li>
这句代码可以看出,网页上的图片文件都是也是保存在不同服务器上的。
<IFRAME id=”p466″ MARGINHEIGHT=0 MARGINWIDTH=0 FRAMEBORDER=0 WIDTH=264 HEIGHT=60 SCROLLING=NO SRC=”http://gg.xiaonei.com/view.jsp?p=466″>
<NOSCRIPT><A HREF=”http://gg.xiaonei.com/direct.jsp?p=466″><IMG SRC=”http://gg.xiaonei.com/view.jsp?p=466″ WIDTH=264 HEIGHT=60 BORDER=0></a></NOSCRIPT></IFRAME>
没想到上面的横幅广告是用iframe做的,好像看了好多文章都不是很推荐用iframe。
<script src=”http://xnimg.cn/utm/urchin.js” type=”text/javascript”>
这个是嵌入的urchin统计代码, 看来校内也是用的google的统计
总体来看他们的代码写得挺优美,一点都不乱,值得我们学习。看过一些关于校内网架构方面的文章,准备研究一下。
Web性能优化的十个技巧
Patrick Killelea写了一本很畅销的书叫”Web Performance Tuning”, 里面很全面的介绍了web性能优化的方法和步骤。在web程序开发的过程中,很多项目都把很大的精力都用在了功能实现上,还有一部分用在了UI设计上,对于性能优化却是出了问题才考虑。其实应该从系统的需求和设计开始就着手进行性能的设计,而且放到跟功能一样的地位。
以下是这本书列出的top 10的性能优化技巧:
1. 使用weblint或者其他HTML 检查工具来检查HTML内容是不是符合HTML 4.0规范,符合HTML 4.0规范的页面会加载的更快。
2. 最小化Javascript和Style Sheets的使用,Javascript是不标准HTML内容的最大来源,虽然实现了很多非常炫的效果但是却放缓了页面加载的时间,Style Sheets是需要在页面显示之前单独下载的,所以也会放缓页面的加载速度。
3. 关闭DNS的反向解析,DNS反向解析会记录客户端的计算机名而不仅仅是IP地址, 这样就增加消耗。
4. 使用统计工具来检查你的web系统的性能瓶颈是出在DNS,网络连接,内容大小或者是服务器端,这样就可以从瓶颈处着手提高性能。
5. 使用简单的servlet或者CGI, 在系统不需要的话使用分布式程序反而会减低性能。
6. 加内存, 跟我们使用的电脑一样,加内存往往是成本最低效果最好的提高性能的方法。要知道内存速度比硬盘速度要搞一个数量级的。
7. 合理的给你的数据库加索引,当根据关键字进行全表查询时,加索引会有效的提高查询性能。
8. 最小化数据库查询,如果能把数据缓存到中间层或者servlet的话,just do it, 数据库连接往往是系统的性能瓶颈。
9. 使用网络工具检查网络丢包和重发, 断断续续的系统性能问题一般是因为网络丢包或者干扰。因为丢包和重新发送数据之间有一个时间间隔,这样就会使系统变得缓慢。
10. 使用工具来实时监视网站的性能。
迟到的工作笔记_<textarea>强制回车(2006-12-28)
例如有一个<textarea>,如果用户没有及时在某一行的末尾添加回车的话,
那么从数据库取出,并显示出来的时候,所有的东西全部显示在一行,要
想让他自动判断:如果用户输入的某行内容超出了这个<textarea>的宽度,
就自动在超出的那个部分添加一个硬回车”\r\n”。
就要对<textarea>这样设置
<textarea wrap=”hard”>
HTTP错误代码详细介绍
“100″ : Continue
“101″ : witching Protocols
“200″ : OK
“201″ : Created
“202″ : Accepted
“203″ : Non-Authoritative Information
“204″ : No Content
“205″ : Reset Content
“206″ : Partial Content
“300″ : Multiple Choices
“301″ : Moved Permanently
“302″ : Found
“303″ : See Other
“304″ : Not Modified
“305″ : Use Proxy
“307″ : Temporary Redirect
HTTP 400 – 请求无效
HTTP 401.1 – 未授权:登录失败
HTTP 401.2 – 未授权:服务器配置问题导致登录失败
HTTP 401.3 – ACL 禁止访问资源
HTTP 401.4 – 未授权:授权被筛选器拒绝
HTTP 401.5 – 未授权:ISAPI 或 CGI 授权失败
HTTP 403 – 禁止访问
HTTP 403 – 对 Internet 服务管理器 (HTML) 的访问仅限于 Localhost
HTTP 403.1 禁止访问:禁止可执行访问
HTTP 403.2 – 禁止访问:禁止读访问
HTTP 403.3 – 禁止访问:禁止写访问
HTTP 403.4 – 禁止访问:要求 SSL
HTTP 403.5 – 禁止访问:要求 SSL 128
HTTP 403.6 – 禁止访问:IP 地址被拒绝
HTTP 403.7 – 禁止访问:要求客户证书
HTTP 403.8 – 禁止访问:禁止站点访问
HTTP 403.9 – 禁止访问:连接的用户过多
HTTP 403.10 – 禁止访问:配置无效
HTTP 403.11 – 禁止访问:密码更改
HTTP 403.12 – 禁止访问:映射器拒绝访问
HTTP 403.13 – 禁止访问:客户证书已被吊销
HTTP 403.15 – 禁止访问:客户访问许可过多
HTTP 403.16 – 禁止访问:客户证书不可信或者无效
HTTP 403.17 – 禁止访问:客户证书已经到期或者尚未生效
HTTP 404.1 – 无法找到 Web 站点
HTTP 404 – 无法找到文件
HTTP 405 – 资源被禁止
HTTP 406 – 无法接受
HTTP 407 – 要求代理身份验证
HTTP 410 – 永远不可用
HTTP 412 – 先决条件失败
HTTP 414 – 请求 – URI 太长
HTTP 500 – 内部服务器错误
HTTP 500.100 – 内部服务器错误 – ASP 错误
HTTP 500-11 服务器关闭
HTTP 500-12 应用程序重新启动
HTTP 500-13 – 服务器太忙
HTTP 500-14 – 应用程序无效
HTTP 500-15 – 不允许请求 global.asa
Error 501 – 未实现
HTTP 502 – 网关错误
13px的汉字比14px的还要大?
今天在调整blog模板的时候发现,13px的汉字竟然比14px的还要大?!!!
经查证:原来是Tahoma这个字体不能设置为13像素大小,改用其他字体就可以解决了
Yahoo网站性能最佳体验的34条黄金守则
Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践。他们为此进行了一系列的实验、开发了各种工具、写了大量的文章和博客并在各种会议上参与探讨。最佳实践的核心就是旨在提高网站性能。
Excetional Performance团队总结出了一系列可以提高网站速度的方法。可以分为7大类34条。包括内容、服务器、cookie、CSS、JavaScript、图片、移动应用等七部分。
其中内容部分一共十条建议:
一、内容部分
- 尽量减少HTTP请求
- 减少DNS查找
- 避免跳转
- 缓存Ajxa
- 推迟加载
- 提前加载
- 减少DOM元素数量
- 用域名划分页面内容
- 减小iframe的大小
- 避免404错误
1、尽量减少HTTP请求次数
终端用户响应的时间中,有80%用于下载各项内容。这部分时间包括下载页面中的图像、样式表、脚本、Flash等。通过减少页面中的元素可以减少HTTP请求的次数。这是提高网页速度的关键步骤。
减少页面组件的方法其实就是简化页面设计。那么有没有一种方法既能保持页面内容的丰富性又能达到加快响应时间的目的呢?这里有几条减少HTTP请求次数同时又可能保持页面内容丰富的技术。
合并文件是通过把所有的脚本放到一个文件中来减少HTTP请求的方法,如可以简单地把所有的CSS文件都放入一个样式表中。当脚本或者样式表在不同页面中使用时需要做不同的修改,这可能会相对麻烦点,但即便如此也要把这个方法作为改善页面性能的重要一步。
CSS Sprites是减少图像请求的有效方法。把所有的背景图像都放到一个图片文件中,然后通过CSS的background-image和background-position属性来显示图片的不同部分;
图片地图是把多张图片整合到一张图片中。虽然文件的总体大小不会改变,但是可以减少HTTP请求次数。图片地图只有在 图片的所有组成部分在页面中是紧挨在一起的时候才能使用,如导航栏。确定图片的坐标和可能会比较繁琐且容易出错,同时使用图片地图导航也不具有可读性,因 此不推荐这种方法;
内联图像是使用data:URL scheme的方法把图像数据加载页面中。这可能会增加页面的大小。把内联图像放到样式表(可缓存)中可以减少HTTP请求同时又避免增加页面文件的大小。但是内联图像现在还没有得到主流浏览器的支持。
减少页面的HTTP请求次数是你首先要做的一步。这是改进首次访问用户等待时间的最重要的方法。如同Tenni Theurer的他的博客Browser Cahe Usage – Exposed!中所说,HTTP请求在无缓存情况下占去了40%到60%的响应时间。让那些初次访问你网站的人获得更加快速的体验吧!
2、减少DNS查找次数
域名系统(DNS)提供了域名和IP的对应关系,就像电话本中人名和他们的电话号码的关系一样。当你在浏览器地址栏中输入http://www.kuqin.com/ 时,DNS解析服务器就会返回这个域名对应的IP地址。DNS解析的过程同样也是需要时间的。一般情况下返回给定域名对应的IP地址会花费20到120毫秒的时间。而且在这个过程中浏览器什么都不会做直到DNS查找完毕。
缓存DNS查找可以改善页面性能。这种缓存需要一个特定的缓存服务器,这种服务器一般属于用户的ISP提供商或者本地局域网控制,但是它同样会在用户使用 的计算机上产生缓存。DNS信息会保留在操作系统的DNS缓存中(微软Windows系统中DNS Client Service)。大多数浏览器有独立于操作系统以外的自己的缓存。由于浏览器有自己的缓存记录,因此在一次请求中它不会受到操作系统的影响。
Internet Explorer默认情况下对DNS查找记录的缓存时间为30分钟,它在注册表中的键值为DnsCacheTimeout。Firefox对DNS的查找 记录缓存时间为1分钟,它在配置文件中的选项为network.dnsCacheExpiration(Fasterfox把这个选项改为了1小时)。
当客户端中的DNS缓存都为空时(浏览器和操作系统都为空),DNS查找的次数和页面中主机名的数量相同。这其中包括页面中URL、图片、脚本文件、样式表、Flash对象等包含的主机名。减少主机名的数量可以减少DNS查找次数。
减少主机名的数量还可以减少页面中并行下载的数量。减少DNS查找次数可以节省响应时间,但是减少并行下载却会增加响应时间。我的指导原则是把这些页面中 的内容分割成至少两部分但不超过四部分。这种结果就是在减少DNS查找次数和保持较高程度并行下载两者之间的权衡了。
3、避免跳转
跳转是使用301和302代码实现的。下面是一个响应代码为301的HTTP头:
HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/html
浏览器会把用户指向到Location中指定的URL。头文件中的所有信息在一次跳转中都是必需的,内容部分可以为空。不管他们的名称,301和302响 应都不会被缓存除非增加一个额外的头选项,如Expires或者Cache-Control来指定它缓存。<meat />元素的刷新标签和JavaScript也可以实现URL的跳转,但是如果你必须要跳转的时候,最好的方法就是使用标准的3XXHTTP状态代 码,这主要是为了确保“后退”按钮可以正确地使用。
但是要记住跳转会降低用户体验。在用户和HTML文档中间增加一个跳转,会拖延页面中所有元素的显示,因为在HTML文件被加载前任何文件(图像、Flash等)都不会被下载。
有一种经常被网页开发者忽略却往往十分浪费响应时间的跳转现象。这种现象发生在当URL本该有斜杠(/)却被忽略掉时。例如,当我们要访问http: //astrology.yahoo.com/astrology 时,实际上返回的是一个包含301代码的跳转,它指向的是http://astrology.yahoo.com/astrology/ (注意末尾的斜杠)。在Apache服务器中可以使用Alias 或者 mod_rewrite或者the DirectorySlash来避免。
连接新网站和旧网站是跳转功能经常被用到的另一种情况。这种情况下往往要连接网站的不同内容然后根据用户的不同类型(如浏览器类型、用户账号所属类型)来 进行跳转。使用跳转来实现两个网站的切换十分简单,需要的代码量也不多。尽管使用这种方法对于开发者来说可以降低复杂程度,但是它同样降低用户体验。一个 可替代方法就是如果两者在同一台服务器上时使用Alias和mod_rewrite和实现。如果是因为域名的不同而采用跳转,那么可以通过使用Alias 或者mod_rewirte建立CNAME(保存一个域名和另外一个域名之间关系的DNS记录)来替代。
4、可缓存的AJAX
Ajax经常被提及的一个好处就是由于其从后台服务器传输信息的异步性而为用户带来的反馈的即时性。但是,使用Ajax并不能保证用户不会在等待异步的 JavaScript和XML响应上花费时间。在很多应用中,用户是否需要等待响应取决于Ajax如何来使用。例如,在一个基于Web的Email客户端 中,用户必须等待Ajax返回符合他们条件的邮件查询结果。记住一点,“异步”并不异味着“即时”,这很重要。
为了提高性能,优化Ajax响应是很重要的。提高Ajxa性能的措施中最重要的方法就是使响应具有可缓存性,具体的讨论可以查看Add an Expires or a Cache-Control Header。其它的几条规则也同样适用于Ajax:
Gizp压缩文件
减少DNS查找次数
精简JavaScript
避免跳转
配置ETags
让我们来看一个例子:一个Web2.0的Email客户端会使用Ajax来自动完成对用户地址薄的下载。如果用户在上次使用过Email web应用程序后没有对地址薄作任何的修改,而且Ajax响应通过Expire或者Cacke-Control头来实现缓存,那么就可以直接从上一次的缓 存中读取地址薄了。必须告知浏览器是使用缓存中的地址薄还是发送一个新的请求。这可以通过为读取地址薄的Ajax URL增加一个含有上次编辑时间的时间戳来实现,例如,&t=11900241612等。如果地址薄在上次下载后没有被编辑过,时间戳就不变,则 从浏览器的缓存中加载从而减少了一次HTTP请求过程。如果用户修改过地址薄,时间戳就会用来确定新的URL和缓存响应并不匹配,浏览器就会重要请求更新 地址薄。
即使你的Ajxa响应是动态生成的,哪怕它只适用于一个用户,那么它也应该被缓存起来。这样做可以使你的Web2.0应用程序更加快捷。
5、推迟加载内容
你可以仔细看一下你的网页,问问自己“哪些内容是页面呈现时所必需首先加载的?哪些内容和结构可以稍后再加载?
把整个过程按照onload事件分隔成两部分,JavaScript是一个理想的选择。例如,如果你有用于实现拖放和动画的JavaScript,那么它 就以等待稍后加载,因为页面上的拖放元素是在初始化呈现之后才发生的。其它的例如隐藏部分的内容(用户操作之后才显现的内容)和处于折叠部分的图像也可以 推迟加载
工具可以节省你的工作量:YUI Image Loader可以帮你推迟加载折叠部分的图片,YUI Get utility是包含JS和 CSS的便捷方法。比如你可以打开Firebug的Net选项卡看一下Yahoo的首页。
当性能目标和其它网站开发实践一致时就会相得益彰。这种情况下,通过程序提高网站性能的方法告诉我们,在支持JavaScript的情况下,可以先去除用 户体验,不过这要保证你的网站在没有JavaScript也可以正常运行。在确定页面运行正常后,再加载脚本来实现如拖放和动画等更加花哨的效果。
6、预加载
预加载和后加载看起来似乎恰恰相反,但实际上预加载是为了实现另外一种目标。预加载是在浏览器空闲时请求将来可能会用到的页面内容(如图像、样式表和脚 本)。使用这种方法,当用户要访问下一个页面时,页面中的内容大部分已经加载到缓存中了,因此可以大大改善访问速度。
下面提供了几种预加载方法:
无条件加载:触发onload事件时,直接加载额外的页面内容。以Google.com为例,你可以看一下它的spirit image图像是怎样在onload中加载的。这个spirit image图像在google.com主页中是不需要的,但是却可以在搜索结果页面中用到它。
有条件加载:根据用户的操作来有根据地判断用户下面可能去往的页面并相应的预加载页面内容。在search.yahoo.com中你可以看到如何在你输入内容时加载额外的页面内容。
有预期的加载:载入重新设计过的页面时使用预加载。这种情况经常出现在页面经过重新设计后用户抱怨“新的页面看起来很 酷,但是却比以前慢”。问题可能出在用户对于你的旧站点建立了完整的缓存,而对于新站点却没有任何缓存内容。因此你可以在访问新站之前就加载一部内容来避 免这种结果的出现。在你的旧站中利用浏览器的空余时间加载新站中用到的图像的和脚本来提高访问速度。
7、减少DOM元素数量
一个复杂的页面意味着需要下载更多数据,同时也意味着JavaScript遍历DOM的效率越慢。比如当你增加一个事件句柄时在500和5000个DOM元素中循环效果肯定是不一样的。
大量的DOM元素的存在意味着页面中有可以不用移除内容只需要替换元素标签就可以精简的部分。你在页面布局中使用表格了吗?你有没有仅仅为了布局而引入更多的<div>元素呢?也许会存在一个适合或者在语意是更贴切的标签可以供你使用。
YUI CSS utilities可以给你的布局带来巨大帮助:grids.css可以帮你实现整体布局,font.css和reset.css可以帮助你移除浏览器默 认格式。它提供了一个重新审视你页面中标签的机会,比如只有在语意上有意义时才使用<div>,而不是因为它具有换行效果才使用它。
DOM元素数量很容易计算出来,只需要在Firebug的控制台内输入:
document.getElementsByTagName(‘*’).length
那么多少个DOM元素算是多呢?这可以对照有很好标记使用的类似页面。比如Yahoo!主页是一个内容非常多的页面,但是它只使用了700个元素(HTML标签)。
8、根据域名划分页面内容
把页面内容划分成若干部分可以使你最大限度地实现平行下载。由于DNS查找带来的影响你首先要确保你使用的域名数量在2个到4个之间。例如,你可以把用到 的HTML内容和动态内容放在www.example.org上,而把页面各种组件(图片、脚本、CSS)分别存放在 statics1.example.org和statics.example.org上。
你可在Tenni Theurer和Patty Chi合写的文章Maximizing Parallel Downloads in the Carpool Lane找到更多相关信息。
9、使iframe的数量最小
ifrmae元素可以在父文档中插入一个新的HTML文档。了解iframe的工作理然后才能更加有效地使用它,这一点很重要。
<iframe>优点:
- 解决加载缓慢的第三方内容如图标和广告等的加载问题
- Security sandbox
- 并行加载脚本
<iframe>的缺点:
- 即时内容为空,加载也需要时间
- 会阻止页面加载
- 没有语意
10、不要出现404错误
HTTP请求时间消耗是很大的,因此使用HTTP请求来获得一个没有用处的响应(例如404没有找到页面)是完全没有必要的,它只会降低用户体验而不会有一点好处。
有些站点把404错误响应页面改为“你是不是要找***”,这虽然改进了用户体验但是同样也会浪费服务器资源(如数据库等)。最糟糕的情况是指向外部 JavaScript的链接出现问题并返回404代码。首先,这种加载会破坏并行加载;其次浏览器会把试图在返回的404响应内容中找到可能有用的部分当 作JavaScript代码来执行。
二,服务器
在本系列的第一节中,讲了提高网站性能中网站“内容”有关的10条原则。除了在网站在内容上的改进外,在网站服务器端上也有需要注意和改进的地方,它们包括:
- 使用内容分发网络
- 为文件头指定Expires或Cache-Control
- Gzip压缩文件内容
- 配置ETag
- 尽早刷新输出缓冲
- 使用GET来完成AJAX请求
… <!– css, js –>
</head>
<?php flush(); ?>
<body>
… <!– content –>
为了证明使用这项技术的好处,Yahoo!搜索率先研究并完成了用户测试。
三、JavaScript和CSS
在第一部分和第二部分中我们分别介绍了改善网站性能中页面内容和服务器的几条守则,除此之外,JavaScript和CSS也是我们页面中经常用到的内容,对它们的优化也提高网站性能的重要方面:
CSS:
- 把样式表置于顶部
- 避免使用CSS表达式(Expression)
- 使用外部JavaScript和CSS
- 削减JavaScript和CSS
- 用<link>代替@import
- 避免使用滤镜
JavaScript
- 把脚本置于页面底部
- 使用外部JavaScript和CSS
- 削减JavaScript和CSS
- 剔除重复脚本
- 减少DOM访问
- 开发智能事件处理程序
18、避免使用CSS表达式(Expression)
CSS表达式是动态设置CSS属性的强大(但危险)方法。Internet Explorer从第5个版本开始支持CSS表达式。下面的例子中,使用CSS表达式可以实现隔一个小时切换一次背景颜色:
background-color: expression( (new Date()).getHours()%2 ? “#B8D4FF” : “#F08A00″ );
如上所示,expression中使用了JavaScript表达式。CSS属性根据JavaScript表达式的计算结果来设置。expression方法在其它浏览器中不起作用,因此在跨浏览器的设计中单独针对Internet Explorer设置时会比较有用。
表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给CSS表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到10000次以上的计算量。
一个减少CSS表达式计算次数的方法就是使用一次性的表达式,它在第一次运行时将结果赋给指定的样式属性,并用这个属性来代替CSS表达式。如果样式属性 必须在页面周期内动态地改变,使用事件句柄来代替CSS表达式是一个可行办法。如果必须使用CSS表达式,一定要记住它们要计算成千上万次并且可能会对你 页面的性能产生影响。
21、用<link>代替@import
前面的最佳实现中提到CSS应该放置在顶端以利于有序加载呈现。
在IE中,页面底部@import和使用<link>作用是一样的,因此最好不要使用它。
25、减少DOM访问
使用JavaScript访问DOM元素比较慢,因此为了获得更多的应该页面,应该做到:
有关此方面的更多信息请查看Julien Lecomte在YUI专题中的文章“高性能Ajax应该程序”。
四、图片、Coockie与移动应用
我们在前面的几节中分别讲了提高网站性能中内容、服务器、JavaScript和CSS等方面的内容。除此之外,图片和Coockie也是我们网站中几乎不可缺少组成部分,此外随着移动设备的流行,对于移动应用的优化也十分重要。这主要包括:
Coockie:
- 减小Cookie体积
- 对于页面内容使用无coockie域名
图片:
- 优化图像
- 优化CSS Spirite
- 不要在HTML中缩放图像
- favicon.ico要小而且可缓存
移动应用:
- 保持单个内容小于25K
- 打包组件成复合文本
27、减小Cookie体积
HTTP coockie可以用于权限验证和个性化身份等多种用途。coockie内的有关信息是通过HTTP文件头来在web服务器和浏览器之间进行交流的。因此保持coockie尽可能的小以减少用户的响应时间十分重要。
有关更多信息可以查看Tenni Theurer和Patty Chi的文章“When the Cookie Crumbles”。这们研究中主要包括:
- 去除不必要的coockie
- 使coockie体积尽量小以减少对用户响应的影响
- 注意在适应级别的域名上设置coockie以便使子域名不受影响
- 设置合理的过期时间。较早地Expire时间和不要过早去清除coockie,都会改善用户的响应时间。
28、对于页面内容使用无coockie域名
当浏览器在请求中同时请求一张静态的图片和发送coockie时,服务器对于这些coockie不会做任何地使用。因此他们只是因为某些负面因素而创建的 网络传输。所有你应该确定对于静态内容的请求是无coockie的请求。创建一个子域名并用他来存放所有静态内容。
如果你的域名是www.example.org,你可以在static.example.org上存在静态内容。但是,如果你不是在 www.example.org上而是在顶级域名example.org设置了coockie,那么所有对于static.example.org的请求 都包含coockie。在这种情况下,你可以再重新购买一个新的域名来存在静态内容,并且要保持这个域名是无coockie的。Yahoo!使用的是 ymig.com,YouTube使用的是ytimg.com,Amazon使用的是images-anazon.com等等。
使用无coockie域名存在静态内容的另外一个好处就是一些代理(服务器)可能会拒绝对coockie的内容请求进行缓存。一个相关的建议就是,如果你 想确定应该使用example.org还是www.example.org作为你的一主页,你要考虑到coockie带来的影响。忽略掉www会使你除了 把coockie设置到*.example.org(*是泛域名解析,代表了所有子域名译者dudo注)外没有其它选择,因此出于性能方面的考虑最好是使 用带有www的子域名并且在它上面设置coockie。
29、优化图像
设计人员完成对页面的设计之后,不要急于将它们上传到web服务器,这里还需要做几件事:
- 你可以检查一下你的GIF图片中图像颜色的数量是否和调色板规格一致。 使用imagemagick中下面的命令行很容易检查:
identify -verbose image.gif
如果你发现图片中只用到了4种颜色,而在调色板的中显示的256色的颜色槽,那么这张图片就还有压缩的空间。 - 尝 试把GIF格式转换成PNG格式,看看是否节省空间。大多数情况下是可以压缩的。由于浏览器支持有限,设计者们往往不太乐意使用PNG格式的图片,不过这 都是过去的事情了。现在只有一个问题就是在真彩PNG格式中的alpha通道半透明问题,不过同样的,GIF也不是真彩格式也不支持半透明。因此GIF能 做到的,PNG(PNG8)同样也能做到(除了动画)。下面这条简单的命令可以安全地把GIF格式转换为PNG格式:
convert image.gif image.png
“我们要说的是:给PNG一个施展身手的机会吧!” - 在所有的PNG图片上运行pngcrush(或者其它PNG优化工具)。例如:
pngcrush image.png -rem alla -reduce -brute result.png - 在所有的JPEG图片上运行jpegtran。这个工具可以对图片中的出现的锯齿等做无损操作,同时它还可以用于优化和清除图片中的注释以及其它无用信息(如EXIF信息):
jpegtran -copy none -optimize -perfect src.jpg dest.jpg
- 在Spirite中水平排列你的图片,垂直排列会稍稍增加文件大小;
- Spirite中把颜色较近的组合在一起可以降低颜色数,理想状况是低于256色以便适用PNG8格式;
- 便于移动,不要在Spirite的图像中间留有较大空隙。这虽然不大会增加文件大小但对于用户代理来说它需要更少的内存来把图片解压为像素地图。100×100的图片为1万像素,而1000×1000就是100万像素。
31、不要在HTML中缩放图像
不要为了在HTML中设置长宽而使用比实际需要大的图片。如果你需要:
<img width=”100″ height=”100″ src=”mycat.jpg” alt=”My Cat” />
那么你的图片(mycat.jpg)就应该是100×100像素而不是把一个500×500像素的图片缩小使用。
32、favicon.ico要小而且可缓存
favicon.ico是位于服务器根目录下的一个图片文件。它是必定存在的,因为即使你不关心它是否有用,浏览器也会对它发出请求,因此最好不要返回一 个404 Not Found的响应。由于是在同一台服务器上,它每被请求一次coockie就会被发送一次。这个图片文件还会影响下载顺序,例如在IE中当你在 onload中请求额外的文件时,favicon会在这些额外内容被加载前下载。
因此,为了减少favicon.ico带来的弊端,要做到:
- 文件尽量地小,最好小于1K
- 在适当的时候(也就是你不要打算再换favicon.ico的时候,因为更换新文件时不能对它进行重命名)为它设置Expires文件头。你可以很安全地把Expires文件头设置为未来的几个月。你可以通过核对当前favicon.ico的上次编辑时间来作出判断。
33、保持单个内容小于25K
这条限制主要是因为iPhone不能缓存大于25K的文件。注意这里指的是解压缩后的大小。由于单纯gizp压缩可能达不要求,因此精简文件就显得十分重要。
查看更多信息,请参阅Wayne Shea和Tenni Theurer的文件“Performance Research, Part 5: iPhone Cacheability – Making it Stick”。
34、打包组件成复合文本
把页面内容打包成复合文本就如同带有多附件的Email,它能够使你在一个HTTP请求中取得多个组件(切记:HTTP请求是很奢侈的)。当你使用这条规则时,首先要确定用户代理是否支持(iPhone就不支持)。