From c10be205844b2df5c3a031375bea871842f89e39 Mon Sep 17 00:00:00 2001
From: Tom Wiesing <tkw01536@gmail.com>
Date: Mon, 5 Jun 2017 22:32:19 +0200
Subject: [PATCH] Performance tuning

This commit adds a lot of performance tuning, making the page compile
much faster (<= 10 seconds)
---
 README.md                  |  21 +++++--
 _config.yml                |   2 +-
 _includes/footer.html      |   4 --
 _includes/head.html        |   2 +-
 _includes/header.html      |   8 +--
 _includes/menu_single.html |  10 ++--
 _includes/menu_sub.html    | 115 ++++++++++++++++---------------------
 _includes/people_chip.html |  37 ++++++------
 _includes/post_link.html   |   7 ++-
 _includes/posts.html       |  33 -----------
 _layouts/default.html      |   1 +
 11 files changed, 104 insertions(+), 136 deletions(-)
 delete mode 100644 _includes/posts.html

diff --git a/README.md b/README.md
index dae828d..815b904 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,5 @@
 # Repository holding the sources of the KWARC.info website
 
-**Building this page can take up to 30 seconds. This is normal and to be expected.**
-
 Note for authors: When editing some text, please do not hard wrap existing lines. 
 This plays very bad with diffs, in particular an entire paragraph shows up as changed even though it might just be a single line. 
 Furthermore, this introduces lots and lots of merge conflicts
@@ -25,6 +23,21 @@ See the above links for details.
 * `project/` -- people -- event_activites: folders used to generate menu pages (as set in `_config.yml`)
 * `_tagpages` : the tag pages, each tag gets an almost empty md file so that the tag page gets generated by jekyll
 
