web程序性能优化

额,好大的题目。其实说起来 web程序性能优化 如果说全说细,写出两三本书来问题不大,况且世面上诸如此类的书太多啦。其实本质呢,说来说去都是那么几句话。

1,啥是程序,啥是性能优化。

先看看比较官方的说法吧!

程序(program)是为实现特定目标或解决特定问题而用计算机语言编写的命令序列的集合。为实现预期目的而进行操作的一系列语句和指令。一般分为系统程序和应用程序两大类。

一个程序应该包括以下两方面的内容。
  1 对数据的描述。在程序中要指定数据的类型和数据的组织形式,即数据结构(data structure)。
  2 对操作的描述。即操作步骤,也就是算法(algorithm)。

以上当然全部来自(百度百科)啦。

犀利的总结一下:数据结构+算法=程序(沃思)。

我这里想说的是 计算机语言,程序设计模式,不应该算在程序这个概念中,程序就定义而言,只是完成任务的工具集合或者操作指令等,看的是结果,所以语言和设计模式不算在程序的概念中,只是实现的过程。

做为一名程序员,我们看完了定义,应该马上就能知道“性能优化”,或者程序性能优化,最基础的2个点了。那就是 数据结构的优化和算法优化,只要这两样快了,那么你的program必然慢不了。

再说个简单的例子,来分析下除了这2样本质原因,其他一些排他因素又有什么呐?

看下下面几段程序:

time.c 0.28秒
time.js 0.19秒
time.php 10左右秒
time.python 5.46599197388秒

他们是分别都干了什么呢?恩,都分别是统计了单纯循环1亿次++的结果和时间,代码就不贴了,4个文件呢,不过在我的机器上跑了一下。 运行时间贴到后面了。是不是很出乎意料……

不要怀疑我写的代码有什么区别,都是10000次的循环套循环,然后打印结果和时间差。
关于php,python,c还有nodejs的底层执行过程,我就不说了,也不太十分清楚,但就这个例子就足以说明(我不是说php和python就慢或者不好)不同语言不同场合,性能或者速度上差别很大。

具体是为什么呢?

我说下我理解的吧。。。首先node比c还要快,可能功劳在v8,v8一定是对这1亿次循环做了某些优化再扔给C或者C++执行的,而直接用C应该是慢在了上面所说的算法那一层上。然后php和python的话,可能语言作者针对优化的方向不同,php和python其实也都是先编译后执行在虚拟机上的,(不提编译花费的时间,php和python对单独一个进程之中的include或者improt的模块或文件结果做了缓存,所以从单独一个文件的执行来看会比较慢)(又有朋友说是数据类型的转换导致C比node稍微慢些,总之 这些是个人猜测。)

这些当然都是我个人猜测,对编译原理之类的东西 完全抓瞎,看看就算了。。。。但确实高级语言没有低级语言快,大家都知道的,机器只认机器码,要说最快一定是汇编,可惜我不会汇编,就没有写例子。。。

好了。言归正传。。 语言这一篇算翻过去了,对于设计模式的使用,太庞大了,只能这么说,有些设计模式为了性能,牺牲了可维护性,比如享元模式,有些设计模式又在很小型的系统上体现不出速度优势而在复杂系统中效果出色,比如组合或者装饰者一类。但就设计模式总而言之,都是一些编码技巧,这些在不同语言中,有些占性能的大部分有些又可以弱化不计(因为解释器牛逼,帮你干了)但是最重要的还是权衡场景而做优化。

关于算法优化,我真心无力,只能简单的说几句,算法即是逻辑操作步骤,当然要快的话,步骤越少越好。所以神吗冒泡,快速,排序,基数,归并一类的,大家有空看看还是不错的,虽然一般场景用的很少,不过话说上几个也都是基础的算法,至于复杂的我也只有望而兴叹。。总而言之就是算法优化复杂度,去阶一类。而数据结构当然也是,结构越简单越快,层次越浅越好,所以最近比较流行的noSql或者mongo等程序应该就是从数据结构下手来做文章的,之后会再做介绍。

好了,基本逻辑到这里算理顺了吧,下面说说 web程序优化的几个概念。

2,啥是web程序,web程序性能优化?

web程序肯定属于程序啦。那么程序优化需要的一些关键点,web程序必然都有。但是web程序也有web程序其他一些性能瓶颈,相比客户端的应用程序。

首先web程序是在远程服务器上部署的,而不是在客户端装机的,装可能也就是装个很轻量级的app或者干脆就是个浏览器。然后大量的运算,逻辑,数据都在远程服务器上保存和执行。

然后就是web程序依赖于web,意思是网络IO的快慢也限制了程序的快慢相应,所以优化网络IO也是重要问题。

最后就是大量的并发和请求的优化,独立的程序可能是只有一个人使用,web程序是很多人联网使用的,大量访问远程服务器,服务器的响应速度和能力也是瓶颈。

噢,和前端貌似没啥关系。。

这里要先说个题外话:胖客户端和瘦客户端,胖服务端和瘦服务端。看字面意思就知道了,都是web程序。胖瘦指的是程序的主要逻辑放在哪一边。最开始的web程序,不一定非要是网站。都是胖客户端,瘦服务端,服务端只保存数据,客户端做一切操作,之后实时与远程数据交互,类似现在大家玩的网络游戏一类的程序。而后来又流行了一段,瘦客户端,胖服务端,意思是以浏览器为依托的BS架构网站。客户不需要安装复杂的客户端软件,而是打开一个web app,进行操作,所有数据和执行都在远程机器上跑。

而我们现在每天上的网站,比如微博啊,人人网,豆瓣,sina,或者视频网站一类的常见web网站。都是属于瘦客户端,胖服务端。

前端指的其实就是客户端,不管胖瘦。。。

好了,胖瘦问题说完了。我相信 看着文章的都是做过网站的,不管是做过一部分还是做过全部的吧。web程序优化,必然是从前后端同时展开的。只不过现在客户端越来越胖,服务端越来越云,所以前端的优化问题日益严峻了。

在7 8年前把。网页里都没几段js的年代,真怀念吖。。也正是那个年代,没什么前端优化问题,优化主要都是从服务器程序的性能下手。

下面我们来看一个传统的网页web程序的大致流程:
Browser - > server -> DB;
DB-> server -> Browser;
数据库存着数据,server端处理请求和响应,操作DB数据,返回给请求体,browser负责吐页面出来给别人看。
经过一些人的优化可能变成了下面这样:
读:
Browser->server->Cache->DB;
含有cache的时候 Cache->server->Browser;
不含有cache的时候 DB->Cache->server->Browser;
写:
Browser->server->Cache;
定时Cache-> DB;

好了,够明白的了,后端的优化主要在读写操作上,而读写最频繁的就是数据库,而IO最大的消耗又在写操作上,所以现在比较流行全拿缓存当数据载体,定时更新硬数据一类的方法,如果怕down机就多顶几台服务器,互相做保证,解决方案有memcached.redis,Terracotta(TC)具体就不多说了。。我也说不太明白,大概理解就是把缓存当数据库用,多太服务器互相同步内存中保存的key-value值,然后均衡请求负载,再定时更新备份数据库。

好了,nosql可以出场了~

看过上面我的例子,用过关系型数据库的人肯定都知道,写一段查询要好多好多好多的sql语句啊,尤其是复杂的写入操作,读还好,有缓存帮忙,就当上面的例子我们写入缓存的数据如何定时更新到数据库呢?也还是要定时执行负载的冗长的关系型sql语句。【你逻辑很简单 一个页面一个表的数据库就快消散吧。。】

那么nosql,就是为了解决大量的写操作频繁而诞生的,因为摒弃了关系型数据库,保存都是key-value的简单关系数据,所以写入速度非常快,并且用TC做扩展很容易分布保存。最后再用mongo或者redis这种的key-value关系数据库定时做硬盘持久化保存。那么速度可想而知了。

例如Facebook建立了自己的Cassandra数据商店并且在其网站上重点推出一项新的搜索功能,没有使用到现有的MySQL数据库。据 Facebook的工程师Avinash Lakshma介绍,Cassandra仅用0.12毫秒就可以写入50GB的数据,比MySQL快了超过2500倍。。。

