BigPipe injecting Local Actions block creates large janky layout shift in Claro

Created on 15 April 2024, 7 months ago
Updated 29 May 2024, 6 months ago

Problem/Motivation

When on an admin page with the local actions block (e.g. "Add content", "Create a new field", etc) at the top of the page, BigPipe will inject this slightly after pageload. This causes the entire page to render, and then immediately shifts the content down, which can be perceived as unpolished and janky.

Steps to reproduce

Navigate to a page with the local actions block such as /admin/structure/types/manage/article/fields. Notice how the "Create a new field" button pops in, and then shifts everything down.

Proposed resolution

As of Drupal 10.1, BigPipe placeholder content can now be customized ! Let's do this.

Remaining tasks

Do it and review it.

User interface changes

Instead of pushing everything down, space will now be reserved, and the buttons will pop in without shifting content around.

🐛 Bug report
Status

Fixed

Version

10.3

Component
Claro 

Last updated about 21 hours ago

Created by

🇺🇸United States mherchel Gainesville, FL, US

Live updates comments and jobs are added and updated live.
  • Performance

    It affects performance. It is often combined with the Needs profiling tag.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Issue created by @mherchel
  • Status changed to Needs review 7 months ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    MR created. Here's a video of the block being added now. Note how space is reserved and the button appears without shifting any other content.

  • Pipeline finished with Failed
    7 months ago
    Total: 198s
    #147313
  • 🇺🇸United States mherchel Gainesville, FL, US
  • Pipeline finished with Success
    7 months ago
    #147318
  • Pipeline finished with Running
    7 months ago
    #147343
  • Status changed to RTBC 7 months ago
  • 🇺🇸United States smustgrave

    Tested this on Chrome 123.0.6312.122
    After applying the MR I don't see any shift just a flicker which I believe is expected based on the 2nd mp4 in #4

    Not seen this before but neat solution.

  • Status changed to Needs review 7 months ago
  • 🇬🇧United Kingdom catch

    One question on the MR.

  • Status changed to RTBC 7 months ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    Isn't this an issue for all themes? Could we add preview HTML to local actions generically?

    I'm not sure. I'm assuming the template naming convention (big-pipe-interface-preview--block--claro-local-actions.html.twig)is based on Claro's core/themes/claro/config/optional/block.block.claro_local_actions.yml config. That naming convention would obviously change based on the theme.

    And, if I recall correctly, that was the only template suggestion that was shown within Twig debug (I had to set an early JS breakpoint to see this).

    Right now, I'm trying double-check and get the local actions block to be pulled in by BigPipe, and it's not happening. I'm not quite sure how Drupal determines if it's going to immediately render the block or let BigPipe handle it, but I'm having issues right now checking the template naming suggestions.

    That all being said, IMO this is an easy win, and fixes something that I've definitely noticed in client sites in the past. Claro obviously powers most Drupal admin pages (and Gin is a subtheme of Claro), so this would positively affect the vast majority of users.

    Setting back to RTBC to get committers' attention. Feel free to kick back if needed.

  • Status changed to Needs review 7 months ago
  • 🇬🇧United Kingdom catch

    I was thinking more that menu module could implement hook_block_build_local_actions_block_alter() and set up the preview markup in there.

    Big Pipe placeholdering depends on the cacheability of the block and auto placeholdering conditions, but 📌 Use placeholdering for more elements to optimize asset serving Needs work would make that more predictable (i.e. on for a lot more things).

    Local actions are also shown in Olivero - especially on entity pages like nodes, so I think this can equally be an issue there no?

    Back to needs review, I might try to get a proof of concept up (in a separate MR in case it's a dead-end) for the block build alter idea.

  • Status changed to Needs work 7 months ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    I might try to get a proof of concept up (in a separate MR in case it's a dead-end) for the block build alter idea.

    I'd appreciate it. I don't have too much contrib time available, and this is a bit outside of my wheelhouse.

    Local actions are also shown in Olivero - especially on entity pages like nodes, so I think this can equally be an issue there no?

    We don't place the primary admin actions block (as Claro does).

    Setting back to Needs Work for now, so you (or anyone else) can work on the block build alter thing.

    Thank you!

  • Status changed to Needs review 7 months ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    @catch thoughts on committing the template solution, and then creating a followup to implement it with hook_block_build_local_actions_block_alter()?

    Although this only solves the problem with the local tasks block with the Claro theme, I'd argue that is is a very significant reduction of jank for 99% of users.

  • 🇬🇧United Kingdom catch

    Put up a rough MR with the alter approach.

  • Merge request !7844Add a block build alter. → (Open) created by catch
  • Pipeline finished with Failed
    7 months ago
    Total: 203s
    #160482
  • 🇬🇧United Kingdom catch

    Differences with the alter approach are that I used the invisible class instead of style: although that could also be done in the template. The main difference is using #theme => menu_local_action which saves having to duplicate the classes from template_preprocess_menu_local_action()

    The ul with class local actions is added by classy - I'm wondering a couple of things:

    1. If we didn't add the ul, would just the link be enough to avoid layout shift? That would keep it closer to stark markup then.
    2. If #1 isn't OK, is it OK for core to default to adding the list, I think it probably is though since it's still pretty generic overall?

    I didn't try artificially slowing down the local actions rendering now to force the layout shift yet, so whether this is actually working yet is tbd.

  • Pipeline finished with Success
    7 months ago
    Total: 508s
    #160626
  • Pipeline finished with Success
    7 months ago
    #160628
  • 🇺🇸United States mherchel Gainesville, FL, US

    Doesn't appear to be working (Screenshot below).

    To test this out

    1. Disable JS/CSS aggregation
    2. Disable caching on /admin/config/development/settings
    3. Go to a "Manage field" page such as admin/structure/types/manage/article/fields. Note this is the only page where I consistently see this loaded by BigPipe
    4. Set a JavaScript breakpoint at the very beginning of drupal.js
    5. Hopefully the local actions are not loaded. Use your inspector to find the span. Ideally this should be populated with placeholder data.

    If we didn't add the ul, would just the link be enough to avoid layout shift? That would keep it closer to stark markup then.

    I think so. I just experimented and I don't think the UL is adding any extra margin in Claro. I'll double check when the code is ready, but right now I don't think we need it.

  • Status changed to Needs work 7 months ago
  • 🇺🇸United States mherchel Gainesville, FL, US

  • 🇬🇧United Kingdom catch

    I got it to work, but for some reason I had to force #create_placeholder. If that's not set, it still gets rendered via a bigpipe placeholder, but not with the preview - haven't figured out why yet. Just the link is indeed plenty to reserve the vertical space.

  • 🇺🇸United States mherchel Gainesville, FL, US

    Yeah, verified that it's working correctly now. The containing elements are both 48px height before and after BigPipe gets to work.

    Note you could also yank out that <li> if you want.

  • 🇺🇸United States mherchel Gainesville, FL, US

    Crap. This causes a regression on /admin/structure though. The local actions BigPipe placeholder loads... but since there isn't any local actions, BigPipe simply removes the span, causing the layout to shift up.

    Is there anything we can do about this? Not sure if we can limit it to routes or some other way?

  • Pipeline finished with Failed
    7 months ago
    Total: 606s
    #160954
  • Pipeline finished with Canceled
    7 months ago
    Total: 66s
    #160967
  • Status changed to RTBC 7 months ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    The latest changes 1) correct the regression, and 2) fixes the original issue.

    🙌 🙌 🙌

    Thanks @catch!

  • 🇺🇸United States mherchel Gainesville, FL, US

    mherchel changed the visibility of the branch 3441137-bigpipe-injecting-local to hidden.

  • Pipeline finished with Success
    7 months ago
    Total: 747s
    #160968
  • Pipeline finished with Success
    7 months ago
    #161117
  • 🇬🇧United Kingdom catch

    I added some unit test coverage. I cannot figure out how to make the unit test fail, however it does add some explicit coverage for things we don't have unit test coverage for.

  • Status changed to Needs review 7 months ago
  • 🇬🇧United Kingdom catch

    Got the unit test failing when it should - it specifically happens when the lazy builder returns auto-placeholderable cache contexts. Should be good now.

  • Pipeline finished with Success
    7 months ago
    Total: 772s
    #161170
  • 🇺🇸United States mherchel Gainesville, FL, US

    @catch mentioned in https://drupal.slack.com/archives/C7AB68LJV/p1714544076932459?thread_ts=...

    One last commit on the MR after that - used   so the link actually shows up (then gets wider) instead of being invisible, I have no idea if that is better or worse, feel free to revert the last commit if you don't like it but would re-RTBC otherwise.

    We do need the invisible class there. Otherwise the placeholder will be visible as a very narrow button (it'll be visible because it has a background color), and before it's replaced. IMO its better for the actions to just pop in.

    I reverted that last commit. Going to do a bit of testing, and then should be ready for a code review.

  • Status changed to RTBC 7 months ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    Looks good! Tests are passing and space is now being reserved for the button. Thank you @catch!

  • Pipeline finished with Success
    7 months ago
    Total: 584s
    #161559
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Committed and pushed 3203676df8 to 11.x and 60b7fbf05a to 10.4.x and 041a12b513 to 10.3.x. Thanks!

    • alexpott committed 041a12b5 on 10.3.x
      Issue #3441137 by catch, mherchel: BigPipe injecting Local Actions block...
    • alexpott committed 60b7fbf0 on 10.4.x
      Issue #3441137 by catch, mherchel: BigPipe injecting Local Actions block...
  • Status changed to Fixed 7 months ago
    • alexpott committed 3203676d on 11.x
      Issue #3441137 by catch, mherchel: BigPipe injecting Local Actions block...
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    TIL hook_block_build_BASE_BLOCK_ID_alter() exists 🤯

    So this uses that hook to generate a "Add" button as the local action … without that local action pointing anywhere … and with that local action being hidden. Just to consume enough vertical space that when the placeholder is swapped, there's no layout shift. Intriguing!

  • 🇬🇧United Kingdom catch

    #29 yes exactly :)

  • 🇫🇷France duaelfr Montpellier, France

    Good job here!
    One concern though:
    Isn't "Add" an inappropriate button label in some rare edge case where CSS is disabled or overridden somehow? I believe it would be better to use another string explaining what's happening here like "Loading" for example.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024