Dropdown Benchmark

Bootstrap 5 Dropdown JS (Popper.js) vs Native Popover API + CSS Anchor Positioning

Bootstrap JS

Uses bootstrap.Dropdown + Popper.js — calculates position via createPopper() on every open, manages click-outside listeners, keyboard navigation.

Native Browser API

Uses Popover API (popover="auto") + CSS Anchor Positioning — browser handles positioning, light-dismiss, and top-layer stacking. Zero JS.

Initializing... 0%

Results

Metric Bootstrap Dropdown Native Popover API
Initialization time (20 instances) - -
Toggle time (100 cycles × 20 items) - -
Instance memory cost - -
JS code size - -
CSS output size
_dropdown.scss (7.9 KB)
- -
Bootstrap JS 20 items — data-bs-toggle="dropdown"
Native Browser API 20 items — popover="auto" + CSS Anchor
About positioning: Bootstrap Dropdown calls Popper.js’s createPopper() on every open, running JavaScript to calculate offsets, detect overflow, and apply inline transform styles. Native Popover API + CSS Anchor Positioning does this entirely in the browser’s layout engine — zero JavaScript for positioning. The browser also provides light-dismiss (click outside to close) and top-layer stacking natively.
Native popover dropdown — entire implementation
HTML
<!-- Trigger button -->
<button style="anchor-name: --my-trigger"
        popovertarget="my-menu">
  Toggle menu
</button>

<!-- Menu (Bootstrap utility classes for styling) -->
<ul popover="auto" id="my-menu"
    class="m-0 py-2 border rounded bg-white shadow list-unstyled"
    style="position-anchor: --my-trigger;">
  <li><a class="dropdown-item" href="#">Action</a></li>
  <li><a class="dropdown-item" href="#">Another action</a></li>
</ul>
CSS (only anchor positioning — no styling needed)
[popover] {
  inset: auto;               /* reset UA default */
  position-area: bottom span-right;  /* place below trigger */
}