Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

Page profiler never treats the detected LCP image as LCP, so it gets no fetchpriority="high" (stored ID is a string, compared with === to an int)

Offen Anfängerfreundlich
#1,202 3 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@girishpanchal30 arbeitet bereits daran.

Seit 29.10.2026.

  • #1213 von @girishpanchal30 — offen

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
88/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
javascript, php
Bereich
backend, performance

Rechercherichtung

Beginne bei inc/rest.php etwa bei Zeile 1032, wo die LCP-imageId über sanitize_text_field() gespeichert wird, und untersuche dann Profile.php:385-393, wo is_lcp_image_in_all_viewports() striktes === verwendet. Reproduziere es über das WP-CLI-Snippet oder den vorhandenen Test test_lazyload_viewport_with_lcp_data, der derzeit den REST-Pfad umgeht. Fertig bedeutet: Die gespeicherte ID ist ein int (oder wird vor dem Vergleich gecastet), die Methode gibt für beide Viewport-Profile true zurück, und der LCP-Zweig in tag_replacer.php fügt fetchpriority="high" hinzu.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

bug
Description

The page profiler detects the LCP image in the browser and sends its data-opt-id to /optimizations as an integer. The REST handler stores it with sanitize_text_field(), which always returns a string. Profile::is_lcp_image_in_all_viewports( int $image_id ) then compares that string to the int ID with ===, so it is always false.

Result, with the default "fixed|viewport" lazy load type and profile data stored for both devices:

  • Optimole never adds fetchpriority="high" to the LCP image (tag_replacer.php LCP branch is dead, and the fixed-count fallback is skipped because profile data exists).
  • If the LCP image is not in the above-the-fold list for both devices, it is lazy-loaded anyway (and any fetchpriority="high" on it is stripped).

Expected: the stored LCP image gets fetchpriority="high" and is never lazy-loaded. Likely fix: store absint( $lcp_data['i'] ?? 0 ) in inc/rest.php (or cast before comparing in Profile.php). Existing profiles in transients/object cache keep the string until they expire, so casting at compare time also covers those.

The unit test test_lazyload_viewport_with_lcp_data stores imageId as an int directly through Profile::store(), so it does not cover the REST path.

Step-by-step reproduction instructions
  1. On a test site with Optimole 4.2.17 connected and default Lazy Load settings, run this with WP-CLI (it stores LCP data the same way inc/rest.php:1032 does):
    wp eval '
    $p   = new OptimoleWP\PageProfiler\Profile();
    $img = 1578474861;
    $lcp = [ "imageId" => sanitize_text_field( $img ), "type" => "img" ];
    foreach ( [ 1, 2 ] as $d ) { $p->store( "bugcheck", $d, [], [], $lcp ); }
    OptimoleWP\PageProfiler\Profile::set_current_profile_id( "bugcheck" );
    $p->set_current_profile_data();
    var_dump( $p->is_lcp_image_in_all_viewports( $img ) );
    '
    
  2. Expected bool(true). Actual bool(false).
  3. Clean up: wp transient delete _oprof_bugcheck_1 && wp transient delete _oprof_bugcheck_2 (or flush the optimole_page_profiler cache group if an object cache is used).

End to end check on a real page: open a page with a large hero image once on desktop and once in mobile emulation so both profiles are stored, then reload and view source. The hero <img data-opt-id=...> has no fetchpriority="high" added by Optimole, and wp transient get _oprof_<profile id>_2 --format=json shows "imageId":"<id>" as a string.

Pure PHP reproduction of the same path (json_decode of the REST body, core _sanitize_text_fields cast, transient serialize round trip, the Profile.php:387 comparison), PHP 8.4:

REST param l.i type: integer
[transient] stored imageId='1578474861' (string), page image_id=1578474861 (integer) -> is_lcp_image_in_all_viewports=false; loose == would be true
[object-cache-json] stored imageId='1578474861' (string), page image_id=1578474861 (integer) -> is_lcp_image_in_all_viewports=false; loose == would be true
Screenshots, screen recording, code snippet or Help Scout ticket

Browser sends an int: https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/assets/js/modules/lcp.js#L88-L92

lcpData.imageId = parseInt(id, 10);

REST handler stores a string: https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/rest.php#L1032

$sanitized_lcp_data['imageId'] = sanitize_text_field( $lcp_data['i'] ?? '' );

Strict compare with the int data-opt-id: https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/v2/PageProfiler/Profile.php#L385-L393

public function is_lcp_image_in_all_viewports( int $image_id ): bool {
    ...
    ( ( self::$current_profile_data[ $device ]['lcp']['imageId'] ?? null ) === $image_id )

Callers that never fire:

$image_id comes from get_id_by_url(), which returns rand() (an int): https://github.com/Codeinwp/optimole-wp/blob/v4.2.17/inc/app_replacer.php#L691-L697

Core: _sanitize_text_fields() casts to string: https://github.com/WordPress/WordPress/blob/7.1.3/wp-includes/formatting.php#L5708-L5713

Environment info
  • Optimole 4.2.17 (same code on master and back to 4.0.0)
  • WordPress 5.5 to 7.1 (_sanitize_text_fields() casts to string in 5.5, 6.8.3 and 7.1.3)
  • PHP 7.4 to 8.4 (strict === behaves the same on all)
  • Lazy load type "fixed|viewport" (default), page profiler enabled (default)
Is the issue you are reporting a regression

No. The string store and the strict compare are both present in 4.0.0.

Found while writing the WordPress compatibility checks for Optimole.

Vorherrschende Sprache
PHP
Sterne
74
Forks
14
Ø Merge
1 T. 22 Std.
Gemergte PRs (30 T.)
29

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus Codeinwp/optimole-wp

Alle Issues in Codeinwp/optimole-wp

Ähnliche Issues

Weitere Issues zu PHP

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.