Large, Complex Navigation
It's those two lines that trigger database queries

{% set url = node.url|length ? node.url : node.linkedEntry|length ? node.linkedEntry.first().url : node.customUrl %}
{% set class = node.children|length ? "has-children" %}


The first one can be optimized by using the first method in the ternary condition. You just need to know if there is a linked entry, not how many. node.linkedEntry|length queries for all matching entry models and is slower than
just calling node.linkedEntry.first(). So change it to

{% set url = node.url|length ? node.url : node.linkedEntry.first() ? node.linkedEntry.first().url : node.customUrl %}


Same applies to the node.children criteria model in the second line. Change it accordingly

{% set class = node.children.first() ? "has-children" %}


That's about all you can do to optimize the code, now you should definitly add caching to it. It's not as straightforward to implement in this situation, as there's the dynamic "active" class you want to add to the output. So you have to either cache the whole navigation for each page it's used individually (each with the active class at the right place) or you use the string replacement technique described in this SE to cache the navigation globally for all pages.