WordPress: kiedy lazy loading źle zgaduje i jak go wyłączyć dla obrazu 🔥
WordPress dodaje loading="lazy" do obrazów, a obraz widoczny od razu po wejściu na stronę ładuje się przez to później i psuje LCP. WordPress Core sam pomija lazy loading dla pierwszych 3 elementów multimedialnych w treści i dodaje fetchpriority="high" dla kwalifikującego się obrazu. W większości przypadków nic nie musisz robić 🚀
Problem zaczyna się, gdy obraz above the fold (na pierwszym ekranie, zanim zaczniesz przewijać stronę) jest 4. elementem w treści: po kilku ikonach albo w układzie z kolumnami. WordPress Core liczy elementy, a nie to, co widać w oknie przeglądarki. Dwa sposoby, od prostszego.
Sposób 1: zwiększ próg (jedna linia PHP)
function my_theme_omit_loading_attr_threshold() {
return 5;
}
add_filter( 'wp_omit_loading_attr_threshold', 'my_theme_omit_loading_attr_threshold' );
Ustaw tyle, ile obrazów bywa above the fold na Twoich stronach. Funkcja ma nazwę, więc możesz ją odpiąć przez remove_filter. Próg działa na całej witrynie, więc za wysoka wartość wyłączy lazy loading obrazom, które na niego zasługują.
Sposób 2: przełącznik w bloku Obraz
Wybierz go, gdy redaktor ma decydować dla każdego obrazu osobno. Potrzebujesz dwóch rzeczy: przełącznika w edytorze i filtra PHP, który coś z nim zrobi.
Przełącznik w edytorze (JS)
WordPress Core rozszerza bloki przez filtry edytora (blocks.registerBlockType, editor.BlockEdit, blocks.getSaveContent.extraProps i inne), bez jednej funkcji do tego. Używam registerBlockExtension z pakietu 10up, który podpina je za Ciebie:
npm install @10up/block-components
import { registerBlockExtension } from '@10up/block-components';
import { __ } from '@wordpress/i18n';
import { InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ToggleControl } from '@wordpress/components';
const extraAttributes = {
lazyLoadingDisabled: {
type: 'boolean',
default: false,
},
};
const Edit = ( { attributes, setAttributes } ) => (
<InspectorControls>
<PanelBody title={ __( 'Additional Settings', 'my-theme' ) }>
<ToggleControl
label={ __( 'Disable image lazy loading', 'my-theme' ) }
help={ __( 'Use it for images above the fold.', 'my-theme' ) }
checked={ attributes.lazyLoadingDisabled }
onChange={ ( value ) => setAttributes( { lazyLoadingDisabled: value } ) }
/>
</PanelBody>
</InspectorControls>
);
const classNameGenerator = ( { lazyLoadingDisabled } ) =>
lazyLoadingDisabled ? 'no-lazyload' : '';
registerBlockExtension( 'core/image', {
extensionName: 'my-theme/disable-lazy-loading',
attributes: extraAttributes,
classNameGenerator,
Edit,
} );
classNameGeneratordodaje klasęno-lazyloaddo głównego elementu bloku, czyli do<figure>- Skrypt musi trafić do edytora przez
enqueue_block_editor_assets - Przełącznik pojawia się w panelu bloku Obraz, na karcie Ustawienia (ikona zębatki)
- Zamień
my-themena własny prefiks
Ustaw loading=”eager” (PHP)
Sama klasa niczego nie wyłącza. Filtr szuka <figure> z tą klasą i ustawia obrazowi loading="eager". WordPress Core nie nadpisuje atrybutów, które już są w znaczniku, więc lazy loading się nie doda:
function my_theme_image_disable_lazy_loading( $content ) {
$html = new WP_HTML_Tag_Processor( $content );
if ( $html->next_tag( array( 'class_name' => 'no-lazyload' ) ) && $html->next_tag( 'img' ) ) {
$html->set_attribute( 'loading', 'eager' );
}
return $html->get_updated_html();
}
add_filter( 'render_block_core/image', 'my_theme_image_disable_lazy_loading', 16 );
WP_HTML_Tag_Processordziała od WordPressa 6.2, arender_block_{nazwa}od 5.7- Priorytet 16, bo od WordPressa 6.4 blok Obraz z opcją „Powiększ po kliknięciu” ma własny filtr z priorytetem 15
Sprawdź
Otwórz źródło strony. Obraz above the fold ma mieć loading="eager" (albo brak lazy), a pozostałe loading="lazy". Pamiętaj, żeby zrobić test w Lighthouse przed zmianą i po niej, na tej samej stronie.
Który sposób wybierasz? Napisz w komentarzu, jak zmienił się LCP 👏