wp-media / rocket-scripts

MIT License
0 stars 0 forks source link

Adjust the LRC beacon feature to requirements and by relying on PHP for depth & element identifications #25

Closed MathieuLamiot closed 1 month ago

MathieuLamiot commented 2 months ago

Context As spotted by @wordpressfan, the current JS implementation of the LRC feature is quite complex with many recurring calls to explore depth of elements. However, part of the exploration logic is handled PHP side and it would be best to keep it there to simplify maintenance: PHP already handles identifying the LRC candidates based on element type and depth.

Also, a discrepancy in the currently implemented behavior and the expected one by @wp-media/product has been identified and discussed here: https://wp-media.slack.com/archives/CUT7FLHF1/p1724431781878999?thread_ts=1724430625.686259&cid=CUT7FLHF1 The changes required to adapt the behavior should enable to simplify the JS logic on depth and parent/child.

Expected behavior

Acceptance Criteria

The following section hashes must be in the results, and only them: F, G, J

MathieuLamiot commented 2 months ago

Early discussion to maybe consider at grooming: https://wp-media.slack.com/archives/CUT7FLHF1/p1724430625686259

DahmaniAdame commented 2 months ago

All what you shared @MathieuLamiot is what is expected.

For items to be included, the logic is as follow:

That same logic applies to children as well. Meaning, if a child is added, there is no need to check or add its children, and so on.

Here is example with the expected behavior for each item:

--------- BEGINNING OF PAGE/VIEWPORT ----------
BODY
     TAG [hash=a] ❌ (above threshold) [⚙️ check children]
          TAG [hash=b] ❌ (above threshold)
--------- END OF VIEWPORT (for reference, shouldn't affect how the check is done as it's based on the threshold = distance of the element from the top of the page)
          TAG [hash=c] ❌ (above  threshold) [⚙️ check children]
               TAG [hash=d] ❌ (above threshold)
--------- END OF THRESHOLD
                    TAG [hash=e] ✔️ (below threshold)
               TAG [hash=f] ✔️ (below threshold)
          TAG [hash=g] ✔️ (below threshold) [⚙️ skip checking children]
               TAG [hash=h] ❌ (parent already added)
     TAG [hash=i] ✔️ (below threshold) [⚙️ skip checking children]
          TAG [hash=j] ❌ (parent already added)
               TAG [hash=k] ❌ (parent already added)
                    TAG [hash=l] ❌ (parent already added)
               TAG [hash=m] ❌ (parent already added)
     TAG [hash=n] ✔️ (below threshold) [⚙️ skip checking children]
          TAG [hash=o] ❌ (parent already added)
               TAG [hash=p] ❌ (parent already added)
     TAG [hash=q] ✔️ (below threshold)
--------- END OF PAGE --------------------

e, f, g, i, n, q are the only items to be included.

Regarding the threshold, I read you mentioning below the fold + threshold.

To avoid any confusion, the check is done from the top of page. So, technically, the threshold includes the viewport.

Let us know if you need further clarification or AC.

cc @piotrbak

jeawhanlee commented 2 months ago

Scope a solution ✅

I see 2 sides to update, both JS & PHP

JS

In PHP WP_Rocket\Engine\Optimization\LazyRenderContent\Frontend\Controller::add_custom_data

Estimate the effort ✅

[S]

MathieuLamiot commented 2 months ago

@jeawhanlee I just have a doubt about this condition:

this._getElementDistance(element.parentElement) === 0 && distance > this.config.lrc_threshold

I understand the following:

Am I missing something?

If I am correct, then I suggest:

this._getElementDistance(element.parentElement) < this.config.lrc_threshold && distance >= this.config.lrc_threshold

jeawhanlee commented 2 months ago

@MathieuLamiot What that condition means is lazy render only all sub-parent elements that has their parent element at distance 0 and their own distance greater than the threshold, that way we only get the parent elements and not the children.

You can validate with me using this template here: https://user-f89ec7c1-e805-4205-806b-9d7fe56d9853-45htvp2guq-uc.a.run.app/?p=de8c45bc6c

The debug has this: Screenshot 2024-08-27 at 08 47 09

What I think we need to enhance is factoring in parent elements that might be less than the threshold but not 0 so I think we can change this: this._getElementDistance(element.parentElement) === 0 && distance > this.config.lrc_threshold to become this: this._getElementDistance(element.parentElement) < this.config.lrc_threshold && distance > this.config.lrc_threshold

MathieuLamiot commented 2 months ago

Following our discussion @jeawhanlee:

MathieuLamiot commented 2 months ago
    const rect = element.getBoundingClientRect();
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    let distanceFromViewportTop = rect.top + scrollTop - viewportHeight;

    // Ensure distance is non-negative
    distanceFromViewportTop = Math.max(0, distanceFromViewportTop);

    // Apply styling based on distance
    let style = '';
    if (distanceFromViewportTop > 1800) {
        style = 'color: green;';
    } else if (distanceFromViewportTop === 0) {
        style = 'color: red;';
    }

I see that the formula + comparison to the threshold comes from @DahmaniAdame's prototype. Maybe @DahmaniAdame you can confirm our discussion and this is creating the confusion:

To avoid any confusion, the check is done from the top of page. So, technically, the threshold includes the viewport.

jeawhanlee commented 2 months ago

@MathieuLamiot Grooming updated in respect to our discussions.

Mai-Saad commented 2 months ago

Note: to be retested with the fix here https://new.rocketlabsqa.ovh/lrc_similive/ , here we have 2 hashes in threshold and not added to DB bde801b81055e486a3cf54938b78ca40and 8c2d3df5df458ee91f4369f5ed9543f0 Screenshot from 2024-08-29 11-54-44