`

从30秒到3秒

    博客分类:
  • read
阅读更多
2006年10月份,我开始对web开发产生了兴趣,并决定自己也尝试开发一个网站。在此之前,我做过3年的java application的开发,对web开发应该算一无所知。在比较了java,php,ror,和python后,我选择了基于python的web框架 - django 。到目前为止,我还认为这是一个明智的决定。Django高效的开发效率让我仅仅用一个月的业余时间,就基本完成了网站的开发。这是一个网络书签的网站,我加上了一些有意思的特性,让网站显得有些与众不同。

我购买了域名和Dreamhost 的主机空间。Dreamhost支持django,并且第一年的费用只有180元人民币。2006年11月份,http://www.hpbookmarks.com 上线了。网友们发来了善意的评论,“很有创意”,“点意思”,“一些feature很不错”。同时,还有一个非常一致的意见就是,“访问速度太慢了”。其实,当时的情况不只是访问速度慢,而且是相当不稳定。很多时候是几个小时网站无法访问。当时,我并没有在意,因为我有两个自以为“合理”的解释。第一,我用的是国外最便宜的虚拟主机,国内访问慢是很正常的。第二,django的还处于0.95的状态,效率和稳定性方面有问题也正常。

但是,我慢慢发现上面的解释不过是自己骗自己的借口。很多用dreamhost的网站,访问起来也很快。而且django也已经被成功应用在许多大型的网站。我开始认真考虑提高网站速度的问题了。毕竟,速度慢的网站很可能在第一次就失去的用户,他们可以永远不会再来了。终于,我进行了下面一步一步的优化工作,并且取得了一个看起来还不错的结果。

第一步,用Ajax提高用户体验

由于我的网站上链接字体的大小是根据点击次数决定,所以每次点击都要提交到服务器端并记录次数,再在客户端打开网站链接。这在localhost测试的时候没有发现问题,但是部署到服务器上,会感到明显的等待。解决办法就是用Ajax。用户点击网站链接后就直接打开,再通过Ajax将点击的事件提交到服务器端记录。这样用户感觉不到任何延时。

第二步,将逻辑移到客户端的javascript中

在开始的时候,“网站标签高亮”和“手气不错”的功能都是提交到服务器端操作,然后返回结果的。后来,我发现其实很多逻辑是可以移到客户端,由 javascript来实现的。Javascript非常强大,可以完成很多复杂的逻辑。将逻辑移到客户端的javascript中,可以很有效的减少和服务器通讯的次数,获得更好的访问速度。

第三步,解决进程的

由于采用的是fastCGI的方式,我配置了 django.fcgi。可是,我发现系统进程中,有大量的django.fcgi进程被标记为 < defunct>(失去功能)。这些进程会导致服务器有时无法正常访问。我开始尝试用命令来kill掉这些进程,但是很快发现这无法从根本上解决问题。后来,我看到一个老外在blog上提到一个解决方案,将django.fcgi改名为dispatch.fcgi。原来,dispatch.fcgi 是一个dreamhost的系统进程,它的健壮性是可以得到保障的。果然,我将django.fcgi改名为 dispatch.fcgi后,的现象再没有出现。

第四步,优化SQL语句

SQL语句的执行通常也是一个很花费时间的操作。经过检查,我发现我的一条SQL语句,是一个嵌套三层的子表查询。而这条SQL还必须是一个Raw SQL,即不能采用django的OR Maping。这意味着不能被cache缓存,每次都是真刀真枪的执行。更失败的是,经过我的分析,这条SQL完全可以不执行。这是一次设计上的失误,标
准的over design(过渡设计)。当时,我是想通过数据库得到一个最精确的统计值。后来发现,这个值完全可以用一个近似的常量代替。优化SQL,尤其是避免不必要的SQL执行,带来的效果是非常明显的。

第五步,尽量减少页面大小

随着添加网站越来越多,有一天我发现django生成的首页已经达到了80k。我很清楚这是一个非常不能被接受的数字。我开始检查页面,很快发现了线索。第一,因为偷懒,页面中很多layout是用空格( )实现的。第二,因为为了增加代码可读行,调试方便,每行生成的页面都增加换行符 (\n)。第三,最糟糕的是,大量的用了
inline css。就是将css style直接嵌入标记块中。于是,我立即动手,用css的align解决layout,去掉\n,将inline css抽象到独立的css文件中。这样下来,在不更改任何内容的情况下,80k变成了57k。(补充:由于网站链接大部分是打开新窗口,所以用了大量的 target=_blank。在ylsdd的提示下,在html的head里增加了,又节约了4k。)

第六步,用gzip进行页面压缩

当我兴高采烈的把页面优化结果贴到了smth bbs上,却被直接泼了盆凉水。原来百分之二十几的优化结果,实在太一般了。ylsdd给我了一个很重要的线索,deflate。原来apache的 deflate模块可以把文件进行gzip压缩,压缩后的文件传到浏览器后再被解压。主流的浏览器都支持这种gzip的解压操作。于是,我在apache 的配置文
件中加入了Add OutputFilter DEFAULT html css js的语句。经过测试,css,js这些文本文件的压缩后都只有原来尺寸的25%。这里,和大家分享一个网站 http://www.port80software.com/products/httpzip/compresscheck 它的作用是检测你的网站是否被压缩,以及压缩比率等。

第七步,回归静态页面

新的问题又来了。原来deflate只支持静态文件的压缩。而我的首页是django动态生成的,deflate模块没有进行压缩。我突然想到,网站的首页为什么不能是静态页面呢?于是,我增加了一个runtime的api,这个api提供的是和原来一样由django动态生成的页面。我又写了一个 python的程序,通过urllib2模块下载这个动态生成的页面,并保存为index.html。我将网站的root映射到index.html这个静态页面。最后,通过linux crontab定义一个行为,每五分钟执行一下这个python程序,生成新的index.html。值得一提的是,由于网络原因,python程序不一定每次都能准确完整的下载动态生成的页面。所以我们必须再进行一个校验算法。当页面大小要超过一定数字,页面中出现某个校验字符串的情况下,才保存 index.html。这样,每次用户提交的访问,不是由服务器端动态生成页面,极大的节省了服务器端的开销。而静态页面又可以有效的被deflate压缩。最后结果,首页被压缩为13k,为原来的22%。唯一的区别就是,新提交和推荐的网站不能立即出现在首页。但是我认为,这应该是可以被接受的。

至此,网站的优化工作基本完成。网站的访问速度从原来30秒以上,缩短到3秒左右,应该说算是一个飞跃。虽然,3秒的速度也不是非常快,但是,考虑到虚拟主机等客观原因,这个结果我还是满意的。原来感觉我的网站很慢的朋友们,也可以再试试。

以上的优化方案出自我的个人经验,并不一定适合所有网站。但是,它告诉我们一个事实。影响网站访问速度的不仅仅是服务器配置,网络带宽。也许,你糟糕的设计,低效率的方案也是致命的因素。应当注意的是,优化工作也不能匆匆上手。一定要仔细研究,具体情况具体分析,得到统计数据,找到真正的问题所在,再开始优化。相信自己,提高网站的访问速度并不是不可能。毕竟,Nothing is Impossible。祝大家成功。

  来自  http://web.hangyequan.com/bbs/board-3347.html
分享到:
评论

相关推荐

    篮球比赛30秒计时器

    (3)计数器为三十秒递减计时,计时间隔为时间单位一秒。 当电路工作时,由555定时器组成多谐振荡器,选取适当的电容使震荡周期为1s。 (4)计时器递减计时到0的时候且灭灯后,有指示灯亮起表示报警信号的发生。 ...

    篮球30秒计数器

    【篮球30秒计数器】是一个用于模拟篮球比赛中24秒进攻时间限制的计时设备。这个设计主要是为了满足体育赛事中对于时间管理的需求,尤其是篮球比赛中对24秒违例规则的执行。计时器需具备清晰的倒计时显示、启动/暂停...

    30秒计时器

    【30秒计时器】和【Proteus计时器】这两个关键词涉及到的是一个基于Proteus软件的电子设计项目,具体是一个篮球竞赛用的30秒倒计时计时器的仿真设计。Proteus是一款强大的电子设计自动化(EDA)软件,尤其在电路仿真、...

    30秒八位抢答器

    30秒八位抢答器 51单片机 1.数字抢答器设计 设计任务与要求(基本功能) (1)抢答器同时供4名选手或4个代表队比赛,分别用4个按钮S0 ~ S3表示; (2)设置一个系统清除和抢答控制开关S,该开关由主持人控制; (3)...

    篮球30秒计时器

    篮球30秒计时器是一种专门用于篮球竞赛的电子设备,设计目的是为了精确计时篮球比赛中的特定30秒规则。计时器需具备显示时间、清零、启动/暂停以及报警功能。以下是对该计时器设计的技术要求、所需元件和工作原理的...

    数字电子技术基础课程设计篮球30秒计时器

    【篮球30秒计时器】是一个基于数字电子技术的基础课程设计项目,旨在模拟篮球比赛中30秒进攻时限的计时功能。这个计时器具备显示30秒计时、外部操作控制(如置数、清零、启动、暂停)、1秒递减计时以及倒计时结束时...

    篮球30秒计时器电路multisim13仿真源文件.zip

    3. **计数器**:用于计数分频后的脉冲,随着脉冲的增加,计数值逐渐递增,直到达到30秒的时间点。 4. **显示驱动**:通常使用LED数码管或LCD显示器显示剩余时间,驱动电路会根据计数器的输出驱动显示器,显示0到30...

    用multisim仿真的30秒计数器

    这是一个用multisim仿真的三十秒计数器,可以实现从三十开始倒数到一,用了两块7448N芯片和两块74192N芯片等。

    单片机 30秒倒计时 报警

    本例中,我们看到的是一个基于单片机实现的30秒倒计时报警系统,它主要由以下几个部分组成: 1. **硬件基础**:首先,这个程序是针对一款基于8051系列的单片机设计的,因为代码中包含了`#include &lt;reg51.h&gt;`,这是...

    无声音频文件,三种格式mp3,ogg,wav,1秒~30秒时长

    本次分享的主题聚焦于“无声音频文件”,其中包括了三种常见的音频格式:MP3、OGG和WAV,覆盖了1秒到30秒的不同时长。这些文件可能用于测试、调试或作为背景音乐的空白模板。下面我们将详细探讨这三个音频格式以及...

    篮球竞赛30秒计时器

    篮球竞赛 30 秒计时器 本课程设计是脉冲数字电路的简单应用,设计了篮球竞赛 30 秒计时器。此计时器功能齐全,可以直接清零、启动、暂停和连续,以及具有光电报警功能,同时应用了七段数码管来显示时间。此计时器有...

    篮球竞赛30秒计时器报告

    通过此类项目,学生可以亲身体验从概念到产品的全过程,这对于提升其工程素养和解决实际问题的能力至关重要。 #### 知识点五:仿真软件在电路设计中的作用 在篮球竞赛30秒计时器的开发过程中,EWB5.12仿真软件扮演...

    traffic_light_vhdl_vhdl写计时30秒_交通灯_

    本项目利用VHDL编写了一个实现30秒倒计时功能的交通灯系统,适用于十字路口的交通控制。下面将详细介绍这个交通灯控制系统的设计原理、关键模块和实现过程。 首先,交通灯系统的基本要求是具有红、绿、黄三种颜色的...

    两个无声MP3,一个30秒,一个120秒

    这里我们探讨的主题是“两个无声MP3,一个30秒,一个120秒”。这可能指的是两个没有声音内容的MP3文件,一个长度为30秒,另一个长度为120秒。这些文件可能用于测试、调试或者作为占位符使用。 首先,让我们了解一下...

    篮球30秒倒计时

    在这个30秒倒计时项目中,计数器需要从30递减到0。 3. **显示模块**:显示当前剩余时间,可能是LED数码管或者LCD屏幕,用于实时反馈倒计时状态。 4. **报警系统**:当倒计时结束时,触发报警信号,提醒裁判和球员...

    30秒倒计时器完整版下载

    【描述】"30秒倒计时器 完整版下载"进一步强调了软件的完整功能,意味着用户可以从这个版本中获得所有预设的功能,无需购买额外的插件或服务。下载过程可能涉及到在线平台、应用商店或者通过官方网站获取安装包。...

    篮球30秒 单片机 微机 课程设计

    在提供的文件"篮球30秒单片机危机课程设计"中,可能包含了设计报告、源代码、电路图、仿真结果等资料,这些对于学习者来说是宝贵的参考资料,可以从中学习到单片机开发的全过程,以及如何将理论知识应用于实际项目中...

    js倒计时30秒才能点击跳转页面代码

    在网页交互中,有时我们需要实现一个功能:用户必须等待特定时间(例如30秒)后才能执行特定操作,如点击跳转到其他页面。这种功能通常通过JavaScript来实现,因为JavaScript是网页动态效果的主要实现语言。本文将...

    30秒计数器

    3. **定时任务**:类似于这个“30秒计数器”,在编程中,我们可以用计数器来实现定时功能,例如每隔一定时间执行一次任务。 4. **游戏编程**:在游戏开发中,计时器和计数器对于实现游戏逻辑至关重要,比如角色动作...

Global site tag (gtag.js) - Google Analytics