+## Performance
+This jekyll page is tuned in order to build as fast as possible. 
+It also makes use of the [jekyll-compress-html](https://github.com/penibelst/jekyll-compress-html) layout, to be efficiently transferable over network. 
+During the evolution of the website, the build time has changed dramatically. 
+It used to take around 5 minutes to build, with a few optimizations it now only takes up 15 seconds. 
+
+The biggest slowdowns were:
+    * unneeded iterations
+        * iterations within iterations (usually not required, if one thinks carefully)
+        * `if` conditions within a loop, instead of a `where` clause
+        * full iteration to extract a single item (use `first` instead)
+    * repeated sorting of `site.pages` by the same `menu_order` key (instead sort this once and use a global variable)
+    * multiple chained `if`s instead of a single `and`
+    * unneeded variable assignments (these seem to take a lot of time in liquid)
+
 ## How to use Jekyll to test/build this website
 
 This is a [*static website*](http://en.wikipedia.org/wiki/Static_web_page) automatically generated with [Jekyll](http://jekyllrb.com/) by [GitHub Pages](http://pages.github.com/).
@@ -91,10 +104,10 @@ Furthermore, if these are mixed between folders and static items, the folders wi
 - menu_title: 'FAU links'
   items:
     - menu_title: 'Overview'
-      menu_external: true
+      external: true
       url: 'https://fau.de/'
     - menu_title: 'CS department'
-      menu_external: true
+      external: true
       url: 'https://cs.fau.de/'
 ```
 
diff --git a/_config.yml b/_config.yml
index 0930907..8a1959b 100644
--- a/_config.yml
+++ b/_config.yml
@@ -85,5 +85,5 @@ defaults:
       path: "" 
     values:
       menu_hidden: false
-      menu_external: false
       menu_order: 100
+      external: false
\ No newline at end of file
diff --git a/_includes/footer.html b/_includes/footer.html
index 66ae87b..3f9bf2b 100644
--- a/_includes/footer.html
+++ b/_includes/footer.html
@@ -13,10 +13,6 @@
         <a href="https://github.com/KWARC" title="GitHub" class="waves-effect waves-teal btn-flat">
           <i class="fa fa-github" aria-hidden="true"></i> GitHub
         </a>
-        
-        <!--
-        
-        -->
       
         <a href="{{ site.baseurl }}/atom.xml" title="Atom Feed" class="waves-effect waves-teal btn-flat">
           <i class="fa fa-rss" aria-hidden="true"></i> Atom Feed
diff --git a/_includes/head.html b/_includes/head.html
index 26f2921..d19c21c 100644
--- a/_includes/head.html
+++ b/_includes/head.html
@@ -16,7 +16,7 @@
     
     <!--Import Google Icon Font -->
     <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
-      
+    
     <!-- Import materialize -->
     <link type="text/css" rel="stylesheet" href="{{ site.baseurl }}/public/{{ site.materialize }}/css/materialize.min.css"  media="screen,projection"/>
     
diff --git a/_includes/header.html b/_includes/header.html
index 551f8b4..937093b 100644
--- a/_includes/header.html
+++ b/_includes/header.html
@@ -3,7 +3,7 @@
   <div class="container">
     <div class="nav-wrapper">
       <a class="page-title">
-        {% if page.title == "Home" %}{{ site.title }}{% else %}{{ page.title }}{% endif %}
+        {% if page.url == "/" %}{{ site.title }}{% else %}{{ page.title }}{% endif %}
       </a>
     </div>
   </div>
@@ -23,10 +23,8 @@
     </div>
   </li>
   
-  {% for item in site.menu | sort:"menu_order %}
-    {% if item.folder %}
-      {% include menu_sub.html %}
-    {% elsif item.items %}
+  {% for item in site.menu | sort:"menu_order" %}
+    {% if (item.folder or item.items) %}
       {% include menu_sub.html %}
     {% else %}
       {% include menu_single.html %}
diff --git a/_includes/menu_single.html b/_includes/menu_single.html
index 1a39724..6dec52f 100644
--- a/_includes/menu_single.html
+++ b/_includes/menu_single.html
@@ -6,10 +6,12 @@
   <li
     {% if page.url == item.url %}class="active"{% endif %}
   >
-    <a
-      href="{% unless item.menu_external %}{{ site.baseurl }}{% endunless %}{{ item.url }}"
-      {% if item.menu_external %}target="_blank"{% endif %}
-    >
+    {% if item.external %}
+        <a href="{{ item.url }}" target="_blank">
+    {% else %}
+        <a href="{{ site.baseurl }}{{ item.url }}">
+    {% endif %}
+    
       {% if item.menu_title %}
         {{ item.menu_title }}
       {% else %}
diff --git a/_includes/menu_sub.html b/_includes/menu_sub.html
index b4d7ef7..fa31534 100644
--- a/_includes/menu_sub.html
+++ b/_includes/menu_sub.html
@@ -1,75 +1,60 @@
 {% comment %}
-  This page creates a submenu item. It expects an appropriate `item` as argument. 
+    This page creates a submenu item. It expects an appropriate `item` as argument. 
+    It also expects the global 'sorted_pages' argument. 
 {% endcomment %}
 
 {% unless item.menu_hidden %}
+    {% assign base_folder = page.url | split: '/' %}
 
-  <!-- Figure out our current location -->
-  {% assign url_parts = page.url | split: '/' %}
-  {% assign base_url = url_parts | last %}
-  {% assign base_folder = url_parts[1] %}
+    <!-- if we are in the right folder, we are active -->
+    {% if base_folder[1] == item.folder %}
+        {% assign menu_active = true %}
+    {% else %}
+        {% assign menu_active = false %}
+        {% for item in (item.items | where: "url", page.url) %}
+            {% unless item.external %}
+                {% assign menu_active = true %}
+                <!-- active because {{item}} -->
+            {% endunless %}
+        {% endfor %}
+    {% endif %}
 
-  <!-- Find out if we are active -->
-  {% assign menu_active = false %}
 
-  <!-- if we are in the right folder, we are active -->
-  {% if base_folder == item.folder %}
-    {% assign menu_active = true %}
-  {% endif %}
-  
-  <!-- check if we are in the current oder -->
-    {% for item in item.items %}
-        {% unless item.menu_page %}
-            {% unless item.external_page %}
-                {% if item.url == page.url %}
-                    {% assign menu_active = true %}
-                {% endif %}
-            {% endunless %}
-        {% endunless %}
-    {% endfor %}
-    
-  {% assign pages = site.pages | sort: "menu_order"%}
-  
-  <!-- Find the current folder -->
-  {% assign item_folder = item.folder %}
+    <!-- Find the current folder -->
+    {% assign item_folder = item.folder %}
 
-  <li class="no-padding">
-    <ul class="collapsible collapsible-accordion">
-      <li class="bold">
-        <a class="collapsible-header {% if menu_active %}active{% endif %}">
-        {% if item.menu_title %}
-          {{ item.menu_title }}
-        {% else %}
-          {{ item.title }}
-        {% endif %}
-        </a>
-        <div class="collapsible-body">
-          <ul>
-              <!-- If we have folders, iterate over them -->
-              {% if item.folder %}
-                {% for item in pages %}
-                    <!-- get the current page -->
-                    {% assign sub_parts = item.url | split: '/' %}
-                    {% assign sub_url = sub_parts | last %}
-                    {% assign sub_folder = sub_parts[1] %}
-                    
-                    <!-- if we are in the right folder, include it -->
-                    {% if sub_folder == item_folder %}
-                      {% include menu_single.html %}
+    <li class="no-padding">
+        <ul class="collapsible collapsible-accordion">
+            <li class="bold">
+                <a class="collapsible-header {% if menu_active %}active{% endif %}">
+                    {% if item.menu_title %}
+                        {{ item.menu_title }}
+                    {% else %}
+                        {{ item.title }}
                     {% endif %}
-                {% endfor %}
-              {% endif %}
-              
-              <!-- if we have items, iterate over them -->
-              {% if item.items %}
-                {% assign sitems = item.items | sort: "menu_order"%}
-                {% for item in sitems %}
-                  {% include menu_single.html %}
-                {% endfor %}
-              {% endif %}
-          </ul>
-        </div>
-      </li>
-    </ul>
-  </li>
+                </a>
+                <div class="collapsible-body">
+                    <ul>
+                        <!-- If we have folders, iterate over them -->
+                        {% if item.folder %}
+                            {% for item in sorted_pages %}
+                            
+                                {% assign sub_components = item.url | split: '/' %}
+                                {% if sub_components[1] == item_folder %}
+                                    {% include menu_single.html %}
+                                {% endif %}
+                            {% endfor %}
+                        {% endif %}
+
+                        <!-- if we have items, iterate over them -->
+                        {% if item.items %}
+                            {% for item in (item.items | sort: "menu_order") %}
+                                {% include menu_single.html %}
+                            {% endfor %}
+                        {% endif %}
+                    </ul>
+                </div>
+            </li>
+        </ul>
+    </li>
 {% endunless %}
\ No newline at end of file
diff --git a/_includes/people_chip.html b/_includes/people_chip.html
index e949b2b..ea01f3c 100644
--- a/_includes/people_chip.html
+++ b/_includes/people_chip.html
@@ -1,19 +1,22 @@
-{% capture purl %}/people/{{person}}/{% endcapture %}
-{% assign pname = person %}
-{% assign pimg = "" %}
+{% comment %}
+    This page creates a single 'chip' for linking to a person. 
+    It expects the username of the person as the 'person' variable
+{% endcomment %}
 
-{% for pp in site.pages %}
-  {% if pp.url == purl %}
-    {% assign pname = pp.fullname %}
-    {% assign pimg = pp.pic %}
-  {% endif %}
-{% endfor %}
+{% capture purl %}/people/{{person}}/{% endcapture %}
+{% assign pp = site.pages | where: "url", purl | first %}
 
-<a href="{{ site.baseurl }}{{purl}}">
-  <div class="chip">
-      {% if pimg != "" %}
-        <img src="{{ site.baseurl }}/{{pimg}}">
-      {% endif %}
-      {{pname}}
-  </div>
-</a>
\ No newline at end of file
+{% if pp %}
+    <a href="{{ site.baseurl }}{{purl}}">
+        <div class="chip">
+            <img src="{{ site.baseurl }}/{{pp.pic}}">
+            {{pp.fullname}}
+        </div>
+    </a>
+{% else %}
+    <a href="{{ site.baseurl }}{{purl}}">
+        <div class="chip">
+            {{person}}
+        </div>
+    </a>
+{% endif %}
\ No newline at end of file
diff --git a/_includes/post_link.html b/_includes/post_link.html
index da014bb..d996920 100644
--- a/_includes/post_link.html
+++ b/_includes/post_link.html
@@ -1,3 +1,7 @@
+{% comment %}
+    Generates a link to a single post. 
+    Expects the page representing the post as a 'post' variable. 
+{% endcomment %}
 
 <div class="post-link">
     <h3 class="post-title">
@@ -7,8 +11,7 @@
     </h3>
     <p class="post-meta" >
         {% assign firsttag = post.tags | first %}
-        {% assign tmp_list = site.tagpages | where:"tag", firsttag %}
-        {% assign type = tmp_list | first %}
+        {% assign type = site.tagpages | where:"tag", firsttag | first %}
         <span class="post-type">{{ type.title }} by {{post.author}}</span> -
         {% if post.location %}<span class="post-location">{{post.location}}</span> - {% endif %}
         <span class="post-date">{{ post.date | date_to_string }}</span>
diff --git a/_includes/posts.html b/_includes/posts.html
deleted file mode 100644
index afce226..0000000
--- a/_includes/posts.html
+++ /dev/null
@@ -1,33 +0,0 @@
----
-layout: page
-title: Project Activites
-alltags: True
-menu_order: 101
----
-
-{% comment %}
-Project activities are generated through the /_posts/ folder
-{% endcomment %}
-
-<h2>By tag</h2>
-
-{% assign with_post_numbers = true %}
-{% include tags_module.html %}
-
-<div class="tagcloud" >
-    <span class="tag" ><a class="btn btn-default" href="{{ site.blog_path}}">All activites <span class="badge">{{ site.posts.size }}</span></a></span>
-{{ tagscontent }}
-</div>
-
-
-<h2>Most recent activites</h2>
-
-{% for post in site.posts %}
-    {% if forloop.index < 5 %}
-    {% include post_link.html %}
-    {% endif %}
-{% endfor %}
-
-<a href="{{ site.blog_path}}">See all</a>
-
-
diff --git a/_layouts/default.html b/_layouts/default.html
index 9bc8f16..f03a9d3 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,6 +1,7 @@
 ---
 layout: compress
 ---
+{% assign sorted_pages = site.pages | sort: "menu_order" %}
 
 <!DOCTYPE html>
 <html lang="en-us">
-- 
GitLab