Problem/Motivation

This is a follow up to #1203766: With large number of permissions /admin/people/permissions becomes unusable, which was committed to both Drupal 7 and Drupal 8 in 2011. It was later re-opened to make further improvements. This is moving that improvement work to a new issue. If you want to read that issue it was re-opened in #1203766-25: With large number of permissions /admin/people/permissions becomes unusable

With a large number of permissions the permission page takes a long time to load.

Steps to reproduce

TBA

Proposed resolution

TBD

Remaining tasks

Discuss
Patch
Review

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Release notes snippet

TBD

Comments

quietone created an issue. See original summary.

quietone credited catch.

quietone credited sun.

quietone’s picture

The upload patch is the latest one from the original issue, #47. It was made in Dec 2011.

Added credit from the other issue, but still learning that so it would be prudent for others to check that.

nod_’s picture

Issue tags: +JavaScript
quietone’s picture

Issue tags: +Performance

@nod_, thanks for the reminder about tags. Adding the performance tag that was in the original issue

droplet’s picture

I have very low interest in it because I can deal with this problem smartly personally.

For those who are interested, I think you need to figure out the root problem first. Browser? CPU? jQuery? Drupal Code? or Plain JS?

Obviously, this has a basic rendering problem, so you need to wait.

// copy it into drupal.js. Don't use Console to do it. And check your RAM usage when you open Console. To restart browser after a few tests to reduce the side-effect.

// change the below "100" to "1" and open the Console tab first. Otherwise, your browser may hang or run into RAM problems.

  $(document).ready(() => {
    var output = '';

    for (i = 0; i < 100; i++) {
      output += jQuery('tbody').html();
    }

    jQuery('.permissions tbody').append(output);
  });

  window.addEventListener('load', (event) => {
    console.log(document.querySelectorAll('[type=checkbox]').length);

    console.time('q');
    console.log(document.querySelectorAll('[type=checkbox]:checked')[40]);
    console.timeEnd('q');

    console.time('q2');
    const allCheckboxes = [];
    document.querySelectorAll('[type=checkbox]').forEach(function (v) {
      allCheckboxes.push(v.value);
    });
    console.log(allCheckboxes);
    console.timeEnd('q2');
  });

For 40,000 elements,
to query one element taken 15ms
to get all values taken 48ms

IMO, this is very acceptable.

** Oh. You can't test above snippet in Firefox. There's a browser bug in Firefox under above heavy load or something I missed. But Firefox rendered much faster than Chrome when you output HTML rather than use JS above

catch’s picture

Status: Active » Needs review

There's a patch here so marking for review.

droplet’s picture

The patch is outdated. No matter code format or code logic.

and a bug:
#3244737: "core/drupal.checkbox" (misc/checkbox.js) has never loaded on user permission page

What blocking server-side doing the Permission update when "AUTHENTICATED USER" is checked? It reduced a lot of extra dummy checkboxes and need not call toggle on page loading.

Don't it a UX problem?
If "AUTHENTICATED" is checked (on page load, load from DB), we see all checkboxes are checked.
Now, unchecked "AUTHENTICATED", only some is still checked. I expected all still checked.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work

Moving to NW as mentioned the patch is outdated.

Not sure if this is postponed by https://www.drupal.org/project/drupal/issues/3244737

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mohammed motar’s picture

Issue tags: -JavaScript +JavaScript

Does anyone have any idea on how to increase the performance of the permissions page?
When I try to access the permissions page I get:
Got error 'PHP message: PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20728968 bytes) in /var/www/drupal/vendor/twig/twig/src/Template.php on line 388'.

mabho’s picture

I wonder if we can approach the problem raised here using Intersection Observer... It seems like the best approach... I am suffering from a huge lag on 15 roles loading in parallel.

mabho’s picture

The patch on this thread can't be applied anymore because of the changes introduced here #3278415: Remove usages of the JavaScript ES6 build step, the build step itself, and associated dev dependencies.

mabho’s picture

Ok, here is a suggested patch using IntersectionObserver. The previous approach was:

  • 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 literally thousands of checkboxes are manipulated by the script.

This new approach I am suggesting is dropping the detach/re-attach method. Instead, the new code will only kick in when necessary by using IntersectionObserver; we will do 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
  • Immediately run the code that activates the dummy checkboxes on these rows. We want this process to happen very soon.
  • For all the other rows, we have no hurry, as the dummy checkboxes will be activated upon user interaction only. Why block the entire page processing because of these guys? We will attach an IntersectionObserver to each one of these rows, and then process them individually as they become visible on the page.

I ran some local tests with console.time() and console.timeEnd() applied to the beginning and end of script and the performance gain was massive.

nicxvan’s picture

mabho’s picture

I got some feedback on the Drupal Slack channel from some Drupal community colleagues who thought my proposed resolution would suit better in a new, separate ticket. I have thus created an issue here (#3464530: Improve performance of the user.permissions.js script running in /admin/people/permissions.) with a new merge request carrying some improvements over the patch file posted on this issue queue. Edit: I just saw the comment recently posted by @nicxvan about the new issue queue.

nod_’s picture

Status: Needs work » Closed (won't fix)

Patch in the related issue cut the number checkboxes by ~60% that will help across the board.

Porting credit