Problem/Motivation

I have a large book (over 3,600 nodes). When building the navigation menu, each of the nodes is loaded in bookTreeCheckAccess(), but those results are cached (statically and persistently) in bookTreeAllData(). The caching does not help much, because the nodes are loaded again in buildItems().

Proposed resolution

Avoid calling Node::load() in buildItems().

Remaining tasks

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

benjifisher created an issue. See original summary.

benjifisher’s picture

Assigned: benjifisher » Unassigned
Status: Active » Needs review
StatusFileSize
new893 bytes

The only reason the node is loaded is in order to get $node->urlInfo(). In my limited testing, "entity:node/$nid" works just as well. (This is passed to Url::fromUri().) The attached patch makes this little change.

benjifisher’s picture

Issue summary: View changes

Originally, I counted using array_walk_recursive() on the tree of links returned by bookTreeAllData(). I came up with a much larger number, since each link it itself a structured array. I came up with 3,600 by counting the number of <a> elements in the HTML markup for the navigation.

I am not sure of my analysis. I originally thought that Node::loadMultiple() was called indirectly by bookTreeAllData(). That may be correct, but now I cannot find such a call to confirm what I said. I may have been looking at a call to BookOutlineStorageI::loadMultiple().

I am pretty sure that I need both the optimization in this issue and some additional caching in order to improve my page-load times. I tried using each by itself and did not find any improvement.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

piotrkonefal’s picture

StatusFileSize
new896 bytes
new1.41 KB

Here is the rerolled version for 8.7.x

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

joachim’s picture

Status: Needs review » Reviewed & tested by the community
alexpott’s picture

It'd be by great if someone can point to where these links are tested as the change seems sensible but in order to commit a change like this I'd need to prove we have existing test coverage.

benjifisher’s picture

StatusFileSize
new903 bytes

Those links are tested in Drupal\Tests\book\Functional\BookTest::testBook(). It is a little hard to follow, especially since that test uses methods from Drupal\Tests\book\Functional\BookTestTrait. So why not hack the patch and let the testbot show us where the links are tested?

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 9: 3010378-9-fail.patch, failed testing. View results

benjifisher’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new896 bytes

I am setting the status back to RTBC and re-uploading the patch from #3 so that the testbot does not get confused.

Unfortunately, the testbot seems to be truncating the error messages :-(. Here is what I get when I run testBook() locally:

$ lando phpunit -c /app/core core/modules/book/tests/src/Functional/BookTest.php 
PHPUnit 6.5.14 by Sebastian Bergmann and contributors.

Testing Drupal\Tests\book\Functional\BookTest
..E............                                                   15 / 15 (100%)

Time: 8.97 minutes, Memory: 6.00MB

There was 1 error:

1) Drupal\Tests\book\Functional\BookTest::testBook
Behat\Mink\Exception\ExpectationException: The pattern /<nav id="book-navigation-1"(.*?)<ul(.*?)(node\/2)(.*?)(01 - SimpleTest test node kbaSQdvZ2I)(.*?)(node\/5)(.*?)(04 - SimpleTest test node xLfEnr8N3e)(.*?)(node\/6)(.*?)(05 - SimpleTest test node yaQHvKxGs2)(.*?)<\/ul>/s was not found anywhere in the HTML response of the page.

/app/vendor/behat/mink/src/WebAssert.php:768
/app/vendor/behat/mink/src/WebAssert.php:354
/app/core/tests/Drupal/FunctionalTests/AssertLegacyTrait.php:690
/app/core/modules/book/tests/src/Functional/BookTestTrait.php:98
/app/core/modules/book/tests/src/Functional/BookTest.php:137

ERRORS!
Tests: 15, Assertions: 619, Errors: 1.

HTML output was generated
https://drupal.lndo.site/sites/simpletest/browser_output/Drupal_Tests_book_Functional_BookTest-575-96303946.html
...
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

This looks like a really nice fix.

Committed and pushed 702b8f1aa8 to 9.0.x and 0537629fa4 to 8.9.x. Thanks!

  • alexpott committed 702b8f1 on 9.0.x
    Issue #3010378 by benjifisher, piotrkonefal: BookManager::buildItems()...

  • alexpott committed 0537629 on 8.9.x
    Issue #3010378 by benjifisher, piotrkonefal: BookManager::buildItems()...
benjifisher’s picture

@joachim, @alexpott:

Thanks for taking a look at this issue! It is nice to know that, even during the mad dash to get 9.0 ready for beta, we can still get little fixes like this one into the codebase.

wim leers’s picture

Issue tags: +Performance

Very nice perf win!

Status: Fixed » Closed (fixed)

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

nicrodgers’s picture

I've spotted a problem with this change. I've created https://www.drupal.org/project/drupal/issues/3155869 and would appreciate your thoughts on the best way to proceed.

lpeabody’s picture

I think this change probably broke any site using the book_tree template.

EDIT: *Customized book_tree template where item.url is not passed into the link function. We generally don't end up using the Twig link function a lot because frontend devs usually like to markup anchor elements in their own prototypes before we integrate them in Drupal templates. In several usages of book-tree.html.twig, we just pass item.url in as a parameter to separate Twig templates that render variations of an anchor element. Having item.url not be a Url object is a departure to how that variable has traditionally been treated.

lpeabody’s picture

I opened https://www.drupal.org/project/drupal/issues/3162181 as a task for updating the now out-dated documentation in the various book-tree.html.twig files in core.

Issue was redundant since https://www.drupal.org/project/drupal/issues/3155869 does account for the possibility of just having to update the Twig documentation, as opposed to just reverting item.url back to a Url object.