*/ function astsp_performance_type_labels() { return array( 'front' => __( 'Homepage', 'astute-speed' ), 'single' => __( 'Articles', 'astute-speed' ), 'page' => __( 'Pages', 'astute-speed' ), 'archive' => __( 'Categories, tags and search', 'astute-speed' ), ); } /** * The switches on this page. * * @return array Setting => label, explanation. */ function astsp_performance_switches() { return array( 'lcp_image' => array( __( 'Load the featured image first', 'astute-speed' ), __( 'The first featured image on a page loads at once, at high priority, and is preloaded from the page head.', 'astute-speed' ) ), 'hero_image' => array( __( 'Preload the hero image', 'astute-speed' ), __( 'For sliders, page builders and lazy-load plugins: the first large image after the site header is preloaded, even while its address is hidden from the browser until a script runs.', 'astute-speed' ) ), 'delay_scripts' => array( __( 'Hold back ads and analytics', 'astute-speed' ), __( 'AdSense and Google Tag Manager load on the first scroll, tap or key press, or after a few seconds. Faster pages, slightly less ad and analytics coverage.', 'astute-speed' ) ), 'webp_sizes' => array( __( 'Save resized copies as WebP', 'astute-speed' ), __( 'New uploads: the copies phones download are WebP, about a third smaller. The original keeps its format.', 'astute-speed' ) ), ); } /** * Save the posted form, or run the check. * * @return string '' when nothing was posted, otherwise a notice to show. */ function astsp_performance_maybe_save() { $nonce = isset( $_POST['astsp_performance_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['astsp_performance_nonce'] ) ) : ''; if ( ! $nonce || ! wp_verify_nonce( $nonce, 'astsp_performance_save' ) || ! current_user_can( 'manage_options' ) ) { return ''; } if ( isset( $_POST['astsp_performance_check'] ) ) { astsp_hero_check_site(); return __( 'Checked. The results are below.', 'astute-speed' ); } $settings = array(); foreach ( array_keys( astsp_performance_switches() ) as $key ) { $settings[ $key ] = isset( $_POST[ 'astsp_performance_' . $key ] ); } update_option( 'astsp_performance', $settings, true ); $hero = array(); foreach ( ASTSP_HERO_TYPES as $type ) { $url = isset( $_POST[ 'astsp_hero_' . $type ] ) ? esc_url_raw( trim( wp_unslash( $_POST[ 'astsp_hero_' . $type ] ) ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- esc_url_raw sanitizes. if ( '' !== $url ) { $hero[ $type ] = $url; } } update_option( 'astsp_performance_hero', $hero, true ); if ( function_exists( 'astsp_ccss_purge_cache' ) ) { astsp_ccss_purge_cache(); } return __( 'Settings saved. The page cache was emptied.', 'astute-speed' ); } /** * The sentence "contact the Write & Grow team", linked when the address is known. * * @return string HTML. */ function astsp_performance_contact_html() { $url = astsp_support_url(); $text = esc_html__( 'contact the Write & Grow team', 'astute-speed' ); return '' !== $url ? '' . $text . '' : $text; } /** * What one check result means for the site owner. * * @param array $result A diagnosis from astsp_hero_check_site(). * @return array{0: string, 1: string} Notice type (success|warning|error), HTML message. */ function astsp_performance_result_message( array $result ) { $contact = astsp_performance_contact_html(); $url = isset( $result['url'] ) ? '' . esc_html( wp_basename( (string) wp_parse_url( $result['url'], PHP_URL_PATH ) ) ) . '' : ''; switch ( $result['status'] ) { case 'featured': return array( 'success', esc_html__( 'Handled: the image at the top is preloaded from the page head.', 'astute-speed' ) ); case 'preloaded': if ( 'slider' === ( $result['kind'] ?? '' ) ) { /* translators: %s: image file name. */ $msg = sprintf( esc_html__( 'Partly handled: the slider\'s first image (%s) is preloaded, so it downloads straight away, but the slider still shows it only after its own script has run. To remove that wait, turn off Lazy Load for this slider in its settings, or replace the slider with a static image.', 'astute-speed' ), $url ); /* translators: %s: "contact the Write & Grow team", linked. */ return array( 'warning', $msg . ' ' . sprintf( esc_html__( 'That part can\'t be done by the plugin: %s and we\'ll update this site for you.', 'astute-speed' ), $contact ) ); } /* translators: %s: image file name. */ return array( 'success', sprintf( esc_html__( 'Handled: the hero image (%s) is preloaded from the page head.', 'astute-speed' ), $url ) ); case 'found': /* translators: %s: image file name. */ return array( 'warning', sprintf( esc_html__( 'The hero image (%s) isn\'t preloaded yet. Switch on "Preload the hero image" and save, then check again. If it still isn\'t, a page cache may be serving an older copy: empty it.', 'astute-speed' ), $url ) ); case 'none': /* translators: %s: "contact the Write & Grow team", linked. */ return array( 'error', sprintf( esc_html__( 'No image at the top of this page\'s HTML. If the first screen is mostly text, there\'s nothing to fix. If there is a large image, it comes from a stylesheet or a script, which the plugin can\'t reach: enter its address below if you know it, or %s and we\'ll fix this site by hand.', 'astute-speed' ), $contact ) ); default: /* translators: %s: the error. */ return array( 'error', sprintf( esc_html__( 'Couldn\'t open this page to check it (%s).', 'astute-speed' ), esc_html( (string) ( $result['error'] ?? '' ) ) ) ); } } /** * Render the page. * * @return void */ function astsp_performance_render_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $notice = astsp_performance_maybe_save(); $labels = astsp_performance_type_labels(); $fixed = astsp_hero_fixed_urls(); $check = (array) get_option( 'astsp_performance_hero_check', array() ); echo '
'; echo '

