Skip to content

Fix a regression in adaptive trimming #1970

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

Merged
merged 2 commits into from
May 23, 2025

Conversation

csillag
Copy link
Contributor

@csillag csillag commented May 21, 2025

This is a follow-up to #1963.

(I found a corner case to break it after merging.)

This change add more resilience to the adaptive trimming process in situations when
React components are mounting and unmounting while the process is ongoing.

(Earlier, in some rare circumstances, the process could get stuck.)

Explanation

This is how the adaptive trimming method has evolved

The original method

In the original implementation of the adaptive trimmer, the idea was that we find out the largest fitting length of text by watching for overflow happening on the element directly containing the content to shorten. This requires all the elements further up in the DOM to have exactly the right CSS settings, otherwise the overflow won't happen, or won't happen at the right place. This was a bit fragile, because changing something in the DOM at a higher level could break the adaptive trimming of the contained adaptive trimmers. (Like it happened in #1943)

Relaxing the CSS requirements

To avoid this fragility, the behavior has been changed to look for overflow happening not only on the exact wrapping element, but at any level above this node, that is, on all parents up to the root. (Sometimes there is already overflow even without our text being too long, so first we do a baseline measurement with a very short text, record which is the first level where we find overflow, and then compare the new situation to this saved baseline when experimenting with longer texts.)

This approach makes it unnecessary to add specific CSS configuration to all wrapping levels, therefore makes the system more robust. But there is a problem:

Solving the interplay of multiple adaptive trimmers working at the same time

In the new approach, we let the components resize, and therefore change the layout of a larger sub-tree of the dom, until they hit an overflow. This works fine if there is only one adaptive trimmer doing this, but if multiple adaptive trimmers are doing this at the same time, then the results are unpredictable. (I.e. we won't know which adaptive trimmer has too long text, causing the overflow at an upper level.) The solution to this was adding a singleton controller object, which orchestrates the whole process:

  • First, tell all adaptive trimmers to reduce to minimal content
  • Then tell them to do the adjustment one by one.

This way, there will be no confusion with the test results, because at each point in time, there is exactly one adaptive trimmer that is attempting to adapt (to the available size). This has been implemented as part of #1963, and solved several issues. But there is one more problem which was not handled...

Solving the interplay of window resizing, component unmounting and ongoing adaptation

When the window is being resized, we get multiple resize events. Reacting to these events, we do a full round of adaptation. This is relatively fast, but not instantaneous. It's possible that we receive multiple events while still busy, but that is not a problem, we can handle that. The tricky situation is when as the result of enlarging the window size, we go over the limit to desktop territory, so we no longer want to do any trimming at all. This causes the adaptive trimmer to be removed from the DOM altogether. The problem happens if the component removed was the one that has the permission from the controller to do the resizing. This means that the resizing of that component never finishes (since it is removed from the DOM altogether), but the controller is still waiting it to finish, before giving the task to the next instance. This basically causes the adaptive process to freeze. This doesn't happen very often, but can triggered by resizing the window a lot. This is the bug that is currently present in the master branch. The solution to this issue is to make the code for selecting the current/next task more robust, and also add some reactive code to handle when the currently active adapting instance is removed. This PR does that.


At this point, no further problems have been detected, and the current mechanism (with this fix) seems to work reliably, but more testing is always welcome.

Copy link

github-actions bot commented May 21, 2025

Deployed to Cloudflare Pages

Latest commit: 04d001cd3dd298c1c6c4a841f30edec4a57fcd83
Status:✅ Deploy successful!
Preview URL: https://9f49d742.oasis-explorer.pages.dev
Alias: https://pr-1970.oasis-explorer.pages.dev

@csillag csillag force-pushed the csillag/more-adaptive-trigger-fixes branch from 2a7ab2b to f7d3cde Compare May 21, 2025 13:57
@csillag csillag marked this pull request as ready for review May 21, 2025 13:57
@csillag csillag self-assigned this May 21, 2025
Copy link
Member

@lukaw3d lukaw3d left a comment

Choose a reason for hiding this comment

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

I don't understand

@csillag
Copy link
Contributor Author

csillag commented May 23, 2025

I don't understand

Added detailed explanation to the PR description.

csillag added 2 commits May 23, 2025 19:12
Add more resilience about React components
mounting and unmounting during the renders and resizes.

(In some rare circumstances, it was possible to
get the process stuck.)
@csillag csillag force-pushed the csillag/more-adaptive-trigger-fixes branch from f7d3cde to 04d001c Compare May 23, 2025 17:12
@csillag csillag enabled auto-merge May 23, 2025 17:12
@csillag csillag merged commit 68b4661 into master May 23, 2025
9 checks passed
@csillag csillag deleted the csillag/more-adaptive-trigger-fixes branch May 23, 2025 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants