Make WordPress Core

Changeset 48422


Ignore:
Timestamp:
07/10/2020 03:12:00 PM (4 years ago)
Author:
adamsilverstein
Message:

Revisions: optimize performance when post has large number of revisions.

Improve speed and reduce the memory footprint when loading posts with many revisions.

  • Use a direct query in wp_get_post_autosave to avoid loading all revisions.
  • Query for IDs vs full objects in register_and_do_post_meta_boxes.

Props pdfernhout, johnnyb, miqrogroove, ocean90, senatorman, DBrumbaugh10Up, martijn-van-der-kooij, pavelevap, mackensen, mikeyarce, whyisjake.
Fixes #34560.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/meta-boxes.php

    r48352 r48422  
    14381438    $publish_callback_args = array( '__back_compat_meta_box' => true );
    14391439    if ( post_type_supports( $post_type, 'revisions' ) && 'auto-draft' !== $post->post_status ) {
    1440         $revisions = wp_get_post_revisions( $post->ID );
     1440        $revisions = wp_get_post_revisions( $post->ID, array( 'fields' => 'ids' ) );
    14411441
    14421442        // We should aim to show the revisions meta box only when there are revisions.
     
    14451445            $publish_callback_args = array(
    14461446                'revisions_count'        => count( $revisions ),
    1447                 'revision_id'            => key( $revisions ),
     1447                'revision_id'            => array_shift( $revisions ),
    14481448                '__back_compat_meta_box' => true,
    14491449            );
  • trunk/src/wp-includes/revision.php

    r48109 r48422  
    222222 * Retrieve the autosaved data of the specified post.
    223223 *
    224  * Returns a post object containing the information that was autosaved for the
     224 * Returns an object containing the information that was autosaved for the
    225225 * specified post. If the optional $user_id is passed, returns the autosave for that user
    226226 * otherwise returns the latest autosave.
     
    233233 */
    234234function wp_get_post_autosave( $post_id, $user_id = 0 ) {
    235     $revisions = wp_get_post_revisions( $post_id, array( 'check_enabled' => false ) );
    236 
    237     foreach ( $revisions as $revision ) {
    238         if ( false !== strpos( $revision->post_name, "{$post_id}-autosave" ) ) {
    239             if ( $user_id && $user_id != $revision->post_author ) {
    240                 continue;
    241             }
    242 
    243             return $revision;
    244         }
    245     }
    246 
    247     return false;
     235    global $wpdb;
     236
     237    $autosave_name = $post_id . '-autosave-v1';
     238    $user_id_query = ( 0 !== $user_id ) ? "AND post_author = $user_id" : null;
     239
     240    // Construct the autosave query
     241    $autosave_query = "
     242        SELECT *
     243        FROM $wpdb->posts
     244        WHERE post_parent = %d
     245        AND post_type = 'revision'
     246        AND post_status = 'inherit'
     247        AND post_name   = %s " . $user_id_query . '
     248        ORDER BY post_date DESC
     249        LIMIT 1';
     250
     251    $autosave = $wpdb->get_results(
     252        $wpdb->prepare(
     253            $autosave_query,
     254            $post_id,
     255            $autosave_name
     256        )
     257    );
     258
     259    if ( ! $autosave ) {
     260        return false;
     261    }
     262
     263    return $autosave[0];
    248264}
    249265
  • trunk/tests/phpunit/tests/ajax/CustomizeManager.php

    r48211 r48422  
    473473        $this->assertEquals( 'draft', $this->_last_response_parsed['data']['changeset_status'] );
    474474        $autosave_revision = wp_get_post_autosave( $post_id );
    475         $this->assertInstanceOf( 'WP_Post', $autosave_revision );
     475        $this->assertInstanceOf( 'stdClass', $autosave_revision );
    476476
    477477        $this->assertContains( 'New Site Title', get_post( $post_id )->post_content );
     
    700700        $this->assertNotWPError( $r );
    701701        $autosave_revision = wp_get_post_autosave( $wp_customize->changeset_post_id() );
    702         $this->assertInstanceOf( 'WP_Post', $autosave_revision );
     702        $this->assertInstanceOf( 'stdClass', $autosave_revision );
    703703        $this->assertContains( 'Foo', get_post( $wp_customize->changeset_post_id() )->post_content );
    704704        $this->assertContains( 'Bar', $autosave_revision->post_content );
  • trunk/tests/phpunit/tests/customize/manager.php

    r47663 r48422  
    18921892        // Verify that autosave happened.
    18931893        $autosave_revision = wp_get_post_autosave( $changeset_post_id, get_current_user_id() );
    1894         $this->assertInstanceOf( 'WP_Post', $autosave_revision );
     1894        $this->assertInstanceOf( 'stdClass', $autosave_revision );
    18951895        $this->assertContains( 'Draft Title', get_post( $changeset_post_id )->post_content );
    18961896        $this->assertContains( 'Autosave Title', $autosave_revision->post_content );
Note: See TracChangeset for help on using the changeset viewer.