Make WordPress Core


Ignore:
Timestamp:
09/29/2015 09:59:44 PM (9 years ago)
Author:
boonebgorges
Message:

Improve lazyloading of term metadata in WP_Query loops.

[34529] introduced lazyloading for the metadata belonging to terms matching
posts in the main WP_Query. The current changeset improves this technique
in the following ways:

  • Term meta lazyloading is now performed on the results of all WP_Query queries, not just the main query.
  • Fewer global variable touches and greater encapsulation.
  • The logic for looping through posts to identify terms is now only performed once per WP_Query.

Props dlh, boonebgorges.
See #34047.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/taxonomy-functions.php

    r34679 r34704  
    15901590
    15911591/**
    1592  * Lazy-loads termmeta when inside of a `WP_Query` loop.
    1593  *
    1594  * As a rule, term queries (`get_terms()` and `wp_get_object_terms()`) prime the metadata cache for matched terms by
    1595  * default. However, this can cause a slight performance penalty, especially when that metadata is not actually used.
    1596  * In the context of a `WP_Query` loop, we're able to avoid this potential penalty. `update_object_term_cache()`,
    1597  * called from `update_post_caches()`, does not 'update_term_meta_cache'. Instead, the first time `get_term_meta()` is
    1598  * called from within a `WP_Query` loop, the current function detects the fact, and then primes the metadata cache for
    1599  * all terms attached to all posts in the loop, with a single database query.
    1600  *
    1601  * @since 4.4.0
    1602  *
    1603  * @param null $check   The `$check` param passed from the 'pre_term_metadata' hook.
    1604  * @param int  $term_id ID of the term whose metadata is being cached.
    1605  * @return null In order not to short-circuit `get_metadata()`.
    1606  */
    1607 function wp_lazyload_term_meta( $check, $term_id ) {
    1608     global $wp_query;
    1609 
    1610     if ( $wp_query instanceof WP_Query && ! empty( $wp_query->posts ) && $wp_query->get( 'update_post_term_cache' ) ) {
    1611         // We can only lazyload if the entire post object is present.
    1612         $posts = array();
    1613         foreach ( $wp_query->posts as $post ) {
    1614             if ( $post instanceof WP_Post ) {
    1615                 $posts[] = $post;
    1616             }
    1617         }
    1618 
    1619         if ( empty( $posts ) ) {
    1620             return;
    1621         }
    1622 
    1623         // Fetch cached term_ids for each post. Keyed by term_id for faster lookup.
    1624         $term_ids = array();
    1625         foreach ( $posts as $post ) {
    1626             $taxonomies = get_object_taxonomies( $post->post_type );
    1627             foreach ( $taxonomies as $taxonomy ) {
    1628                 // No extra queries. Term cache should already be primed by 'update_post_term_cache'.
    1629                 $terms = get_object_term_cache( $post->ID, $taxonomy );
    1630                 if ( false !== $terms ) {
    1631                     foreach ( $terms as $term ) {
    1632                         if ( ! isset( $term_ids[ $term->term_id ] ) ) {
    1633                             $term_ids[ $term->term_id ] = 1;
    1634                         }
    1635                     }
    1636                 }
    1637             }
    1638         }
    1639 
    1640         if ( $term_ids ) {
    1641             update_termmeta_cache( array_keys( $term_ids ) );
    1642         }
    1643     }
    1644 
    1645     return $check;
    1646 }
    1647 
    1648 /**
    16491592 * Check if Term exists.
    16501593 *
Note: See TracChangeset for help on using the changeset viewer.