上个月公司的网站性能出了问题,首页打开要等三秒钟,用户体验很差。老板把这个优化任务交给了我,要求一周之内把响应时间降到一秒以内。我花了五天时间,最后把首页响应时间降到了三百毫秒,比预期的还要好。
拿到任务之后我没有急着改代码,而是先做了性能分析。工欲善其事必先利其器,不知道瓶颈在哪里就盲目优化,往往是白费力气。我用xhprof做了性能分析,把首页的执行过程拆解开来,看看到底是哪一步耗时最长。
分析结果出来之后,问题很明显。数据库查询占了百分之七十的时间,其中有几个查询每次都要执行几百毫秒。剩下的时间里,PHP的模板渲染占了一部分,还有一些是外部接口调用。
先从最耗时的数据库开始优化。有一个查询是获取文章列表,每次都要join三张表,而且没有用好索引。我把这个查询拆成了两步,先查文章ID列表,再根据ID查文章详情,这样就避免了大表join。然后给查询条件用到的字段都加上了合适的索引。改完之后,这个查询的执行时间从八百毫秒降到了五十毫秒。
还有一个查询是统计文章数量,每次都要count整个表。这种查询在数据量大的时候很慢。我的做法是把统计结果缓存起来,只有在新增或删除文章的时候才更新缓存。这样大部分时候都不需要实时count,直接读缓存就行了。
数据库优化完之后,响应时间从三秒降到了一秒五。但还不够,我继续优化。
第二步是加缓存。我把首页的整个输出都缓存到了Redis里,有效期五分钟。这样大部分用户访问的时候,根本不需要执行PHP和查询数据库,直接从Redis里读缓存内容返回就行了。加了页面缓存之后,响应时间直接降到了两百毫秒以内。
但页面缓存有个问题,就是用户登录之后看到的内容和未登录用户不一样,不能用同一份缓存。我的做法是对未登录用户用整页缓存,对已登录用户用局部缓存,把页面上不变的部分缓存起来,变化的部分动态生成。这样既保证了性能,又保证了内容的正确性。
第三步是优化前端。后端再快,前端加载慢用户还是觉得卡。我把CSS和JavaScript文件都合并压缩了,减少了HTTP请求数。图片做了懒加载,首屏之外的图片不加载,等用户滚动到的时候再加载。还开了gzip压缩,文本资源的传输体积减少了百分之六十多。
前端优化完之后,用户感知的页面加载时间又缩短了不少。虽然后端接口的响应时间是两百毫秒,但用户感觉页面几乎是秒开的。
第四步是优化外部接口调用。首页有一个天气模块,调用的是第三方的天气接口。这个接口有时候很慢,要等一两秒。我把天气数据也缓存了,每小时更新一次,不再每次都实时调用。这样就不会因为第三方接口慢而拖慢整个页面。
经过这几步优化之后,首页的响应时间稳定在三百毫秒左右,高峰期也不会超过五百毫秒。老板很满意,团队的同事也觉得体验提升很明显。
这次优化让我深刻体会到,性能优化不是靠某一个技巧,而是一个系统工程。数据库、缓存、前端、外部接口,每一个环节都可能成为瓶颈。需要全面分析,逐个击破。
还有一个体会是,优化一定要有数据支撑。不要凭感觉去优化,要用工具分析,找到真正的瓶颈再动手。否则很可能花了很多时间,却没有什么效果。
现在网站的性能已经很不错了,但我知道这不是终点。随着用户量增长,还会遇到新的性能问题。到时候再继续优化就是了。做技术就是这样,一直在解决问题的路上。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录