Optimized nested navigation rendering: don't cross template boundary (#2213)

The number of calls to sub-templates when rendering the navigation is O(n^2) relative to the number of pages. This is the only such instance, which is why I think this is worth optimizing.

The optimization here doesn't improve the complexity, it just removes the overhead of instantiating a new Jinja template for each of these calls.

E.g. for 710 pages on the site, the number of calls to Jinja's `get_template` (implying `new_context` and others) crosses a million ==(710**2)*2. They're not expensive but also not super cheap, and add up to a big percentage of overall site build times.
This commit is contained in:
Oleh Prypin 2021-01-17 10:38:03 +01:00 committed by GitHub
parent 1e0a242d92
commit 81a13f6bc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 6 deletions

View File

@ -2,6 +2,7 @@
This file was automatically generated - do not edit This file was automatically generated - do not edit
-#} -#}
{% set features = config.theme.features or [] %} {% set features = config.theme.features or [] %}
{% macro do_nav_item(nav_item, path, level) %}
{% set class = "md-nav__item" %} {% set class = "md-nav__item" %}
{% if nav_item.active %} {% if nav_item.active %}
{% set class = class ~ " md-nav__item--active" %} {% set class = class ~ " md-nav__item--active" %}
@ -31,9 +32,7 @@
<ul class="md-nav__list" data-md-scrollfix> <ul class="md-nav__list" data-md-scrollfix>
{% set base = path %} {% set base = path %}
{% for nav_item in nav_item.children %} {% for nav_item in nav_item.children %}
{% set path = base ~ "-" ~ loop.index %} {{ do_nav_item(nav_item, path = base ~ "-" ~ loop.index, level = level + 1) }}
{% set level = level + 1 %}
{% include "partials/nav-item.html" %}
{% endfor %} {% endfor %}
</ul> </ul>
</nav> </nav>
@ -65,3 +64,5 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% endmacro %}
{{ do_nav_item(nav_item, path, level) }}

View File

@ -23,6 +23,9 @@
<!-- Retrieve features from configuration --> <!-- Retrieve features from configuration -->
{% set features = config.theme.features or [] %} {% set features = config.theme.features or [] %}
<!-- Wrap everything into a macro to reduce file roundtrips -->
{% macro do_nav_item(nav_item, path, level) %}
<!-- Determine class according to state --> <!-- Determine class according to state -->
{% set class = "md-nav__item" %} {% set class = "md-nav__item" %}
{% if nav_item.active %} {% if nav_item.active %}
@ -82,9 +85,7 @@
<!-- Render nested item list --> <!-- Render nested item list -->
{% set base = path %} {% set base = path %}
{% for nav_item in nav_item.children %} {% for nav_item in nav_item.children %}
{% set path = base ~ "-" ~ loop.index %} {{ do_nav_item(nav_item, path = base ~ "-" ~ loop.index, level = level + 1) }}
{% set level = level + 1 %}
{% include "partials/nav-item.html" %}
{% endfor %} {% endfor %}
</ul> </ul>
</nav> </nav>
@ -136,3 +137,7 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% endmacro %}
{{ do_nav_item(nav_item, path, level) }}