在上一篇文章《WordPress建站心得(一)前端性能优化》中,我们提到了如何在服务器和网络状况不变的情况下,通过调整优化请求数目和顺序,缩短页面呈现时间,从而提升用户体验。不过,这种优化只是在请求之间的优化,它并不能提升每个请求的响应时间,如果需要继续优化性能,则必须从服务器和网络本身入手。
我们谈到服务器性能,主要有三个比较重要的衡量标准。一是吞吐量,表示网站在一定时间内能有效承载的请求的最大数量,也就是网站能承受多少人同时访问。二是资源消耗,表示网站在处理一定数量的请求时,所消耗的服务器资源,这和网站的成本直接挂钩。三是首包时间,表示网站返回动态(如PHP, JSP)与静态请求(如js,css,jpg)所需要的计算时间。
在这三个标准中,传统的性能优化主要集中在头两个方面,这无可厚非,因为直接涉及到网站的运营成本和覆盖范围。诚然,这三个标准其实相互作用,一个性能优良的网站,必然会有较高的吞吐量,较低的资源消耗,以及较低的首包时间。不过这并非完全正确,因为采用传统方法优化服务器架构,只能在前两方面有所进步。比如,采用web–>application–>db三层服务器集群,中间通过load balancer来动态调配,的确能极大增加吞吐量和降低单服务器资源消耗,但首包时间并不会因此而大大降低,反而会因为服务器之间的网络沟通产生延时。
回到WordPress的例子上面,相信很多站长都和我一样,没有充裕的budget,只是凭个人爱好而建站,必然没有那么多资源建设庞大的服务器集群,但我们同样有很多办法优化我们仅有的vps性能,从而降低首包时间,减少资源消耗,增大吞吐量。这篇文章针对的正是我们这些草根站长。
首先,让我们回顾一下,一个网站是如何向用户展示信息的,以WordPress为例。
- 用户浏览器准备发送请求
- 系统从DNS缓存中解析出服务器IP
- 如DNS缓存中没有,则通过DNS请求向上级DNS服务器逐步请求,直至获得IP(可选)
- 浏览器同服务器建立连接
- 如果是SSL连接,则浏览器同服务器进行SSL Handshake(可选)
- 浏览器向服务器发送请求
- 服务器的Web Server(如Apache, Nginx)收到请求,判断是否为动态请求
- 如果是静态请求,从硬盘中读取相应文件,返回给浏览器
- 如果是动态请求,将该请求交由PHP模块或独立PHP进程处理
- PHP程序收到处理请求,从硬盘中读取相应的PHP文件
- PHP程序将PHP文件从源码编译为Opcode
- PHP程序执行Opcode
- 如果需要DB操作,则PHP程序向MySQL Server发出查询请求(可选)
- MySQL Server从硬盘中读取数据库,进行查询,返回结果(可选)
- PHP将生成的HTML返回给Web Server
- Web Server将HTML返回给用户浏览器
- 用户浏览器解析HTML,展示页面,同时准备下一个请求
看着都头晕,如果你的服务器返回每一个动态页面都需要经历这十几个步骤,首包时间怎么可能短的了呢?所以,必须进行优化。
以下将根据以上过程的顺序逐一介绍优化的技术。注意:并不是每个技术都适用于所有网站,本文仅供参考。站长应知晓调整架构所带来的风险。照以下方法进行优化所带来的一切后果本人概不负责。
DNS缓存
一般情况下,用户访问的第一站就是你的DNS了。DNS负责将你的域名转换成IP,如果设计不当,将大大拖慢用户首次访问所需的时间。
1. DNS运营商选择
如果网站的目标用户群在国外,则GoDaddy等自带的DNS就不错。不过如果目标用户群在国内,则需要用国内的DNS运营商,如DNSPod等。考虑DNS运营商时,一定要看清楚其DNS的分布节点。当然是越多越好。这里为避免广告嫌疑,就不做推荐了。
2. DNS解析类型
一般解析类型为A,AAAA (IPV6),CNAME几种。如果可能,尽量避免使用CNAME,而使用A记录,因为CNAME记录会让DNS解析多解析一两个其他域名,加大延时。另外一定要注意CNAME记录不要放在@,否则会和MX记录冲突,导致邮件接收失败。
3. 记录过期时间(TTL)
这个设置对提升DNS解析速度至关重要。全球各地的运营商会在自己的DNS服务器上设置缓存,而决定缓存失效的时间就是TTL。如果设置了TTL,则同一地区的其他人再次访问DNS的时候,就会直接从本地的DNS获取结果,不用再经历漫长的DNS查询。不过,TTL设置得太长,则会影响灵活性,比如要更改DNS设置的时候,需要更长的时间才能让全球各地的用户更新。一般建议没有太大变动的DNS设置为86400秒,也就是一天,如果要更改DNS设置,则提前一天将TTL改成300或更少。设置好之后,在站长工具检测一下就知道是否成功了。
内容分发网络(CDN)
CDN是一种服务,将你网站的内容通过其他的服务器分发,降低Ping值,减少连接时间。有的CDN支持将html整个缓存,从而减少服务器压力。
1. 究竟需不需要CDN?
这个问题放在以前,我肯定毫不犹豫地说需要,不过在权衡了价格和效果后,我的看法是,It depends。如果你的网站真的有成千上万人从全国各地甚至全世界各地访问,而你恰好又有充足的预算,那就可以有。不过如果只是一个中小型网站,像我这种个人博客,那就得具体看服务器的位置和提供的服务了。如果你的网站架设在百度云、阿里云或者新浪云上,恭喜你,你不需要CDN,因为这些平台本身就是分布式的,从全国各地访问速度差不多。如果架设虚拟空间或者VPS,且域名已经备案,可以尝试用加速乐等免费的CDN。如果域名没有备案,那么国内许多CDN用不了,或者只能用国外节点,我建议不要用CDN,因为即使从内地访问到CDN所用时间不多,CDN连接你的服务器也需要很长时间,所以综合算下来还是不值得。当然,如果你有预算,上Akamai或者ChinaCache,就另当别论了。
2. CDN全页缓存
有一些CDN提供了页面缓存功能,意图是不错的,不过一定要注意对Log-in用户的处理,我曾经用Google Pagespeed当CDN用,但它会连一些只有管理员才能看到的元素都缓存下载,带来安全隐患。所以,如果CDN不能提供缓存的微调功能,不要随意开启全页缓存。
3. CDN的永远在线功能
很多CDN提供了永远在线功能,说白了就是在你的源服务器无法访问的情况下,为终端用户显示一个漂亮的维护页面。这样做可以提高用户体验。
关于CDN就谈这么多,Alex Sky前前后后也试过不少CDN,但最后终因效果不佳、稳定性不高而放弃。等以后真的有了很多很多访客的时候,再考虑添加CDN吧。
服务器连接优化
服务器连接方面可调整的并不多,主要是KeepLive的设置,在返回的标头上应加上
Connection: Keep-Alive
这样浏览器在连接到服务器后,发送的其他请求就不需要重新连接,从而加快响应。
缓存代理
缓存代理布置在Web Server之前,缓存所有请求,并直接响应新的请求,从而大大提高响应速度。缓存代理对性能提升的影响非常大,因此我强烈建议采用。采用缓存代理后,上面所述的请求处理步骤,在第六部的时候就可以得到完整地html应答,省去了后面繁杂的步骤。缓存代理的代表是Varnish。
本文不会详细介绍Varnish的安装。如果你是Debian平台,可以参考这篇指南。如果是RedHat系,可以参考这篇指南。
以下分享一下Alex Sky所用的Varnish配置,配置文件在/etc/varnish/default.vcl目录
# 导入standard module设置自定义错误页面
import std;
backend default {
.host = "127.0.0.1";
.port = "%backend webserver port%";
}
acl purge {
"127.0.0.1";
"%public_ip%";
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return (lookup);
}
if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.*$", "");
}
if (req.url ~ "\?(utm_(campaign|medium|source|term)|adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er|iew))=") {
set req.url = regsub(req.url, "\?.*$", "");
}
if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
return (pass);
}
if (req.request == "POST" && req.url ~ "wp-comments.php") {
ban("req.url == " + req.url);
return(pass);
}
if (req.http.cookie) {
if (req.http.cookie ~ "(wordpress_|wp-settings-)") {
return(pass);
} else {
unset req.http.cookie;
}
}
}
# 缓存页面30天
sub vcl_fetch {
if ( (!(req.url ~ "(wp-(login|admin)|login)")) || (req.request == "GET") ) {
unset beresp.http.set-cookie;
set beresp.ttl = 30d;
}
# 缓存静态资源一年
if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
set beresp.ttl = 365d;
}
}
sub vcl_deliver {
# multi-server webfarm? set a variable here so you can check
# the headers to see which frontend served the request
# set resp.http.X-Server = "server-01";
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
# 除去没必要的回应标头
remove resp.http.X-Powered-By;
remove resp.http.Via;
remove resp.http.X-Varnish;
remove resp.http.Age;
remove resp.http.X-Cache;
remove resp.http.X-W3TC-Minify;
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "OK";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 404 "Not cached";
}
}
# 设置自定义错误页面
sub vcl_error {
set obj.http.Content-Type = "text/html; charset=utf-8";
synthetic std.fileread("%errorpage%");
return(deliver);
}
注意替换%变量%
%backend webserver port%替换为你的backend webserver的开放端口,设置Varnish后,80端口被Varnish占用,你需要为Apache或Nginx配置另外一个内部端口作为侦听端口
%public_ip%替换为你的服务器的ip地址
%errorpage%替换为你自定义的报错页面的绝对路径,比如/var/www/error.html
下图是Alex Sky使用了Varnish后的响应时间图。
可以看到,在200个虚拟用户疯狂不间断点击的情况下,响应时间仍然在80ms以下,吞吐量至少有63544/min,而短短一分钟内,Varnish响应了3.17GB的内容,没有任何错误!
SSL连接优化
如果你的站点开启了SSL,就会发现连接速度大大降低。这是因为每一次连接都涉及到SSL Handshake的步骤。其实这一部分也是可以通过优化来减少连接时间的。
1. 采用ECDHE Cipher Suite
ECDHE是近年来流行的Cipher Suite,可以实现Perfect Forward Secrecy,至于对安全的作用我将在下一篇文章中着重阐述。这篇文章主要讲讲对性能的影响。目前支持PFS的Cipher Suite只有两种,DHE和ECDHE。如果使用DHE,会很大程度上影响性能,所以建议采用ECDHE。目前版本的Nginx支持,而Apache则需要升级到2.4才能支持。
2. 开启SPDY协议
SPDY是Google近年来推行的一个新的协议。目前建立在SSL上,是为了优化已经沿用十几年的HTTP/1.1标准,SPDY协议的介绍可以看月光博客或者Google官方说明。SPDY目标是提高HTTP响应速度50%。SPDY和HTTP/2.0将成为下一代互联网的基础。SPDY目前的版本号是SPDY/3.1,只有Google的服务器支持,Apache可以使用的版本是SPDY/3,而Nginx使用的是SPDY/2。因为奇奇怪怪的原因,SPDY目前仅支持Apache2.2,虽然官方说会尽快支持2.4,不过现在做的也只有等。所以对于Apache来说,支持ECDHE和SPDY正好是矛盾的。对于Nginx来说两者都能支持,不过因为SPDY模块不是Google在维护,所以开发进度较慢,目前的版本为2,已经不支持Chrome32和Firefox27了(感叹一下,发展太快了跟不上啊!)
Apache MPM
通常对于一个更新不怎么频繁的WordPress网站来说,Varnish已经能拦掉80%左右的流量了,对于剩下的20%和SSL流量,则进入了我们真正的Web Server。因为WordPress原生支持的是Apache服务器,所以为了更好地稳定性和易用性,我仍然选择Apache。其实Apache已经不像我们之前想的那样笨重了。
Apache MPM (multi-processing modules) 是Apache2.0推出的一个新功能,通过多处理模块来适应各种环境。目前有三种MPM的模式可供选择。传统的prefork,主力的worker和新加的event。三种模式各有各的优势。prefork稳定兼容性高,是最老的模式。worker性能强悍,是为了应对Nginx的挑战而设。event在worker的基础上优化了对keep-alive的处理方法,进一步增大了吞吐量。具体采用什么模式,需要考虑到所运行的application,不过对于wordpress和php来说,三种模式都可以运行。如果条件允许,建议尝试最新的event模式。
如果你安装的apache2.4已经compile了event模式,可以通过命令开启event模式。
a2dismod mpm_prefork
a2dismod mpm_worker
a2enmod mpm_event
service apache2 restart
验证开启了哪一个模块,可以运行
apache2ctl -V
来查看。
PHP模块还是PHP进程
如果在Apache MPM模式中选择了worker或event,则无法使用mod_php,mod_php是Apache集成的PHP处理模块,是默认用来处理php的方式。不过由于worker和event是多线程的,也就是说同一个apache2的进程里会同时处理多个不同的请求,而mod_php是集成在每一个apache2进程当中的,它无法分辨不同的线程处理的请求,也就是通常说的non thread safe。因此mod_php无法同worder和event模式并用。
解决的方法是将PHP处理从Apache中独立出来,让Apache仅处理静态文件和http请求,而将PHP的处理分发给专门从事PHP处理的进程。
说到这里,就要涉及到一系列的概念了,比如php-cgi,fastcgi,cgi,mod_fcgid,mod_fastcgi,php5-fpm,大家可以看一看这篇回答,这是我看到最清晰的解答之一。如果头痛不想看,那么结论就是对于WordPress来说,用php5-fpm处理PHP请求,并通过fastcgi协议同Apache2来传递信息,是最有效的方法,既能支持Apache的worker和event模式,也支持共享缓存,也就能更好地支持APC等Opcode缓存。
php5-fpm的安装不难,一般会认为php5-fpm和Nginx搭配比较好,其实Apache一样可以搭配。而且毫不逊色。安装同LEMP stack里一样,直接apt-get install php5-fpm就行了。
以下是Alex Sky的配置文件,放在/etc/apache2/conf-available/php5-fpm.conf,仅供参考。
<IfModule mod_fastcgi.c>
FastCgiExternalServer %absolute_path%/php5.fcgi -socket /tmp/php5-fpm.sock -pass-header Authorization
AddHandler application/x-httpd-fastphp5 .php
Action application/x-httpd-fastphp5 /php5.fcgi
Alias /php5.fcgi %absolute_path%/php5.fcgi
</IfModule>
注意更改%变量%。
%absolute_path%为网站根目录在服务器的绝对路径,比如/var/www。
在/etc/php5/fpm/pool.d/www.conf文件里面配置监听的socket。
listen = /tmp/php5-fpm.sock
之后执行service php5-fpm restart重启完成配置。
Opcode缓存
现在请求终于到达了PHP层。正常情况下,php5-fpm会读取相应的php文件,然后根据php语法解释代码,生成Opcode,再开始执行。但是我们可以缓存编译后的Opcode,之后再执行的时候不需要重新读取文件进行解释,直接从缓存的Opcode开始执行,这样大大缩短了执行时间。
负责Opcode缓存的组件是APC,全称Alternative PHP Cache。安装教程见此。配置文件建议和其他配置一起放在/etc/php5/conf.d/apc.ini。
对于WordPress的博客来说,设置64MB的cache size就足够了,以下是Alex Sky的apc.ini文件内容。
extension=apc.so
apc.shm_segments=1
apc.shm_size = 64M
apc.ttl=7200
apc.use_request_time=1
apc.user_ttl=7200
apc.gc_ttl=3600
apc.cache_by_default=1
apc.filters
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.file_update_protection=2
apc.enable_cli=0
apc.max_file_size=2M
apc.stat=1
apc.stat_ctime=0
apc.canonicalize=1
apc.write_lock=1
apc.report_autofilter=0
apc.rfc1867=0
apc.rfc1867_prefix =upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0
apc.rfc1867_ttl=3600
apc.include_once_override=0
apc.lazy_classes=0
apc.lazy_functions=0
apc.coredump_unmap=0
apc.file_md5=0
apc.preload_path
如果要禁用apc,就把第一行用;符号注释掉就行了。注意,不要在不同的配置文件中多次启用apc,这样会导致php的警告信息。
安装好以后可以从/usr/share/php/目录中拷贝apc.php探针到自己的网站中,可以看到实时的apc统计数据。对于WordPress来说,Opcode缓存命中率高达99.7%,也就是说php5-fpm再也不用重新解释php文件了。当然只要你重启php5-fpm,缓存就会消失并重建,所以不用担心更改application code之后缓存不同步的问题。
对于PHP5.5,Zend Optimizer成为官方的Opcode Cache,默认已经开启,所以不需要特别设置。
WordPress全页缓存
PHP开始执行代码后,就要生成html网页了。(2013.12.16更新:此处理解有误,WordPress全页缓存实际上不需要执行PHP代码,而是在Web Server层面进行Rewrite。)等等!我们为什么还要生成html?这种实时计算的东西最麻烦了,麦当劳从来不会在客人点单之后再去捕鱼杀鸡磨面,而是先把汉堡包做好,客人即点即卖,这就是WordPress全页缓存的原理。其实缓存类型和Varnish差不多,不过这次是针对Varnish漏掉的页面,并且不包括静态资源。WordPress全页缓存的插件有很多,我之前的日志推荐的Batcache,就是建立在Memcached基础上的全内存全页缓存。不过有测试表明,全内存全页缓存,其实并没有比基于硬盘的全页缓存效率高,因为Linux在系统层面会把常用的文件缓存到内存中,而Linux的内存管理效率要高过PHP,所以使用硬盘缓存效率更高。
对于WordPress全页缓存,我推荐W3 Total Cache插件。它不仅能做到全页缓存,还能进行缓存预热,也就是在还没人访问前先把缓存建好,这样所有人都能访问到缓存过的页面了。在这种情况下,全页缓存的命中率几乎是100%,除了用户即兴的搜索无法缓存,其他的页面都能缓存。W3 Total Cache还能进行自动minify,从而部分实现第一篇文章中说的前端优化。后面提到的对象缓存和数据库查询缓存,也可以通过W3 Total Cache调配,因此可以说,W3 Total Cache是WordPress在应用层面的性能管理中心。W3 Total Cache安装介绍太多了,自己百度Google之即可。
WordPress对象缓存
有些时候我们作为管理员登陆了博客,这时候全页缓存失效,全靠执行PHP代码生成HTML,因此我们到了这一步还需要继续优化。下一个被优化的就是WordPress对象缓存。作为基于对象的语言,php运行时需要存取许多数据。WordPress对象缓存就是为了缓存这一类数据。对象缓存有两种实现形式,硬盘和内存。同全页缓存不同的是,这一次我们需要用到内存缓存,因为对象缓存的存取特别频繁,如果用硬盘的话很可能会造成碎片化,降低硬盘性能,而内存就是为碎片化准备的。至于内存缓存方面,我们本可以用APC,但是APC处理碎片化并不出色,而且会导致cache full reset。于是我们采用memcached来专门进行对象缓存(以及后文马上提到的数据库查询缓存)。
安装memcached也十分简单,参见教程。在设置文件/etc/php5/conf.d/memcache.ini中uncomment extension=memcache.so开启,然后在W3 Total Cache中的对象缓存里选择memcached作为存储方式。
数据库查询缓存
有时候WordPress运行的数据在对象缓存中找不到,就会用sql来查询MySQL数据库。为了尽量减少数据库查询,我们还有最后两层缓存。
1. WordPress数据库查询缓存
这个是基于WordPress层面的,将select等语句返回的结果缓存下来,可以用W3 Total Cache调用memcached来实现。
2. MySQL Query Cache
这个是MySQL自带的,在数据库层面缓存经常执行的sql语句的返回结果。这个缓存MySQL是默认启用的,可以在/etc/mysql/my.cnf配置文件中调整缓存大小和数目,不过一般情况下不需要调整。
到此为止,我们已经将WordPress所在的服务器进行全面的优化。让我们再来看看改进后的请求处理流程吧。
- 用户浏览器准备发送请求
- 系统从DNS缓存中解析出服务器IP
- 如DNS缓存中没有,则通过DNS请求向上级DNS服务器逐步请求,直至获得IP(可选)(DNS缓存优化直接获得IP)
- 浏览器同服务器建立连接(通过keep-alive保持连接)
- 如果是SSL连接,则浏览器同服务器进行SSL Handshake(可选)(通过ECDHE和SPDY加速)
- 浏览器向服务器发送请求(80%被Varnish拦下,从内存直接返回结果,跳过后面所有步骤)
- 服务器的Web Server(如Apache, Nginx)收到请求,判断是否为动态请求(mpm-event模式加速处理)
- 如果是静态请求,从硬盘中读取相应文件,返回给浏览器(命中Wordpress全页缓存,命中率90%,跳过后面所有步骤)
- 如果是动态请求,将该请求交由PHP模块或独立PHP进程处理(php5-fpm更高效地执行)
- PHP程序收到处理请求,从硬盘中读取相应的PHP文件(已被APC进行Opcode缓存,跳过)
- PHP程序将PHP文件从源码编译为Opcode(已被APC进行Opcode缓存,跳过)
- PHP程序执行Opcode(如需执行,所需数据由Memcached WordPress对象缓存提供)
- 如果需要DB操作,则PHP程序向MySQL Server发出查询请求(可选)(Memcached WordPress数据库查询缓存,跳过)
- MySQL Server从硬盘中读取数据库,进行查询,返回结果(可选)(MySQL Query Cache,跳过)
- PHP将生成的HTML返回给Web Server
- Web Server将HTML返回给用户浏览器
- 用户浏览器解析HTML,展示页面,同时准备下一个请求
最后要强调的是,以上所说的各种优化方式,并不适用于所有环境,请使用前详细了解,作出最适合自己网站的决定。
2013年12月9日更新:
Alex Sky近期又进行了较大幅度的调整。目前已经从Apache转到Nginx,得益于Nginx出色的静态文件处理和W3 Total Cache的Disk Enhanced Cache,网站即使不需要Varnish也能保持很短的响应时间,反而减少了资源消耗。
之前在SSL的性能中有一点没有提到,那就是OCSP Stapling,这个对于SSL的连接有很强的提升,据说能减少响应时间30%,原理是减少浏览器进行证书验证的请求。参照这篇文章开启。
文章写得很好,条理清晰,文字流畅,专业技术讲的深入浅出,对本人很有帮助,谢谢。
希望有时间能再写篇文章讲讲您现在的Nginx方案的架构和具体配置。
另外问一下您现在digital ocean的服务器架设在哪个区域?如果用wordpress搭建面向全球用户的网站,使用一台服务器是否够用呢?有必要在不同的地区租用VPS构建前置代理之类吗?
十分感谢关注。Nginx我现在的配置不是很复杂,基本按照现有网上的方案来做,只是自己加了一些应答头,实现Content-Security-Policy,这个在我后一篇文章里写到了。我的DigitalOcean现在在SFO机房,我之前是在NYC2,不过感觉内地访问稍微慢一些,所以改成SFO。全球用户的问题,我之前也考虑过,比较简单的方法是用一个CDN来分发内容,所以源头一台服务器就够用了。不过国外的某些CDN国内无法访问,所以最后折腾了半天,还是决定不用CDN。如果服务器放在北美的话,国内访问延迟大概在200ms左右,如果前端优化得比较好还是很快的。如果美国访问就秒开,欧洲访问大概在100ms内,日本香港台湾等大概150ms,印度可能会超过500ms。总的来说延时还算满意。你可以去http://www.webpagetest.org测试你的网站,看看各地真实访问情况如何。
谢谢回复!
还想向您请教个问题:我目前的wordpress站点用了不少的第三方插件,很多插件都在wp_head中加入自己的js和css,这对于前端的加载速度非常不利,请问有什么好的原则可以用于提高wp_head的效率?
另外,我的主题和插件用到了一些google提供的api(例如网络字体和地图),由于“网络闭关锁国(官方好像叫网络长城)”的影响这会导致国内用户访问速度极慢,请问对于这类情况您有没有好的建议?
关于前端性能,可以参考我的前一篇文章《WordPress建站心得(一)前端性能优化》。总的来说,js的数量要尽量少,加载要尽量延迟。只要对页面展示没有影响的,一律异步加载,代码可以参考Google Analytics里面的那段。如果你的插件更新不太频繁,可以将js提取,然后用Google Closure Compiler合并成一个common.js,或者两个,一个随页面加载,一个异步加载。国外的公共库我都很少用,其实展示一个页面,涉及到的域名越少越好。所以jquery等我都是直接调用自己服务器上面的版本。字体等其他元素也是如此,能放在本地的就放在本地。
http://themes.googleusercontent.com/static/fonts/opensans/v8/k3k702ZOKiLJc3WVjuplzBa1RVmPjeKy21_GQJaLlJI.woff,你是怎么优化处理这种字体请求的?
直接用系统现有字体替换,去除这类请求。不过如果你觉得特别好,可以下载下来放到本地调用。一般来说连接的域名能少则少。
nginx的open_file_cache和proxy_cache你有比较过么?
open_file_cache是缓存文件metadata的,小流量的网站几乎没啥用。proxy_cache是只有将nginx作为最前端的reverse proxy的时候才会用到,如果直接采用nginx + php 这种结构也用不上。Linux会自动缓存经常读取的文件,所以如果大流量的话,nginx是直接读取内存缓存的,不存在性能瓶颈。