优化WordPress性能的高级指南

本文概述

  • 获取帖子
  • 充分利用WordPress选项
  • 启用永久缓存
  • AJAXing最快的方法
  • 消除WordPress变慢的观念
今天, WordPress为超过30%的Internet提供动力。它易于使用, 令人难以置信地受欢迎, 而且很快就不会出现在任何地方。
但是WordPress可能很慢。那么如何优化它呢?
关于如何优化和优化WordPress的文章很多。实际上, WordPress本身提供了有关WordPress优化的强大指南。
在大多数情况下, 这些文章和教程涵盖了非常基本但有用的概念, 例如使用缓存插件, 与内容交付网络(CDN)集成以及最小化请求。尽管这些技巧非常有效, 甚至是必要的, 但最终它们并没有解决潜在的问题:大多数速度慢的WordPress网站都是由于代码错误或效率低下造成的。
优化WordPress性能的高级指南

文章图片
WordPress可能很慢, 但不一定如此。
鸣叫
因此, 本文主要旨在为开发人员和WordPress开发公司提供一些指导, 以帮助他们解决许多WordPress性能问题的根本原因。
WordPress提供了许多面向性能的功能, 这些功能通常被开发人员所忽略。不利用这些功能的代码会减慢最简单的任务, 例如获取帖子。本文详细介绍了四种可能的解决方案, 这些解决方案解决了WordPress性能缓慢的背后的一些潜在问题。
获取帖子 WordPress提供了从数据库中获取任何形式的帖子的可能性。共有三种基本方法:
  • 使用query_posts()函数:这是一种非常直接的方法, 但是问题在于它会覆盖主查询, 这可能会带来不便。例如, 如果我们想在获取帖子后的某个时刻(例如footer.php内部)确定要处理的页面类型, 则可能会遇到问题。实际上, 官方文档中有一条注释建议不要使用此功能, 因为你将需要调用其他功能来还原原始查询。此外, 替换主查询将对页面加载时间产生负面影响。
  • 使用get_posts()函数:这几乎与query_posts()类似, 但它不会修改主查询。另一方面, 默认情况下, get_posts()在执行时将prevent_filters参数设置为true来执行查询。这可能导致不一致, 尤其是如果我们在代码中使用与查询相关的过滤器, 则此功能可能会返回你在页面中不希望看到的帖子。
  • 使用WP_Query类:我认为, 这是从数据库检索帖子的最佳方法。它不会更改主查询, 并且以其标准方式执行, 就像其他任何WordPress查询一样。
但是, 无论我们使用哪种方法与数据库进行交互, 都需要考虑其他事项。
限制查询
我们应该始终指定查询必须提取多少个帖子。
为此, 我们使用posts_per_page参数。
WordPress让我们将-1表示为该参数的可能值, 在这种情况下, 系统将尝试获取所有符合定义条件的帖子。
即使我们确定只能得到一些结果作为回应, 这也不是一个好习惯。
首先, 我们很少能确定只能获得一些结果。即使可以, 不设置限制也将要求数据库引擎扫描整个数据库以查找匹配项。
相反, 限制结果通常会使数据库引擎仅部分扫描数据, 从而缩短了处理时间并提高了响应速度。
WordPress默认情况下会做的另一件事可能会对性能产生不利影响, 它会尝试发布粘性帖子并计算在查询中找到多少行。
不过, 通常我们实际上并不需要这些信息。添加这两个参数将禁用这些功能并加快查询速度:
$query = new WP_Query( array( 'ignore_sticky_posts' => true, 'no_found_rows'=> true ) );

从查询中排除帖子
优化WordPress性能的高级指南

