Речь пойдет о том, как создавать сложные меню и выводить их в шаблоне. Так же добавим немного динамичности с помощью Cron'а
Собственно создаем файл с любым именем и подключаем пролог сайта
define('STOP_STATISTICS', true);
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
$GLOBALS['APPLICATION']->RestartBuffer();
Ядро подключено. далее подключаем те модули, которые будут необходимы для генерации самого меню. Например - модуль sale и iblock
use Bitrix\Main\Loader; 

Loader::includeModule("iblock"); 	
Loader::includeModule("sale"); 	
Всё, дальше пишем логику формирования массивов, с которыми будем работать, например выборку разделов с инфоблока
$arFilter = Array('IBLOCK_ID'=>$iblock_id, "DEPTH_LEVEL" => 1);  
$db_list = CIBlockSection::GetList(Array($by=>$order), $arFilter, true, array('IBLOCK_ID',"NAME","ID","CODE"));  
while($arSection = $db_list->GetNext())
{	
	//формируем массивы данных
} 
Далее все собранные массивы необходимо перебрать, сформировать html самого меню и сохранить в файл
ob_start();	//всё, что идёт дальше - пишется в буфер вывода?>
//Тут уже идёт формирование HTML-кода
$out = ob_get_contents();	//для удобства сохраняем буфер в переменную 
$fp = fopen('/АБСОЛЮТНЫЙ_ПУТЬ_ДО_ФАЙЛА_ОТ_КОРНЯ_СЕРВЕРА/menu.html', 'w');	//открываем файл на запись
fwrite($fp, $out);	//сохраняем буфер в файл
fclose($fp);
Готово. Теперь подключение данного файла делаем в header.php через обычный include_once();
include_once("/АБСОЛЮТНЫЙ_ПУТЬ_ДО_ФАЙЛА_ОТ_КОРНЯ_СЕРВЕРА/menu.html");
Теперь клиенту отдаётся только кусок html кода, а вся логика и, зачастую, огромные выборки, от которых не спасает ни кэширование, ни композитный режим. Осталось прикрутить генерацию нашего меню на крон примерно так:
*/5 * * * *     /opt/php71/bin/php -f АБСОЛЮТНЫЙ_ПУТЬ_ФАЙЛА_ГЕНЕРАЦИИ.php > /dev/null