' . esc_html__( 'Page Speed', 'astute-speed' ) . '

'; echo '

' . esc_html__( 'Largest Contentful Paint is how long the biggest thing on the first screen takes to appear, usually an image. These settings get that image downloading as early as possible.', 'astute-speed' ) . '

'; if ( $notice ) { echo '

' . esc_html( $notice ) . '

'; } echo '
'; wp_nonce_field( 'astsp_performance_save', 'astsp_performance_nonce' ); echo '

' . esc_html__( 'What Astute Speed can do for each page type', 'astute-speed' ) . '

'; if ( empty( $check['results'] ) ) { echo '

' . esc_html__( 'Not checked yet. The check opens a page of each type as a visitor would and looks at the top of it.', 'astute-speed' ) . '

'; } else { /* translators: %s: date and time. */ echo '

' . esc_html( sprintf( __( 'Checked %s (UTC).', 'astute-speed' ), $check['at'] ) ) . '

'; echo ''; foreach ( $check['results'] as $type => $result ) { list( $kind, $message ) = astsp_performance_result_message( (array) $result ); $colour = array( 'success' => '#00a32a', 'warning' => '#dba617', 'error' => '#d63638', )[ $kind ]; echo ''; echo ''; } echo '
' . esc_html( $labels[ $type ] ?? $type ) . '
' . esc_html( (string) wp_parse_url( $result['url_checked'] ?? '', PHP_URL_PATH ) ) . '
' . wp_kses_post( $message ) . '
'; } echo '

'; echo '

' . esc_html__( 'Settings', 'astute-speed' ) . '

'; foreach ( astsp_performance_switches() as $key => $text ) { echo ''; } echo ''; echo '

' . esc_html__( 'Hero image by hand', 'astute-speed' ) . '

'; echo '

' . esc_html__( 'Only when the check finds no image, or the wrong one: the address of the image at the top of that kind of page. Leave empty to let Astute find it.', 'astute-speed' ) . '

'; echo ''; foreach ( ASTSP_HERO_TYPES as $type ) { echo ''; } echo ''; submit_button( __( 'Save settings', 'astute-speed' ) ); echo '
'; astsp_errlog_render_box(); echo '
'; }