Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix logic for seeking during optimization loop to prevent emitting seek() notices #1376

Merged
merged 8 commits into from
Jul 19, 2024

Conversation

westonruter
Copy link
Member

@westonruter westonruter commented Jul 18, 2024

Summary

As observed by @thelovekesh, Optimization Detective is causing many notices to show up in the error log:

Function WP_HTML_Tag_Processor::seek was called incorrectly. Too many calls to seek() - this can lead to performance issues. (This message was added in version 6.2.0.)

This is due to my incorrect implementation of the optimization loop, where it is seeking back to the current tag after calling a visitor, even if that visitor never seeked (sought?) or called next_tag(). I guess HTML Tag Processor should actually short-circuit if the bookmark being seeked to is the same as the current cursor (bytes_already_parsed). In any case, we can work around this by exposing the seek_count with a getter and only seeking back to the current tag if the seek count has increased and doing the same by counting the number of times that next_token() was called and seeking back if it was incremented.

This also fixes a bug with a translation string I noticed.

optimization-detective

Important

Stable tag change: 0.4.0 → 0.4.1

svn status:

M       build/web-vitals.js
M       class-od-html-tag-processor.php
M       optimization.php
M       readme.txt
svn diff
Index: build/web-vitals.js
===================================================================
--- build/web-vitals.js	(revision 3121783)
+++ build/web-vitals.js	(working copy)
@@ -1 +1 @@
-var e,n,t,r,i,a=-1,o=function(e){addEventListener("pageshow",(function(n){n.persisted&&(a=n.timeStamp,e(n))}),!0)},c=function(){return window.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0]},u=function(){var e=c();return e&&e.activationStart||0},f=function(e,n){var t=c(),r="navigate";return a>=0?r="back-forward-cache":t&&(document.prerendering||u()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-"))),{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v3-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},s=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},d=function(e,n,t,r){var i,o;return function(a){n.value>=0&&(a||r)&&((o=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=o,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},l=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},p=function(e){var n=function(n){"pagehide"!==n.type&&"hidden"!==document.visibilityState||e(n)};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},v=function(e){var n=!1;return function(t){n||(e(t),n=!0)}},m=-1,h=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},g=function(e){"hidden"===document.visibilityState&&m>-1&&(m="visibilitychange"===e.type?e.timeStamp:0,T())},y=function(){addEventListener("visibilitychange",g,!0),addEventListener("prerenderingchange",g,!0)},T=function(){removeEventListener("visibilitychange",g,!0),removeEventListener("prerenderingchange",g,!0)},E=function(){return m<0&&(m=h(),y(),o((function(){setTimeout((function(){m=h(),y()}),0)}))),{get firstHiddenTime(){return m}}},C=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},L=[1800,3e3],b=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("FCP"),a=s("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(a.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries.push(e),t(!0)))}))}));a&&(t=d(e,i,L,n.reportAllChanges),o((function(r){i=f("FCP"),t=d(e,i,L,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},w=[.1,.25],S=function(e,n){n=n||{},b(v((function(){var t,r=f("CLS",0),i=0,a=[],c=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=a[0],t=a[a.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,a.push(e)):(i=e.value,a=[e])}})),i>r.value&&(r.value=i,r.entries=a,t())},u=s("layout-shift",c);u&&(t=d(e,r,w,n.reportAllChanges),p((function(){c(u.takeRecords()),t(!0)})),o((function(){i=0,r=f("CLS",0),t=d(e,r,w,n.reportAllChanges),l((function(){return t()}))})),setTimeout(t,0))})))},A={passive:!0,capture:!0},I=new Date,P=function(r,i){e||(e=i,n=r,t=new Date,k(removeEventListener),F())},F=function(){if(n>=0&&n<t-I){var i={entryType:"first-input",name:e.type,target:e.target,cancelable:e.cancelable,startTime:e.timeStamp,processingStart:e.timeStamp+n};r.forEach((function(e){e(i)})),r=[]}},M=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){P(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,A),removeEventListener("pointercancel",r,A)};addEventListener("pointerup",t,A),addEventListener("pointercancel",r,A)}(n,e):P(n,e)}},k=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,M,A)}))},D=[100,300],x=function(t,i){i=i||{},C((function(){var a,c=E(),u=f("FID"),l=function(e){e.startTime<c.firstHiddenTime&&(u.value=e.processingStart-e.startTime,u.entries.push(e),a(!0))},m=function(e){e.forEach(l)},h=s("first-input",m);a=d(t,u,D,i.reportAllChanges),h&&p(v((function(){m(h.takeRecords()),h.disconnect()}))),h&&o((function(){var o;u=f("FID"),a=d(t,u,D,i.reportAllChanges),r=[],n=-1,e=null,k(addEventListener),o=l,r.push(o),F()}))}))},B=0,R=1/0,H=0,N=function(e){e.forEach((function(e){e.interactionId&&(R=Math.min(R,e.interactionId),H=Math.max(H,e.interactionId),B=H?(H-R)/7+1:0)}))},O=function(){return i?B:performance.interactionCount||0},q=function(){"interactionCount"in performance||i||(i=s("event",N,{type:"event",buffered:!0,durationThreshold:0}))},j=[200,500],_=0,z=function(){return O()-_},G=[],J={},K=function(e){var n=G[G.length-1],t=J[e.interactionId];if(t||G.length<10||e.duration>n.latency){if(t)t.entries.push(e),t.latency=Math.max(t.latency,e.duration);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};J[r.id]=r,G.push(r)}G.sort((function(e,n){return n.latency-e.latency})),G.splice(10).forEach((function(e){delete J[e.id]}))}},Q=function(e,n){n=n||{},C((function(){var t;q();var r,i=f("INP"),a=function(e){e.forEach((function(e){e.interactionId&&K(e),"first-input"===e.entryType&&!G.some((function(n){return n.entries.some((function(n){return e.duration===n.duration&&e.startTime===n.startTime}))}))&&K(e)}));var n,t=(n=Math.min(G.length-1,Math.floor(z()/50)),G[n]);t&&t.latency!==i.value&&(i.value=t.latency,i.entries=t.entries,r())},c=s("event",a,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=d(e,i,j,n.reportAllChanges),c&&("interactionId"in PerformanceEventTiming.prototype&&c.observe({type:"first-input",buffered:!0}),p((function(){a(c.takeRecords()),i.value<0&&z()>0&&(i.value=0,i.entries=[]),r(!0)})),o((function(){G=[],_=O(),i=f("INP"),r=d(e,i,j,n.reportAllChanges)})))}))},U=[2500,4e3],V={},W=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("LCP"),a=function(e){var n=e[e.length-1];n&&n.startTime<r.firstHiddenTime&&(i.value=Math.max(n.startTime-u(),0),i.entries=[n],t())},c=s("largest-contentful-paint",a);if(c){t=d(e,i,U,n.reportAllChanges);var m=v((function(){V[i.id]||(a(c.takeRecords()),c.disconnect(),V[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return setTimeout(m,0)}),!0)})),p(m),o((function(r){i=f("LCP"),t=d(e,i,U,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,V[i.id]=!0,t(!0)}))}))}}))},X=[800,1800],Y=function e(n){document.prerendering?C((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},Z=function(e,n){n=n||{};var t=f("TTFB"),r=d(e,t,X,n.reportAllChanges);Y((function(){var i=c();if(i){var a=i.responseStart;if(a<=0||a>performance.now())return;t.value=Math.max(a-u(),0),t.entries=[i],r(!0),o((function(){t=f("TTFB",0),(r=d(e,t,X,n.reportAllChanges))(!0)}))}}))};export{w as CLSThresholds,L as FCPThresholds,D as FIDThresholds,j as INPThresholds,U as LCPThresholds,X as TTFBThresholds,S as getCLS,b as getFCP,x as getFID,Q as getINP,W as getLCP,Z as getTTFB,S as onCLS,b as onFCP,x as onFID,Q as onINP,W as onLCP,Z as onTTFB};
\ No newline at end of file
+var e,n,t,r,i,o=-1,a=function(e){addEventListener("pageshow",(function(n){n.persisted&&(o=n.timeStamp,e(n))}),!0)},c=function(){var e=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},u=function(){var e=c();return e&&e.activationStart||0},f=function(e,n){var t=c(),r="navigate";return o>=0?r="back-forward-cache":t&&(document.prerendering||u()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=t.type.replace(/_/g,"-"))),{name:e,value:void 0===n?-1:n,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:r}},s=function(e,n,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){var r=new PerformanceObserver((function(e){Promise.resolve().then((function(){n(e.getEntries())}))}));return r.observe(Object.assign({type:e,buffered:!0},t||{})),r}}catch(e){}},d=function(e,n,t,r){var i,a;return function(o){n.value>=0&&(o||r)&&((a=n.value-(i||0))||void 0===i)&&(i=n.value,n.delta=a,n.rating=function(e,n){return e>n[1]?"poor":e>n[0]?"needs-improvement":"good"}(n.value,t),e(n))}},l=function(e){requestAnimationFrame((function(){return requestAnimationFrame((function(){return e()}))}))},p=function(e){document.addEventListener("visibilitychange",(function(){"hidden"===document.visibilityState&&e()}))},v=function(e){var n=!1;return function(){n||(e(),n=!0)}},m=-1,h=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},g=function(e){"hidden"===document.visibilityState&&m>-1&&(m="visibilitychange"===e.type?e.timeStamp:0,T())},y=function(){addEventListener("visibilitychange",g,!0),addEventListener("prerenderingchange",g,!0)},T=function(){removeEventListener("visibilitychange",g,!0),removeEventListener("prerenderingchange",g,!0)},E=function(){return m<0&&(m=h(),y(),a((function(){setTimeout((function(){m=h(),y()}),0)}))),{get firstHiddenTime(){return m}}},C=function(e){document.prerendering?addEventListener("prerenderingchange",(function(){return e()}),!0):e()},b=[1800,3e3],S=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("FCP"),o=s("paint",(function(e){e.forEach((function(e){"first-contentful-paint"===e.name&&(o.disconnect(),e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries.push(e),t(!0)))}))}));o&&(t=d(e,i,b,n.reportAllChanges),a((function(r){i=f("FCP"),t=d(e,i,b,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,t(!0)}))})))}))},L=[.1,.25],w=function(e,n){n=n||{},S(v((function(){var t,r=f("CLS",0),i=0,o=[],c=function(e){e.forEach((function(e){if(!e.hadRecentInput){var n=o[0],t=o[o.length-1];i&&e.startTime-t.startTime<1e3&&e.startTime-n.startTime<5e3?(i+=e.value,o.push(e)):(i=e.value,o=[e])}})),i>r.value&&(r.value=i,r.entries=o,t())},u=s("layout-shift",c);u&&(t=d(e,r,L,n.reportAllChanges),p((function(){c(u.takeRecords()),t(!0)})),a((function(){i=0,r=f("CLS",0),t=d(e,r,L,n.reportAllChanges),l((function(){return t()}))})),setTimeout(t,0))})))},A=0,I=1/0,P=0,M=function(e){e.forEach((function(e){e.interactionId&&(I=Math.min(I,e.interactionId),P=Math.max(P,e.interactionId),A=P?(P-I)/7+1:0)}))},k=function(){"interactionCount"in performance||e||(e=s("event",M,{type:"event",buffered:!0,durationThreshold:0}))},F=[],D=new Map,x=0,R=function(){return(e?A:performance.interactionCount||0)-x},B=[],H=function(e){if(B.forEach((function(n){return n(e)})),e.interactionId||"first-input"===e.entryType){var n=F[F.length-1],t=D.get(e.interactionId);if(t||F.length<10||e.duration>n.latency){if(t)e.duration>t.latency?(t.entries=[e],t.latency=e.duration):e.duration===t.latency&&e.startTime===t.entries[0].startTime&&t.entries.push(e);else{var r={id:e.interactionId,latency:e.duration,entries:[e]};D.set(r.id,r),F.push(r)}F.sort((function(e,n){return n.latency-e.latency})),F.length>10&&F.splice(10).forEach((function(e){return D.delete(e.id)}))}}},q=function(e){var n=self.requestIdleCallback||self.setTimeout,t=-1;return e=v(e),"hidden"===document.visibilityState?e():(t=n(e),p(e)),t},O=[200,500],N=function(e,n){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(n=n||{},C((function(){var t;k();var r,i=f("INP"),o=function(e){q((function(){e.forEach(H);var n,t=(n=Math.min(F.length-1,Math.floor(R()/50)),F[n]);t&&t.latency!==i.value&&(i.value=t.latency,i.entries=t.entries,r())}))},c=s("event",o,{durationThreshold:null!==(t=n.durationThreshold)&&void 0!==t?t:40});r=d(e,i,O,n.reportAllChanges),c&&(c.observe({type:"first-input",buffered:!0}),p((function(){o(c.takeRecords()),r(!0)})),a((function(){x=0,F.length=0,D.clear(),i=f("INP"),r=d(e,i,O,n.reportAllChanges)})))})))},j=[2500,4e3],_={},z=function(e,n){n=n||{},C((function(){var t,r=E(),i=f("LCP"),o=function(e){n.reportAllChanges||(e=e.slice(-1)),e.forEach((function(e){e.startTime<r.firstHiddenTime&&(i.value=Math.max(e.startTime-u(),0),i.entries=[e],t())}))},c=s("largest-contentful-paint",o);if(c){t=d(e,i,j,n.reportAllChanges);var m=v((function(){_[i.id]||(o(c.takeRecords()),c.disconnect(),_[i.id]=!0,t(!0))}));["keydown","click"].forEach((function(e){addEventListener(e,(function(){return q(m)}),!0)})),p(m),a((function(r){i=f("LCP"),t=d(e,i,j,n.reportAllChanges),l((function(){i.value=performance.now()-r.timeStamp,_[i.id]=!0,t(!0)}))}))}}))},G=[800,1800],J=function e(n){document.prerendering?C((function(){return e(n)})):"complete"!==document.readyState?addEventListener("load",(function(){return e(n)}),!0):setTimeout(n,0)},K=function(e,n){n=n||{};var t=f("TTFB"),r=d(e,t,G,n.reportAllChanges);J((function(){var i=c();i&&(t.value=Math.max(i.responseStart-u(),0),t.entries=[i],r(!0),a((function(){t=f("TTFB",0),(r=d(e,t,G,n.reportAllChanges))(!0)})))}))},Q={passive:!0,capture:!0},U=new Date,V=function(e,i){n||(n=i,t=e,r=new Date,Y(removeEventListener),W())},W=function(){if(t>=0&&t<r-U){var e={entryType:"first-input",name:n.type,target:n.target,cancelable:n.cancelable,startTime:n.timeStamp,processingStart:n.timeStamp+t};i.forEach((function(n){n(e)})),i=[]}},X=function(e){if(e.cancelable){var n=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,n){var t=function(){V(e,n),i()},r=function(){i()},i=function(){removeEventListener("pointerup",t,Q),removeEventListener("pointercancel",r,Q)};addEventListener("pointerup",t,Q),addEventListener("pointercancel",r,Q)}(n,e):V(n,e)}},Y=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach((function(n){return e(n,X,Q)}))},Z=[100,300],$=function(e,r){r=r||{},C((function(){var o,c=E(),u=f("FID"),l=function(e){e.startTime<c.firstHiddenTime&&(u.value=e.processingStart-e.startTime,u.entries.push(e),o(!0))},m=function(e){e.forEach(l)},h=s("first-input",m);o=d(e,u,Z,r.reportAllChanges),h&&(p(v((function(){m(h.takeRecords()),h.disconnect()}))),a((function(){var a;u=f("FID"),o=d(e,u,Z,r.reportAllChanges),i=[],t=-1,n=null,Y(addEventListener),a=l,i.push(a),W()})))}))};export{L as CLSThresholds,b as FCPThresholds,Z as FIDThresholds,O as INPThresholds,j as LCPThresholds,G as TTFBThresholds,w as onCLS,S as onFCP,$ as onFID,N as onINP,z as onLCP,K as onTTFB};
\ No newline at end of file
Index: class-od-html-tag-processor.php
===================================================================
--- class-od-html-tag-processor.php	(revision 3121783)
+++ class-od-html-tag-processor.php	(working copy)
@@ -107,6 +107,7 @@
 	/**
 	 * Bookmark for the end of the HEAD.
 	 *
+	 * @todo Consider reserving this.
 	 * @since 0.4.0
 	 * @var string
 	 */
