diff --git a/core/lib/Drupal/Core/Render/Element/Actions.php b/core/lib/Drupal/Core/Render/Element/Actions.php
index 2e7516548e..492ef936fa 100644
--- a/core/lib/Drupal/Core/Render/Element/Actions.php
+++ b/core/lib/Drupal/Core/Render/Element/Actions.php
@@ -33,11 +33,12 @@ public function getInfo() {
     $class = get_class($this);
     return [
       '#process' => [
-        // @todo Move this to #pre_render.
-        [$class, 'preRenderActionsDropbutton'],
         [$class, 'processActions'],
         [$class, 'processContainer'],
       ],
+      '#pre_render' => [
+        [$class, 'preRenderActionsDropbutton'],
+      ],
       '#weight' => 100,
       '#theme_wrappers' => ['container'],
     ];
@@ -67,51 +68,52 @@ public static function processActions(&$element, FormStateInterface $form_state,
    *
    * This callback iterates over all child elements of the #type 'actions'
    * container to look for elements with a #dropbutton property, so as to group
-   * those elements into dropbuttons. As such, it works similar to #group, but is
-   * specialized for dropbuttons.
+   * those elements into dropbuttons. As such, it works similar to #group, but
+   * is specialized for dropbuttons.
    *
    * The value of #dropbutton denotes the dropbutton to group the child element
-   * into. For example, two different values of 'foo' and 'bar' on child elements
-   * would generate two separate dropbuttons, which each contain the corresponding
-   * buttons.
+   * into. For example, two different values of 'foo' and 'bar' on child
+   * elements would generate two separate dropbuttons, which each contain the
+   * corresponding buttons.
    *
    * @param array $element
-   *   The #type 'actions' element to process.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   * @param array $complete_form
-   *   The complete form structure.
+   *   The #type 'actions' element to pre-render.
    *
    * @return array
-   *   The processed #type 'actions' element, including individual buttons grouped
-   *   into new #type 'dropbutton' elements.
+   *   The pre-rendered #type 'actions' element, including individual buttons
+   *   grouped into new #type 'dropbutton' elements.
    */
-  public static function preRenderActionsDropbutton(&$element, FormStateInterface $form_state, &$complete_form) {
+  public static function preRenderActionsDropbutton($element) {
     $dropbuttons = [];
     foreach (Element::children($element, TRUE) as $key) {
       if (isset($element[$key]['#dropbutton'])) {
         $dropbutton = $element[$key]['#dropbutton'];
+
         // If there is no dropbutton for this button group yet, create one.
         if (!isset($dropbuttons[$dropbutton])) {
           $dropbuttons[$dropbutton] = [
             '#type' => 'dropbutton',
           ];
         }
-        // Add this button to the corresponding dropbutton.
-        // @todo Change #type 'dropbutton' to be based on item-list.html.twig
-        //   instead of links.html.twig to avoid this preemptive rendering.
+
+        // Add button to the corresponding dropbutton by cloning it.
+        // Note: do not prematurely render this as it will break any #attached
+        // bubbled metadata that is associated with the button.
         $button = \Drupal::service('renderer')->renderPlain($element[$key]);
         $dropbuttons[$dropbutton]['#links'][$key] = [
-          'title' => $button,
+          'title' => $element[$key],
         ];
+
+        // Hide original cloned element by indicating it was already printed.
+        $element[$key]['#printed'] = TRUE;
+
         // Merge metadata like drupalSettings.
         BubbleableMetadata::createFromRenderArray($dropbuttons[$dropbutton])
           ->merge(BubbleableMetadata::createFromRenderArray($element[$key]))
           ->applyTo($dropbuttons[$dropbutton]);
       }
     }
-    // @todo For now, all dropbuttons appear first. Consider to invent a more
-    //   fancy sorting/injection algorithm here.
+    // Prepend dropbuttons with the original element.
     return $dropbuttons + $element;
   }
 
