Improve performance of the user.permissions.js script running in /admin/people/permissions.

Created on 29 July 2024, about 1 year ago
Updated 18 September 2024, 11 months ago

Problem/Motivation

The permissions page in Drupal (path /admin/people/permissions) has both backend and frontend performance problems that have been documented over the years on multiple tickets (e.g.: πŸ› Improve performance of /admin/people/permissions Needs work , #1203766: With large number of permissions /admin/people/permissions becomes unusable β†’ , #1565704: Core interfaces can go over max_input_vars β†’ among others one might find out there, both closed and open).

I recently came up with an improvement on this issue queue ( πŸ› Improve performance of /admin/people/permissions Needs work ) but upon suggestion by colleagues @nicxvan and @Scott Sawyer over the #contribute Slack channel, I am moving the proposed resolution into a new, separate issue queue. This way we can narrow the scope of the changes being introduced to the front-end realm only. This issue should not clash with any back-end improvements users might come up with in separate tickets.

Here is a brief description of what is being done within that file currently:

  • Detach the entire permissions table from DOM.
  • Manipulate it to create and apply one dummy checkbox per permission, per role.
  • Re-insert the entire table back to the original container.

Although detaching/re-inserting is probably an improvement over the previous version, it still causes considerable lag when loading the permissions page in the context of multiple roles and modules, where potentially thousands of checkboxes are manipulated by the script upon page load. It turns out, though, the heavy process of manipulating all those checkboxes at once is unnecessary and resource-intensive for the browser.

Steps to reproduce

--

Proposed resolution

I am offering a new approach that activates checkbox replacements only when necessary by using IntersectionObserver; the new script does the bare minimum to make sure the expected results are still delivered; here is an overview of what is being delivered:

  • Grab all table rows and find those carrying a checked checkbox in the Authenticated user column.
  • Attach an IntersectionObserver to each one of these rows, and then process them on demand, as they become visible on the page; it may also happen that they will never become visible on the page, thus saving unnecessary client processing to run all those replacements. The script is immediately triggered upon page load to affect only the visible rows for the user.

I ran a very simple test on a local installation of Drupal 11 with console.time() and console.timeEnd() applied to the start and end of the Drupal.behaviors.permissions. This measures how long the script takes to run. Considering a website with 190 modules installed (all included, both core and contrib), and 15 user roles, there was a massive performance gain: I could drop the time it takes for the script to run from ~400ms to ~12ms.

Remaining tasks

A proposed solution is already available to be tested by the community.

User interface changes

There are no user interface changes: the script changes should deliver a positive impact on the loading time of the permissions page with no visual changes for the end-user. The time it took for the script to run dropped from ~ 400ms to ~10ms on Firefox.

Introduced terminology

--

API changes

--

Data model changes

--

Release notes snippet

--

πŸ“Œ Task
Status

Fixed

Version

10.3 ✨

Component
User moduleΒ  β†’

Last updated about 8 hours ago

Created by

πŸ‡§πŸ‡·Brazil mabho Rio de Janeiro, RJ

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

Production build 0.71.5 2024