@@ -115,6 +116,7 @@
 	/**
 	 * Bookmark for the end of the BODY.
 	 *
+	 * @todo Consider reserving this.
 	 * @since 0.4.0
 	 * @var string
 	 */
@@ -177,6 +179,15 @@
 	private $buffered_text_replacements = array();
 
 	/**
+	 * Count for the number of times next_token() was called
+	 *
+	 * @since 0.4.1
+	 * @var int
+	 * @see self::next_token()
+	 */
+	private $next_token_count = 0;
+
+	/**
 	 * Finds the next tag.
 	 *
 	 * Unlike the base class, this subclass disallows querying. This is to ensure the breadcrumbs can be tracked.
@@ -247,6 +258,7 @@
 	 */
 	public function next_token(): bool {
 		$this->current_xpath = null; // Clear cache.
+		++$this->next_token_count;
 		if ( ! parent::next_token() ) {
 			$this->open_stack_tags    = array();
 			$this->open_stack_indices = array();
@@ -326,6 +338,18 @@
 	}
 
 	/**
+	 * Gets the number of times next_token() was called.
+	 *
+	 * @since 0.4.1
+	 * @see self::next_token()
+	 *
+	 * @return int Count of next_token() calls.
+	 */
+	public function get_next_token_count(): int {
+		return $this->next_token_count;
+	}
+
+	/**
 	 * Updates or creates a new attribute on the currently matched tag with the passed value.
 	 *
 	 * @inheritDoc
@@ -409,6 +433,18 @@
 	}
 
 	/**
+	 * Gets the number of times seek() was called.
+	 *
+	 * @since 0.4.1
+	 * @see self::seek()
+	 *
+	 * @return int Count of seek() calls.
+	 */
+	public function get_seek_count(): int {
+		return $this->seek_count;
+	}
+
+	/**
 	 * Sets a bookmark in the HTML document.
 	 *
 	 * @inheritDoc
@@ -539,8 +575,11 @@
 			}
 			if ( ! $this->has_bookmark( $bookmark ) ) {
 				$this->warn(
-					/* translators: %s is the bookmark name */
-					__( 'Unable to append markup to %s since the bookmark no longer exists.', 'optimization-detective' )
+					sprintf(
+						/* translators: %s is the bookmark name */
+						__( 'Unable to append markup to %s since the bookmark no longer exists.', 'optimization-detective' ),
+						$bookmark
+					)
 				);
 			} else {
 				$start = $this->bookmarks[ $bookmark ]->start;
Index: optimization.php
===================================================================
--- optimization.php	(revision 3121783)
+++ optimization.php	(working copy)
@@ -176,14 +176,18 @@
 	$visitors             = iterator_to_array( $tag_visitor_registry );
 	while ( $processor->next_open_tag() ) {
 		$did_visit = false;
-		$processor->set_bookmark( $current_tag_bookmark );
+		$processor->set_bookmark( $current_tag_bookmark ); // TODO: Should we break if this returns false?
+
 		foreach ( $visitors as $visitor ) {
-			$did_visit = $visitor( $tag_visitor_context ) || $did_visit;
+			$seek_count       = $processor->get_seek_count();
+			$next_token_count = $processor->get_next_token_count();
+			$did_visit        = $visitor( $tag_visitor_context ) || $did_visit;
 
-			// Since the visitor may have traversed HTML tags, we need to make sure we go back to this tag so that
-			// in the next iteration any relevant tag visitors may apply, in addition to properly setting the data-od-xpath
-			// on this tag below.
-			$processor->seek( $current_tag_bookmark );
+			// If the visitor traversed HTML tags, we need to go back to this tag so that in the next iteration any
+			// relevant tag visitors may apply, in addition to properly setting the data-od-xpath on this tag below.
+			if ( $seek_count !== $processor->get_seek_count() || $next_token_count !== $processor->get_next_token_count() ) {
+				$processor->seek( $current_tag_bookmark ); // TODO: Should this break out of the optimization loop if it returns false?
+			}
 		}
 		$processor->release_bookmark( $current_tag_bookmark );
 
Index: readme.txt
===================================================================
--- readme.txt	(revision 3121783)
+++ readme.txt	(working copy)
@@ -2,7 +2,7 @@
 
 Contributors: wordpressdotorg
 Tested up to: 6.6
-Stable tag:   0.4.0
+Stable tag:   0.4.1
 License:      GPLv2 or later
 License URI:  https://www.gnu.org/licenses/gpl-2.0.html
 Tags:         performance, optimization, rum
@@ -133,6 +133,16 @@
 
 == Changelog ==
 
+= 0.4.1 =
+
+**Enhancements**
+
+* Upgrade web-vitals.js from [v3.5.0](https://github.com/GoogleChrome/web-vitals/blob/main/CHANGELOG.md#v350-2023-09-28) to [v4.2.1](https://github.com/GoogleChrome/web-vitals/blob/main/CHANGELOG.md#v422-2024-07-17).
+
+**Bug Fixes**
+
+* Fix logic for seeking during optimization loop to prevent emitting seek() notices. ([1376](https://github.com/WordPress/performance/pull/1376))
+
 = 0.4.0 =
 
 **Enhancements**

@westonruter westonruter requested a review from felixarntz as a code owner July 18, 2024 20:54
@westonruter westonruter requested a review from thelovekesh July 18, 2024 20:54
Copy link

github-actions bot commented Jul 18, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: westonruter <[email protected]>
Co-authored-by: thelovekesh <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@westonruter westonruter added [Type] Bug An existing feature is broken [Plugin] Optimization Detective Issues for the Optimization Detective plugin labels Jul 18, 2024
@westonruter westonruter changed the title Fix/od seek Improve logic for seeking during optimization loop Jul 18, 2024
@westonruter westonruter changed the title Improve logic for seeking during optimization loop Fix logic for seeking during optimization loop to prevent emitting seek() notices Jul 18, 2024
@@ -309,6 +308,79 @@ public function data_provider_test_od_optimize_template_output_buffer(): array {
',
),

'many_images' => array(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😎

* @return int Count of seek() calls.
*/
public function get_seek_count(): int {
return $this->seek_count;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

static function () {
$tags = array();
for ( $i = 1; $i < WP_HTML_Tag_Processor::MAX_SEEK_OPS + 1; $i++ ) {
$tags[] = sprintf( '<img data-od-xpath="/*[1][self::HTML]/*[2][self::BODY]/*[%d][self::IMG]" src="https://example.com/foo.jpg" alt="Foo" width="1200" height="800" loading="lazy">', $i );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spiffy

Copy link
Member

@adamsilverstein adamsilverstein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch & fix!

@github-actions github-actions bot temporarily deployed to wp.org plugin: optimization-detective July 19, 2024 03:22 Destroyed
@westonruter westonruter merged commit f70b0a2 into trunk Jul 19, 2024
17 checks passed
@westonruter westonruter deleted the fix/od-seek branch July 19, 2024 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Bug An existing feature is broken
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants