建立这个 WordPress 博客时间并不长,但是可以说一直在尽力优化网站性能,加快页面的载入速度。几个月下来,靠身体力行并汲取了很多牛人的经验,自己对其也算有一点了浅薄的认识,所以做出一个初级的一个性能优化文章。

针对 WordPress,可以把影响 WordPress 速度的因素归结为三点(单击小标题可直接跳转至该内容):

  1. 服务器端:一般就是指服务器进行 MySQL 数据库查询和将 PHP 解析为 HTML 的时间。
  2. 网络传输:服务器端与用户客户端之间传送数据的时间。
  3. 客户端:即浏览器解析 HTML 文件,渲染页面和执行 JavaScript 脚本的效率、客户端的缓存、页面的 CPU 和内存占用等。

上面分的三类,往往都是互相关联的,许多优化方法,能归到以上三个分类的任意分类中。这里也只是简单的介绍一下优化的方法,使用分类会更加清晰一些。

用户打开某一页面的时间基本等于:服务器端时间+网络传输时间(包括 DNS 查询、请求和返回数据)+页面解析和渲染时间(此项几乎可以忽略不计)

所以正文就以这三个因素分别说明其加速原理和实现,在此之前先介绍 Firefox 的三个扩展:

  • Firebug 对于网络传输的监控和 HTML、JS 脚本的查看功能十分强大。
  • Yslow 与 PageSpeed,这两个扩展对影响页面速度的因素分析和评价十分详细,并且给出了比较完整的解决方案。

使用上述三个插件,便可以对自己网页的性能和可优化之处有比较全面的了解。

服务器端:

服务器端的主要任务就是将动态网页 PHP 解析为静态的 HTML 文件,并将它传输到客户端。在解析的过程中,还需要向 MySQL 查询数据。影响服务器端的,主要有以下几点因素:

  1. 服务器的性能:服务器的性能越强大,共享用户越少或者给用户分配的资源越多,则可以认为服务器的性能强大,这样 PHP 文件的解析速度或者说页面生成速度就越快。建议:购买性能更加强大的虚拟空间,或者 VPS,甚至是独立服务器,但是相应的成本提升巨大。

    实现难度:☆或★★★★★ ,加速效果:★☆

  2. 服务器优化:对服务器的软件进行优化,比如 Memcached,NginX + Apache 组合等,但这需要对 Linux 比较熟悉和不断调试才能配制出最佳的环境。

    实现难度:★★★★★ ,加速效果:★★★

  3. PHP 页面源代码:页面越简单,则生成的速度就越快。
    • 复杂程度:以博客首页为例,显示 50 篇文章与 5 篇文章,在数据库查询、页面生成速度和用户加载速度上的差距是显而易见的,页面中放入了太多的元素(DOMS)不仅影响了页面的生成与传输速度,也容易对用户的体验有负面的影响。建议:将每页的文章数量设定在一个比较合理的数量上,并合理使用 more 标签。

      实现难度:☆ ,加速效果:★★★

    • 去除或修改不必要代码:大多数主题为保证主题的通用性,采用了许多获取信息的函数,但是一般情况下,大多数用户并不会将自己的主题发布,而是直接在现有的主题上加以修改。以本博客为例,主题 header.php 中有:
      <title>
      <?php wp_title('|', true, 'right'); ?>
      <?php bloginfo('name'); ?>
      </title>
      // 既然博客的名称和地址除特殊情况下都不会有变动,那为何不使用纯 HTML 代码来代替 PHP 语句呢?,所以改为:
      <title>
      <?php wp_title('|', true, 'right'); ?>
      小虾的 Blog
      </title>
      // 再比如
       <?php if($blogOption['top_sns_twitter']!=''){ ?><li><a href="<?php echo $blogOption['top_sns_twitter'];?>" class="twitter" title="Follow 我的 Twitter" target="_blank">Twitter</a></li><?php } ?>
      // 如果打算长期显示,就不必让服务器再去数据库中查询是否开启该图标和其地址了。
      <li><a class="twitter" title="Follow 我的 Twitter" href="http://twitter.com/neverweep" target="_blank">Twitter</a></li>

      大多数情况下,header.php、index.php 等等中都有这样可以替换的代码,如字符集声明,feed 地址等,可以根据自己的需要和主题进行替换。 此外,主题中有"_e" 和"__" 的地方,都可以直接将该语句替换成中文,可以避免读取语言包的时间。

      建议:尽量去除不必要的 PHP 语句,比如某些判断语句是否必要,某些 PHP 语句是否可以用其它纯 HTML 的方法实现等等。这些都可以减少微量的 MySQL 查询和页面生成时间。

      实现难度:★★ ,加速效果:★

  4. 插件:插件自身的性能表现和插件数量的多少,都影响着页面的生成速度。
    • 比较相同功能的插件,从中选取性能表现较优的插件。以博客的最近评论插件为例,为实现 ajax 评论,我测试了两款基于 ajax 的最近评论插件,mg12 的最近评论要比 qiqiboy 的功能更强大的 RC reply ajax 的数据库查询次数要少一倍还多。
    • 剔除不必要的插件,安装一些非常酷炫的插件是否有必要?尽量删除对于博客和用户没有太大价值的插件来换取速度上的提高是值得的。另外强烈推荐WordPress P3插件,该插件为 Godaddy 出品,可以量化各插件对服务器性能的影响,那些占用资源又可以被替代的插件就毫不犹豫的删除吧。
    • 用纯代码方式替代插件实现功能。以 WP-codebox 为例,这个插件的功能是将文章中特定标签内的代码高亮,使代码可读性明显增强。但是每次都将无格式文本代码生成为具有丰富表现力的 HTML 代码是需要占用大量资源的,所以不妨临时开启 WP-codebox,再查看网页源码,将格式化过的代码的 HTML 替换到正文中,再关闭 WP-codebox,这样做即可一劳永逸的使某篇文章实现“静态化”,大大降低了该文章页面的生成时间。此外,用 willin 大师的小墙替代 Akismet 等等方法都可以降低插件的使用数量。

    实现难度:★★★ ,加速效果:★★★★

  5. 缓存: 采用各种缓存插件,可以显著减少服务器端占用的时间。
    • 页面缓存:推荐 WP super cache 或 Hyper Cache,其原理就是将 PHP 页面静态化为 HTML,这样访客所获取的页面几乎不再需要服务器处理,基本将服务器端时间消除了。但是这种缓存插件对于页面也有某些不利的影响,比如会造成文章点击次数统计不准确等。加速效果:★★★★★
    • 数据库缓存:推荐 DB Cache Reloaded Fix,可以将数据库查询缓存至硬盘,以极低的空间占用可以换来强大的性能提升。此外这个插件还提供了一个很实用的功能:将页面生成时间和数据库查询次数等信息插入到页面中,对分析服务器端性能非常有帮助。加速效果:★★
    • Widget 缓存:推荐 WP Widget Cache,由于大多数博客所有页面上的小部件都是一致的,并且大多数情况下都不会有短时间内的变动,比如分类 Widget 的输出甚至可能永远不会变动,搭配上述两种插件可以再次减少生成静态化页面时的数据库查询次数。加速效果:★

    建议:这三类缓存插件可以互相搭配使用,对于访问量不大的博客来说,只使用数据库缓存或者再搭配页面缓存即可 。缓存类插件启用非常简单,但是通过合理的设置使插件工作在完美状态则比较困难,比如缓存文件的过期时间等设置项就需要结合访问量等因素综合考虑。

    实现难度:★★ ,加速效果:★★★★

  6. 优化数据库:定期优化数据库,数据库体积越大则优化后的速度提升就越明显。可以通过登陆 phpmyadmin 选择优化,也可以通过插件 DB Backup 来优化。

    实现难度:★ ,加速效果:★

小结:就我的博客文章页来说,页面生成时间大多在 0.4~0.7 秒之间,上述大多数因素对于速度的影响其实都非常小,甚至不到 0.05 秒。不过有时某些因素可能会大大减缓页面生成时间,比如利用 WP-codebox 高亮 40 行左右的代码后,生成时间会减缓到 1.3 秒甚至 1.8 秒。总体来说,剔除无用插件和使用缓存类插件对于博客服务器端的加速效果会更明显

网络传输:

网络传输上很难改变的一个因素是服务器到客户端之间的带宽和响应速度,所以就需要尽量减少传输文件的数量和大小。Firebug 中的网络面板,将每个文件的传输时间都以瀑布图的方式显示出来,非常直观清晰。页面中的每个文件都需要向服务器发送 HTTP 握手请求,一般情况下,握手花费的时间会比传输一个 1KB 的文件还长,所以精简文件个数是加快网络传输的重中之重。

  1. 减少 HTTP 请求数量
    • 去除不必要的图像,将图像用 CSS Spitite 合并。减少不必要的图像,在不影响体验和美观的前提下,尽量用文字代替图像。用 CSS Spitite 合并图像,可以将许多图标和按钮图像合并在一张图像上,以一次请求和总体更小的数据传输量代替多次请求和许多零碎的数据传输量,效果十分明显。比如本博客右上方的社会化链接图标,其只用了一张 PNG 图像,然后分别设置每个图标 DIV 的背景图像呈现出当前的效果。其 CSS 代码如下。
      #top-sns a{background:url(img/icons-css.png) no-repeat left top;display:inline;float:right;height:28px;width:28px;background-position:0 0px;}
      #top-sns a.email{background-position:0 -28px;}
      #top-sns a.facebook{background-position:0px -84px;}
      #top-sns a.twitter{background-position:0px -56px;}
      #top-sns a.sns{background-position:0px -112px;}
      #top-sns a.buzz{background-position:0px -168px;}
      #top-sns a.gmail{background-position:0px -140px;}

      推荐使用基于 Adobe AIR 的 CSS Spirites 样式生成工具,只要在 PS 等图像工具中先排列好图标,再在这个工具中分别选定图像的区域大小便可以输出可用的 CSS 代码,十分便捷。另外就是要注意不是所有的图像都适用于用 CSS 来表现。

    • 合理使用 base64 图像。使用 base64 编码后的图像可以直接放入 CSS 文件中,省去了一次请求,如果有相似的图像使用 base64 合并在一起再 gzip,会减少不少的数据量。缺点是对图片的再编辑比较麻烦。示例:
      .bk {background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAIAAAD9iXMrAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAuElEQVQokWMUFRNjIAIwEaOIgYGBBYUn7JCebiUCYb85NmPWgbcwGUa4vcIOaRlqtxByasHVIQyr29beYmBgYGBg5ubmhgh7u/1aM+uAcHBVRqCtnSbztV3bd14TD/FiO3v9LZK9aroMB9a+FXZwfDuztQ1m29sD+986CDPceovuD2FhYRz+gNn79q9WsO7LXdtfGhdmBNra2WqyXDv7gMshROvZ4etvSfAHI0o4ExMu+AGx8UGsOgBjpEf4ldV7GAAAAABJRU5ErkJggg==');}

      实现难度:★★ ,加速效果:★★

    • 使用 WP Minify合并压缩 JavaScript,CSS,HTML 文件,其具体使用方法见http://xia.im/wp-minify/

    实现难度:★★ ,加速效果:★★★

  2. 减少传输文件大小
    • 开启网站 Gzip,这是最有效的减少传输数据量的方法,对 HTML,JavaScript,CSS 文件的压缩率很高。判断网站是否开启了 Gzip 可以到 Firebug 网络面板中,点击上述的任意文件,查看头信息 Tab 中的响应头信息,contenten-coding 为 Gzip 即为开启了 Gzip 功能。目前大多数服务器均默认开启了 Gzip,如果发现没有开启,可以在以"WordPress gzip" 为关键字进行搜索,在此不再累述。

      实现难度:★★☆ ,加速效果:★★★★

    • 对图像文件进行优化。网站主题中的图像文件,建议使用http://smush.it/或者 PageSpeed 中的压缩服务,这个功能可以在不降低图像质量的前提下尽量压缩图像文件。另外推荐除动态图像外均使用 PNG-8 格式储存图像,这种格式一般比 GIF 具有更高的压缩比。针对博客中上传的照片,推荐将图像分辨率调至 1024X768 以下,并使用 Advanced JPEG Compressor 优化,这个工具可以直观的对比压缩前后图像质量的变化,选项也很丰富,可以在可接受的前提下尽量减少图像的体积。如果有条件,也可以选择速度更快的图片托管服务。

      实现难度:★★☆ ,加速效果:★★★★

    • 精简无用的 JavaScript 代码和 CSS 代码。一般博客中需要加载许多 JavaScript 和 CSS,可是其中有些功能或样式我们的博客中用不到。这时可以将无用的代码删除或注释掉,再经过 WP Minify 处理后大小就能显著减小。以 WP-codebox 为例,在本博客中只需要显示代码的功能而已,代码框折叠等功能并不需要,所以可以将 WP-codebox 自带的 JavaScript 文件清空保存即可。

      实现难度:★★★☆ ,加速效果:★★☆

    • 使用 CDN 加速。可以使用 Cloudflare 等 CDN 服务,如果网站有良民证,使用国内的众多 CDN 服务也是可以的。如果没有条件使用 CDN,我们也可以对部分静态文件使用 CDN:一般 WordPress 博客都会加载 jQuery 等 JavaScript 库,使用 Google CDN 不仅可以减小服务器的负担,更重要的是由于其通用性,很可能访客的缓存中已经缓存了该 JavaScript 库,这样就避免了再次加载所需的时间。比如需要引用 1.4.4 版的 jQuery,只需要在 header.php 中适当位置加入
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.JavaScript"></script>

      使用外部 jQuery 库后还需要在前台禁止加载 WP 自带的 jQuery 库,需要修改 /wp-includes/script-loader.php,将:

      $scripts->add( 'jquery', '/wp-includes/JavaScript/jquery/jquery.JavaScript', false, '1.4.4');
      // 改为
      if(is_admin()){
      $scripts->add( 'jquery', '/wp-includes/JavaScript/jquery/jquery.JavaScript', false, '1.4.4');}

      不止 google,微软和新浪 SAE 都提供了 CDN 服务,通过下面的链接找到各库的地址,择快而选:
      微软 aspnetcdn:http://www.asp.net/ajaxlibrary/cdn.ashx
      新浪 SAE:http://lib.sinaapp.com/

      实现难度:★★ ,加速效果:★★★

    • 合理安排文件存放位置。根据 HTTP 协议和浏览器规定,对同一域名同时请求的数量是有限制的。所以合理的分散文件,将静态的、不常改变的文件存放在其他域名下,可能会提高一定的加载速度。需要注意的是也不可以使用过多的域名,否则将在 DNS 查询上浪费不少时间。

      实现难度:★★ ,加速效果:★★

    • 使用 WP Minify 合并压缩 JavaScript,CSS,HTML 文件,其具体使用方法见http://xia.im/wp-minify/

      实现难度:★★★ ,加速效果:★☆

小结:网络传输时间占据的时间最多,所以在精简文件数量和大小上多下功夫能产生明显的效果。合并压缩文件,启用 Gzip 后访问速度会有质的提升

客户端:

  1. 设定文件过期时间。设定比较适当的文件过期时间,可以减少再次访问的用户的时间。以 apache 为例,只要修改文件根目录下的 .htaccess 文件,在最后加入 
    ### mod_expires
    ExpiresActive On
    ExpiresByType application/x-shockwave-flash A2592000
    ExpiresByType image/x-icon A2592000
    ExpiresByType image/png A2592000
    ExpiresByType image/jpeg A2592000
    ExpiresByType image/gif A2592000
    ### mod_expires

    其中最后的 A2592000 表示过期秒数,范例中的值为一个月。中间是文件的 MIME 类型,application/x-shockwave-flash 表示 flash 文件,image/x-icon 表示 favicon.ico 文件,image/jpeg 表示 jpeg 和 jpg 文件。

    实现难度:★ ,加速效果:★★

  2. 避免降低性能的图像、JavaScript 和 CSS。以背景图像为例,可以在 CSS 设定图像得到 repeat 达到平铺的效果,但是如果平铺的图像分辨率过低。比如采用 1X1 像素,那么将会占用访客极大的 CPU 资源,相反采用 10X10 图像,资源占用将会有很大的下降。CSS 中要避免大量使用 text-shadow,box-shadow 等属性,这同样也会对访客的资源造成很大负担。此外,由于 IE 中 JavaScript 的执行效率较差,所以也要避免占用资源过大的 JavaScript,比如半透明、渐变等 JavaScript 效果。

    另外推荐一篇优化 JavaScript 执行效能的一篇文章:提高 web 应用性能之 JavaScript 性能调优

    实现难度:★★ ,加速效果:★★★

  3. 指定图像大小。图像的 HTML 代码一般为
    <img src="http://yoururl.com/image.gif" alt="image" />
    // 指定高度和宽度
    <img src="http://yoururl.com/image.gif" alt="image" width="120" height="90" />

    制定图像的高度和宽度,有利于减少浏览器渲染的时间,并可以在图像没有下载完成的情况下保持页面的结构,此外,尽量避免缩放图像,比如给一个 10X10 的图像指定高度和宽度为 5X5,这样会减慢浏览器的性能。

    实现难度:★ ,加速效果:☆

  4. 使用更有效率的 CSS 选择器。比如如下 DIV 结构
    <div class="div">
      <div id="div1"></div>
      <div class="div2"></div>
    </div>

    对于网页上唯一的 div1 来说,使用 #div1 就比 .div #div1 更有效率。
    另外特别推荐一篇优化 CSS 的技术文章:提高 web 应用性能之 CSS 性能调优

    实现难度:★★ ,加速效果:☆

  5. 避免不存在的链接。保证网页中的文件链接的有效性,可以避免返回 HTTP 404 等错误信息,防止时间的损耗。

    实现难度:★ ,加速效果:★★

  6. Cookie Free:当浏览器向服务器请求文件前,会先发送同域名下的 cookie,但是服务器对于这些 cookie 不会做任何处理。所以,除了尽量保持 cookie 体积小之外,还可以通过 Cookie Free 的手段避免请求时发送 cookie。如果博客首页为 http://xia.im/,则所有此域名下得二级域名都会发送此 cookie,这样的域名除了使用另外的域名来做 Cookie Free 之外没有别的办法了(我的博客就是这样)。如果博客首页为 http://www.xia.im/,那么 http://img.xia.im/ 的内容将不会发送 cookie,从而加快了速度。

    实现难度:★☆ ,加速效果:★★

小结:客户端除缓存设置外影响并不大,因为渲染往往都在几十到几百毫秒内即可完成。不过有些因素会明显拖慢用户的浏览器,加大 CPU 占用,这也是需要为访客考虑的。设置一个合理的文件过期时间,优化页面在浏览器上的性能表现

  1. 支持一下!很好的文章!! :smile:
    PS:歡迎訪問 AREFLY.COM~~ :biggrin:

  2. 呵呵,博主的这篇文章很给力,让我学到了不少给 WP 提速的技巧,回去好好试试,研究研究。
    插件我好像用了 3 个还是 4 个吧,Akismet,WP SUPER CACHE,ALL IN OEN SEO PACK,还有一个是很蛋疼的插件,就是给分类 url 后面添加 / 的,还不知道怎么用代码直接搞定这个斜杠……

  3. 太详尽了收益非浅啊,js 和 css 合并压缩真是感觉压力很大。 :oops:

  4. 博客刚建立,但访问速度实在不让人满意,我也去优化下 :razz:

  5. 我用了 22 个插件,算多吗?

    • @NoAnyLove
      22 个插件在 WordPress 博客里面应该算是中档吧,用 30+ 插件的人也不在少数~
      不同类型的插件对载入速度的影响也不相同,如果你不在意这点速度,可以尽情使用。如果在意,那就卸载掉一些不必要插件啦~

    • @小虾
      用了 Linost 的空间之后彻底弃用了 WP Minify 和 WP super cache,在本地测试的优化效果棒极了,结果上传到服务器发现速度还不如不用优化插件来得快。。。估计只有抽空手动优化了。准备手动合并一些 css 和 js,css 准备用 csstidy 处理,js 准备用 YUI Compressor。剩下的减少插件。。。呃,对于有选择恐慌的我来说这个才是准困难的,我很难衡量一个插件带来的方便特性和其消耗的资源的得失。。。。。。最后弃用了 Akismet,然后在纠结 Google Analytics for WordPress 和失效链接检查器这两个插件到底要还是不要。。。。。。。能给点建议吗?

    • @NoAnyLove
      放弃 Akismet 么,这个插件还是挺有用处的,好像只会在提交评论时激活。
      Google Analytics for WordPress,不知道这个插件对于手动复制统计代码有什么区别?如果区别不大的话就删除吧。
      失效链接检查器这个东西可以先停用,定期开启检查一下不知道是否可行?
      对于咱们这种小博客而言,还是方便更重要一些。我看了看你的博客,算是技术类博客吧,查找资料的人一般不会在意甚至不会感觉到半秒一秒的载入时间差异的。我最开始弄博客就是太在意这些,时间长了发现过于追求精简实在没有必要,在实用与性能之间找个平衡就行了。

    • @小虾
      弃用 Akismet 一个原因主要是我用了 mini-capatcha,一个验证码插件,另外一个原因是,我以为 Akismet 会非常消耗资源。Google Analytics for WordPress 这个插件我说不清楚与手动添加统计代码有什么区别,不过可以看到这个插件用了不少的 add_action 和 add_filter 。失效链接检查器这个插件感觉有点鸡肋,比较纠结。
      嗯,这个我也觉得,感觉花在折腾和纠结上面的时间比写文章的时间还多,比较汗颜啊。。。。。。 :oops:

    • @NoAnyLove
      选择和淘汰插件总会有个过程的,这个文章也正是我纠结的时候写的,现在看来有些地方还是过于较真了。 :appall:

    • @小虾
      其实有些地方的优化也就那么零点几秒的提升,总体来说差别不大,不过作为一个技术宅,我还是有点过分追求数据的怨念。。。。。。

  6. 使用了一些插件 表示速度还行

  7. [...]http://xia.im/wordpress-optimization/[...]