文章图片
有时我们想从查询中排除某些帖子。 WordPress提供了一种非常直接的实现方法:使用post__not_in参数。例如:
$posts_to_exclude= array( 1, 2, 3 ); $posts_per_page = 10; $query = new WP_Query( array( 'posts_per_page' => $posts_per_page, 'post__not_in'=> $posts_to_exclude ) ); for ( $i = 0; $i < count( $query-> posts ); $i++ ) { //do stuff with $query-> posts[ $i ] }

但这虽然很简单, 但却不是最佳选择, 因为它会在内部生成子查询。特别是在大型安装中, 这可能会导致响应变慢。通过一些简单的修改, 使PHP解释器可以更快地完成该处理:
$posts_to_exclude= array( 1, 2, 3 ); $posts_per_page = 10; $query = new WP_Query( array( 'posts_per_page' => $posts_per_page + count( $posts_to_exclude ) ) ); for ( $i = 0; $i < count( $query-> posts ) & & $i < $posts_per_page; $i++ ) { if ( ! in_array( $query-> posts[ $i ]-> ID, $posts_to_exclude ) ) { //do stuff with $query-> posts[ $i ] } }

我在那里做什么?
基本上, 我从数据库引擎中删除了一些工作, 然后将其留给了PHP引擎, 该引擎执行相同的工作, 但是在内存中的速度更快。
怎么样?
首先, 我从查询中删除了post__not_in参数。
由于查询可能会给我们带来一些我们不想要的帖子, 因此我增加了posts_per_page参数。这样, 即使在响应中有一些我不想要的帖子, 我也可以确保那里至少有$ posts_per_page个所需的帖子。
然后, 当我遍历帖子时, 我只会处理那些不在$ posts_to_exclude数组中的帖子。
避免复杂的参数化
所有这些查询方法都提供了多种获取帖子的可能性:按类别, 按元键或值, 按日期, 按作者等。
尽管灵活性是一项强大的功能, 但应谨慎使用, 因为参数化可能会转化为复杂的表联接和昂贵的数据库操作。
在下一节中, 我们将概述一种优雅的方法, 可以在不影响性能的情况下仍实现类似的功能。
充分利用WordPress选项 WordPress选项API提供了一系列工具, 可轻松加载或保存数据。这对于处理少量信息非常有用, 而WordPress提供的其他机制(如帖子或分类法)过于复杂, 因此对这些信息来说非常有用。
优化WordPress性能的高级指南

文章图片
例如, 如果我们要存储身份验证密钥或网站标题的背景颜色, 则需要使用选项。
WordPress不仅为我们提供了处理它们的功能, 而且还使我们能够以最有效的方式进行处理。
某些选项甚至在系统启动时直接加载, 从而为我们提供了更快的访问权限(创建新选项时, 我们需要考虑是否要自动加载它)。
例如, 考虑一个站点, 我们在该站点上有一个显示后端指定的突发新闻的轮播。我们的第一个直觉是为此使用一个元密钥, 如下所示:
// functions.php add_action( 'save_post', function ( $post_id ) { // For simplicity, we do not include all the required validation before saving // the meta key: checking nonces, checking post type and status, checking // it is not a revision or an autosaving, etc. update_post_meta( $post_id, 'is_breaking_news', ! empty ( $_POST['is_breaking_news'] ) ); } ); // front-page.php $query = new WP_Query( array( 'posts_per_page' => 1, 'meta_key'=> 'is_breaking_news' ) ); $breaking_news = $query-> posts[0] ?: NULL;

如你所见, 此方法非常简单, 但不是最佳方法。它将执行数据库查询, 尝试查找具有特定元键的帖子。我们可以使用一个选项来实现类似的结果:
// functions.php add_action( 'save_post', function ( $post_id ) { // Same comment for post validation if ( ! empty ( $_POST['is_breaking_news'] ) ) update_option( 'breaking_news_id', $post_id ); } ); // front-page.php if ( $breaking_news_id = get_option( 'breaking_news_id' ) ) $breaking_news = get_post( $breaking_news_id ); else $breaking_news = NULL;

每个示例的功能略有不同。
在第一段代码中, 我们将始终获得有关最新消息的最新消息, 以发布的日期为准。
在第二篇文章中, 每次将新帖子设置为突发新闻时, 它将覆盖以前的突发新闻。
但是因为我们可能一次想要一个最新新闻, 所以这应该不是问题。
最后, 我们将繁重的数据库查询(使用带有元键的WP_Query)更改为简单直接的查询(调用get_post()), 这是一种更好, 性能更高的方法。
我们还可以进行一些小的更改, 并使用瞬态代替选项。
瞬态的工作原理类似, 但允许我们指定到期时间。
例如, 对于突发新闻, 它就像手套一样适合, 因为我们不希望将旧帖子作为突发新闻, 并且如果我们将更改或消除突发新闻的任务留给管理员, 他可能会忘记做它。因此, 通过两个简单的更改, 我们添加了一个到期日期:
// functions.php add_action( 'save_post', function ( $post_id ) { // Same comment for post validation // Let's say we want that breaking news for one hour // (3600 =# of seconds in an hour). if ( ! empty ( $_POST['is_breaking_news'] ) ) set_transient( 'breaking_news_id', $post_id, 3600 ); } ); // front-page.php if ( $breaking_news_id = get_transient( 'breaking_news_id' ) ) $breaking_news = get_post( $breaking_news_id ); else $breaking_news = NULL;

启用永久缓存 WordPress本身具有对象缓存机制。
例如, 使用该机制来缓存选项。
【优化WordPress性能的高级指南】但是, 默认情况下, 该缓存不是持久性的, 这意味着它仅在单个请求期间有效。所有数据都缓存在内存中, 以加快访问速度, 但仅在该请求期间可用。
优化WordPress性能的高级指南

文章图片
要支持持久性缓存, 需要安装持久性缓存插件。
一些全页缓存插件包括一个永久性缓存插件(例如W3 Total Cache), 但是其他没有, 我们需要单独安装。
这将取决于我们平台的体系结构, 无论我们将使用文件, Memcached还是其他某种机制来存储缓存的数据, 但我们都应该利用这一惊人的功能。
有人会问:” 如果这是一个很棒的功能, 为什么WordPress默认不启用它” ?
主要原因是, 根据我们平台的体系结构, 某些缓存技术将起作用, 而另一些则不能。
例如, 如果我们将站点托管在分布式服务器中, 则应该使用外部缓存系统(例如Memcached服务器), 但是如果我们的网站位于单个服务器上, 则只需使用文件系统就可以节省一些钱。缓存。
我们需要考虑的一件事是缓存过期。这是使用持久缓存的最常见陷阱。
如果我们未能正确解决此问题, 我们的用户将抱怨他们看不到所做的更改, 或者更改时间太长而无法应用。
有时我们会发现自己需要在性能和动态性之间做出权衡, 但是即使有这些障碍, 持久缓存实际上也是每个WordPress安装都应该利用的东西。
AJAXing最快的方法 如果我们需要通过AJAX与我们的网站进行通信, 则WordPress在服务器端处理请求时会提供一些抽象。
即使可以在对后端工具进行编程或从前端进行表单提交时使用这些技术, 但如果并非绝对必要, 则应避免使用这些技术。
这样做的原因是, 为了使用这些机制, 我们必须对wp-admin文件夹中的某个文件发出发布请求。大部分WordPress全页缓存插件(如果不是全部)既不缓存发布请求, 也不缓存对管理员文件的调用。
例如, 如果我们在用户滚动我们的主页时动态加载更多帖子, 则最好直接调用其他前端页面, 这将得到缓存的好处。
然后, 我们可以在浏览器中通过JavaScript解析结果。
是的, 我们发送的数据超出了我们的需要, 但是在处理速度和响应时间方面我们赢得了胜利。
消除WordPress变慢的观念 这些只是开发人员在为WordPress编码时应考虑的一些建议。
有时, 我们忘记了我们的插件或主题可能需要与其他插件一起使用, 或者我们的站点可能由托管公司提供服务, 该公司为成百上千个具有公共数据库的其他站点提供服务。
我们只关注插件应如何工作, 而不关注它如何处理该功能, 或如何有效地进行操作。
从上面可以明显看出, WordPress性能不佳的根本原因是不良且效率低下的代码。但是, WordPress通过其各种API提供了所有必要的功能, 这些功能可以帮助我们构建性能更高的插件和主题, 而不会影响整个平台的速度。

    推荐阅读