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

Ability is needed to capture styles of elements to ensure proper optimization #1892

Open
westonruter opened this issue Feb 26, 2025 · 2 comments
Labels
[Plugin] Image Prioritizer Issues for the Image Prioritizer plugin (dependent on Optimization Detective) [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Enhancement A suggestion for improvement of an existing feature

Comments

@westonruter
Copy link
Member

Sometimes the Intersection Observer doesn't provide all of the information needed in order to perform optimizations. For example, images which have visibility:hidden, display:none, or opacity:0 should in theory get fetchpriority=low when they are in the initial viewport per #1587, but these won't

Conversely, from #1308 (comment), images which are inside of elements which have content-visibility:auto will have a zeroed-out boundingClientRect which Image Prioritizer then interprets as being in the initial viewport (since the boundingClientRect.top of 0 is less than viewport.height) and so they are getting fetchpriority=low when they should actually get loading=lazy.

These issues should perhaps have a way to efficiently query the computed style of certain elements to store their properties with the element in URL Metrics. There could be an async getComputedStyle function exported to the initialize and finalize async functions in extensions which could include some additional performance safeguards, like returning a Promise that involves requestAnimationFrame() or maybe even first requestIdleCallback(). Calling getComputedStyle() can trigger a layout calculation (reflow), so we need to be careful to not negatively impact the performance of the page.

I put together a Codepen that shows what Intersection Observer reports for various scenarios: https://codepen.io/westonruter/pen/zxYoNJP?editors=1111

Notice importantly that elements with visibility:hidden and opacity:0 are considered fully visible as far as Intersection Observer is concerned, leading to them not getting fetchpriority=low. And notice how the element with content-visibility:auto has a boundingClientRect with zeroed out values, leading it to not get loading=lazy by Image Prioritizer.

In addition to the possibility of a new JS API, we should extend the element schema to include a computedStyle object. In fact, let's say instead of getComputedStyle() there was a captureElementStyles() function passed to initialize and finalize. It could take two args: the XPath of the element and an array of the styles properties to capture from the computed style. This could then automatically extend the computedStyle object of the element. Since the computedStyle object would be a core property it would not be available for extendElementData() to override. Image Prioritizer should do the computed style capturing should be done during initialize, since we want to know whether an image is visible up front.

@westonruter westonruter added [Plugin] Image Prioritizer Issues for the Image Prioritizer plugin (dependent on Optimization Detective) [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Enhancement A suggestion for improvement of an existing feature labels Feb 26, 2025
@github-project-automation github-project-automation bot moved this to Not Started/Backlog 📆 in WP Performance 2025 Feb 26, 2025
@westonruter
Copy link
Member Author

westonruter commented Feb 26, 2025

Also, we could consider avoiding the need to introduce any JS to capture the desired styles for an element. For example, the context object passed to the tag visitors has a track_tag() method on it. This could take an arg which is the array of style properties which should be captured automatically by Optimization Detective when it is measuring elements on the page. In this way, the new core property for the element schema should be initialComputedStyles. The tag visitor could then access that new property on the OD_Element object to do the correct optimizations. The list of style properties which should be captured can be added to a data-od-initial-styles meta attribute which can then be read from the DOM.

@westonruter
Copy link
Member Author

Helpful article I had open in a tab about efficiency reading computer styles: https://webperf.tips/tip/layout-thrashing/

Since we're not doing any writes to the DOM during detection, we shouldn't be at fault for any layout thrashing. But using rAF seems like a good idea anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Plugin] Image Prioritizer Issues for the Image Prioritizer plugin (dependent on Optimization Detective) [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Enhancement A suggestion for improvement of an existing feature
Projects
Status: To Do 🔧
Development

No branches or pull requests

1 participant