From 820d256bcd34daf755b74a03af2fd66a6f5a10be Mon Sep 17 00:00:00 2001 From: Peter Mosses <18308236+pdmosses@users.noreply.github.com> Date: Fri, 23 Feb 2024 06:56:52 +0100 Subject: [PATCH] Quicker build (#1397) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR uses the cached site-nav to determine the position of each page in the navigation hierarchy. [Profiling](https://just-the-docs.github.io/just-the-docs-tests/tests/profiles/index/) shows that it significantly reduces the v0.7.0 build time for larger sites – especially with Jekyll 3. The improvement is due mainly to the elimination of loops and filters that depended on the entire site. For example: - [endoflife.date](https://just-the-docs.github.io/just-the-docs-tests/tests/profiles/endoflife.date/index/) drops from 32s to 11s - [machinetranslate.org](https://just-the-docs.github.io/just-the-docs-tests/tests/profiles/machinetranslate.org/index/) drops from 267s to ~~73s~~ 56s ### Testing [Just the Docs Tests](https://just-the-docs.github.io/just-the-docs-tests/) is currently built using this PR branch. With JS disabled, the highlighting and unfolding of the navigation panel should be as with v0.7.0. A diff of the tests site built with this PR branch compared to v0.7.0 should report no significant changes. For more rigorous testing, diffs of variants of the tests site should also be inspected. --- CHANGELOG.md | 2 + _includes/components/breadcrumbs.html | 105 +++++++++- _includes/css/activation.scss.liquid | 285 +++++++++++++++----------- 3 files changed, 269 insertions(+), 123 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e87ccf8..ba58b67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Code changes to `main` that are *not* in the latest release: - Added: configurable keyboard shortcut to focus search input by [@kcromanpl-bajra] in [#1411] - Fixed: incorrect navigation when `.html` omitted from URL by [@pdmosses] in [#1374] +- Fixed: quicker build by [@pdmosses] in [#1397] - Fixed: incorrect positioning of clickable area for navigation links on Safari by [@mattxwang] in [#1403] Docs changes made since the latest release: @@ -34,6 +35,7 @@ Docs changes made since the latest release: [#1374]: https://github.com/just-the-docs/just-the-docs/pull/1374 [#1390]: https://github.com/just-the-docs/just-the-docs/pull/1390 +[#1397]: https://github.com/just-the-docs/just-the-docs/pull/1397 [#1403]: https://github.com/just-the-docs/just-the-docs/pull/1403 [#1411]: https://github.com/just-the-docs/just-the-docs/pull/1411 diff --git a/_includes/components/breadcrumbs.html b/_includes/components/breadcrumbs.html index 5db2342..2be747b 100644 --- a/_includes/components/breadcrumbs.html +++ b/_includes/components/breadcrumbs.html @@ -8,8 +8,91 @@ {%- if page.url != "/" and page.parent -%} - {%- assign pages_list = site[page.collection] | default: site.html_pages -%} +{%- capture nav_list_link -%} + +{%- endcapture -%} +{%- capture site_nav -%} +{%- include_cached components/site_nav.html -%} +{%- endcapture -%} + +{%- if site_nav contains nav_list_link -%} + + {%- capture nav_list_simple -%} + "s requires that number + of potential ancestors to be popped from the stack. + + The number of occurrences of a string in nav_split_next is computed by removing + them all, then dividing the resulting size difference by the length of the string. + {%- endcomment %} + + {%- assign nav_breadcrumbs = "" | split: "" -%} + + {%- for nav_split in nav_anchor_splits -%} + {%- unless forloop.last -%} + + {%- assign nav_split_next = nav_anchor_splits[forloop.index] | trim -%} + + {%- assign nav_split_test = + nav_split_next | remove_first: nav_list_simple | prepend: nav_list_simple -%} + {%- if nav_split_test == nav_split_next -%} + {%- assign nav_breadcrumb_link = + nav_split | split: "" | append: "" -%} + {%- assign nav_breadcrumbs = nav_breadcrumbs | push: nav_breadcrumb_link -%} + {%- endif -%} + + {%- if nav_split_next contains "" -%} + {%- assign nav_list_end_less = nav_split_next | remove: "" -%} + {%- assign nav_list_end_count = + nav_split_next.size | minus: nav_list_end_less.size | divided_by: 5 -%} + {% for nav_end_index in (1..nav_list_end_count) %} + {%- assign nav_breadcrumbs = nav_breadcrumbs | pop -%} + {%- endfor -%} + {%- endif -%} + + {%- endunless -%} + {%- endfor -%} + + {%- assign nav_parent_link = nav_breadcrumbs[-1] -%} + {%- assign nav_grandparent_link = nav_breadcrumbs[-2] -%} + +{%- else -%} + + {%- comment -%} + Pages whose links are excluded from the main navigation may still have + breadcrumbs. Determining them appears to require inspecting the front matter + of all the pages in the same group. For sites with 100s of pages, this is too + inefficient in Jekyll 3 (also when the for-loop is replaced by where-filters). + {%- endcomment -%} + + {%- assign pages_list = site[page.collection] | default: site.html_pages -%} + {%- assign parent_page = nil -%} {%- assign grandparent_page = nil -%} @@ -35,15 +118,25 @@ {%- endif -%} {%- endfor -%} + + {%- capture nav_parent_link -%} + {{ page.parent }} + {%- endcapture -%} + + {%- if page.grand_parent %} + {%- capture nav_grandparent_link -%} + {{ page.grand_parent }} + {%- endcapture -%} + {%- endif -%} + +{%- endif -%} diff --git a/_includes/css/activation.scss.liquid b/_includes/css/activation.scss.liquid index a32392e..31e4829 100644 --- a/_includes/css/activation.scss.liquid +++ b/_includes/css/activation.scss.liquid @@ -1,19 +1,17 @@ {%- comment -%} Include as: {%- include css/activation.scss.liquid -%} - Depends on: page, site. - Results in: page-dependent (non-nested) CSS rules for inclusion in a head style element, - which needs to be suppressed when JS is enabled. - Includes: - sorted_pages.html. + Depends on: page. + Results in: page-dependent CSS rules for inclusion in a style element, + which needs to be disabled when JS is enabled. + Includes: components/site_nav.html. Overwrites: - activation_no_nav_link, activation_pages, activation_pages_top_size, activation_page, activation_title, - activation_first_level, activation_second_level, activation_third_level, - activation_first_level_reversed, activation_second_level_reversed, - activation_first_level_index, activation_second_level_index, activation_third_level_index, - activation_index, activation_collection_prefix, activation_other_collection_prefix. + activation_no_nav_link, nav_list_link, site_nav, + nav_list, nav_list_end, nav_list_item, nav_category_list, + nav_list_link_prefix, nav_splits, nav_split, nav_levels, + nav_list_less, nav_list_count, nav_end_less, nav_end_count, + nav_index, nav_slice_size, + activation_collection_prefix, activation_other_collection_prefix. Should not be cached, because it depends on page. - (For a site with only top-level pages, the rendering of this file is always empty. - This property could be detected, and used to reduce the build time for such sites.) {%- endcomment -%} {%- comment -%} @@ -37,89 +35,163 @@ {%- endif %} {% endcapture -%} -{%- if page.title == nil or page.nav_exclude == true -%} +{%- capture nav_list_link -%} + +{%- endcapture -%} -{{ activation_no_nav_link }} +{%- capture site_nav -%} +{%- include_cached components/site_nav.html -%} +{%- endcapture -%} -{%- else -%} +{%- if site_nav contains nav_list_link -%} -{%- assign activation_pages = site[page.collection] - | default: site.html_pages - | where_exp: "item", "item.title != nil" - | where_exp: "item", "item.nav_exclude != true" -%} +{%- capture nav_list -%} +