不是所有的web程序都适用于nosql,对于业务逻辑比较简单,写入操作非常频繁,数据量巨大的web系统,nosql有不可言语的优势,比如微博应用,大量的我说,内容短小,关系简单,但是量却是海量。。。我相信他们一定是有用nosql来做的,至少是我上面所说的实现思路,因为瓶颈就在那里,mysql的复杂写操作太昂贵了。。

对nosql我也就理解到这个程度了。。更深也说不出了。或者说现在这也算后端优化发展到目前的状态。【从扩展方面说也很简单,加机器,加内存即可,又便宜又好用,而数据库你加多少台,都是一样的慢。。】

说了这么多,举个例子吧!

下面是用node编写的一个没用到数据库的小应用。

用的是express,界面可以输入key value的值,然后保存在node当前这个进程中的db变量里,随后每隔10秒就往db.js中写入json数据,每次程序启动,首先先读一次db.js确定是否有之前的数据。

通过这个例子模拟,可想写入key value键值对的速度一直都是写内存的速度,而只要我这个进程的db内存,我现在是放在node这个进程里的,如果每次写完我存入TC或者memcached等程序中做同步,那么其他服务器的node进程也就可以存取这个键了,定时更新下硬盘中的持久化介质就好,而node的写又是异步的进行,不会让程序阻塞,哪怕你是往好多的mysql数据库里写,所以做这种尝试很理想。

好了,后端的优化主要就在读写的操作上,至于程序语言选择方面,不仅仅有性能的考虑,还有编码风格和类库支持,等等等主观因素在里面,就不讨论了,主要是高密集CPU操作,换成C或者汇编一类的语言来实现,可以更快。

从经济的角度上看,可以更节约电和热还有cpu寿命,如果你的应用程序足够的庞大。。

好了,我其实想说我要详细介绍的东西才刚刚开始。

看了上面的那么多,web程序优化的点已经说明白了,后端主要在做的事情也了解了。我们假设一个web程序,后端逻辑处理速度及其快,比如1秒完成请求,读写缓存或者数据库操作,完成逻辑并突出html页面给浏览器。恩,一共1秒。

然后客户端开始接受,由于网速的限制等,用了2秒才接受完毕。然后客户端解析响应头,解析页面HTML,CSS,下载静态资源,并访问一些ajax的数据接口。一共用了多少秒呢?额,理论上会是之前1+2秒的许多倍。因为网速问题,静态资源,包括css,js,图片外链的下载需要时间,ajax接口需要等待domready之后再发,哪怕提前发了,也是需要等页面渲染完毕再开始,这写时间都是再第3秒之后了。大家都做过web网站,3秒之后的等待是及其漫长的,一般占总的页面加载完毕的70%左右。

那么这个应用可能需要10秒才能完全打开,当然这个比喻很不恰当,也许页面里没有图和css和js还有ajax接口,那么3秒之后直接你就看到了。

那么事实呢,我们的应用程序越来越复杂,我刚才说的7秒有些夸张,但是前端的资源加载和浏览器渲染速度确实是一个拖慢速度的问题。【抛开网络不好的,我们不可控制-》其实也可以优化,后面再说】

那么web程序优化的前端优化部分,我打算分下面几个点来介绍:

资源的下载,服务器如何更快的响应,CDN是个啥,DNS解析又是啥,同步和异步请求,模块化开发与打包,HTTP的限制等等 网络耗时相关。

DOM,CSS,JS的渲染与执行,优化与效率,重构与测试【技巧与设计模式等-专门会说一些js性能优化代码层面的东西】。

图片的优化,css3,html5的使用,好的设计在性能中的重要性,区分客户端,给更慢的人更多选择,是否还需要SEO?

我觉得可以写书了。。。所以我不会讲的很全。

好,一个一个来。

我在这里就不说yahoo14军规,page speed优化建议上写的了,可能会重,不过那些条条框框主要是拿工具可以测的出来的,说不说意义不大,按照建议能改就改,是最好的,比如yslow可能你做到了A,但是网速不给力,你的页面怎么也快不了,再比如page speed都是对勾了,可能你在你的程序中依然存在严重的性能问题。

相关推荐