Шпаргалка. Оптимизации верстки шаблона в битриксе

 Этот пост призван дополнить или расширить прошлые посты об оптимизации загрузки сайта: 
Итак, задачи, которые я решаю в этом посте - отложенная загрузка скриптов и инлайн CSS стилей сайта (актуально для сайтов, чьи стили укладываются в 50-100кб). 

1. header.php шаблона сайта:
//$APPLICATION->ShowHead();
      
$APPLICATION->ShowMeta('keywords');      // Вывод мета тега keywords
$APPLICATION->ShowMeta('description');   // Вывод мета тега description
$APPLICATION->ShowCSS();                 // Подключение основных файлов стилей
      
if($USER->IsAdmin())
   $APPLICATION->ShowHeadStrings();      // Отображает специальные стили, JavaScript
Здесь ShowHead заменяем на его составляющие 

2. footer.php шаблона сайта
$APPLICATION->ShowHeadScripts();         // Вывод служебных скриптов
Здесь подключаем скрипты. Зачем внизу? Что бы не тормозить отображение страницы, пока грузятся скрипты 

3. init.php (или functions.php, если подключаем его):
AddEventHandler('main', 'OnEndBufferContent', 'deleteKernelCss');

function deleteKernelCss(&$content) {
   global $USER, $APPLICATION;
   
   if((is_object($USER) && $USER->IsAuthorized()) || strpos($APPLICATION->GetCurDir(), "/bitrix/")!==false) return;
   if($APPLICATION->GetProperty("save_kernel") == "Y") return;

   $arPatternsToRemove = Array(
      '/<li nk.+?href=".+?kernel_main\/kernel_main\.css\?\d+"[^>]+>/',
   );

   $content = preg_replace($arPatternsToRemove, "", $content);
   $content = preg_replace("/\n{2,}/", "\n\n", $content);
}

AddEventHandler("main", "OnEndBufferContent", "includeCssInline");

function includeCssInline(&$content) {
   global $USER, $APPLICATION;
   
   if((is_object($USER) && $USER->IsAuthorized()) || strpos($APPLICATION->GetCurDir(), "/bitrix/")!==false) return;
   if($APPLICATION->GetProperty("save_kernel") == "Y") return;

   preg_match('/<li nk.+?href="(\/bitrix\/cache\/css\/'.SITE_ID.'\/'.SITE_TEMPLATE_ID.'\/template_[^"]+)"[^>]+>/', $content, $arMatches);
   $sFilePath = "http://".$_SERVER["HTTP_HOST"].$arMatches[1];
   
   $obCache = new CPHPCache;
   $life_time = 0*60;
   
   if($obCache->InitCache($life_time, $sFilePath, "/")) {
      $vars         = $obCache->GetVars();
      $sIncludeCss      = $vars["sIncludeCss"];
      $sIncludeCssClear   = $vars["sIncludeCssClear"];
      
   } else {
      $sIncludeCss      = file_get_contents($sFilePath);
      $sIncludeCssClear   = compressCSS($sIncludeCss);
      
   }
   
   if(false) {
      ?><pre style="font-size:10px;line-height: 8px;">До: <?=strlen($sIncludeCss);?></pre><?
      ?><pre style="font-size:10px;line-height: 8px;">После: <?=strlen($sIncludeCssClear);?></pre><?
   }
   
   $content = str_replace($arMatches[0], "<st yle>$sIncludeCssClear</style>", $content);
   
   if($obCache->StartDataCache()) {
      $obCache->EndDataCache(array(
         "sIncludeCss" => $sIncludeCss,
         "sIncludeCssClear" => $sIncludeCssClear,
      ));
   }
}

function compressCSS($css, $arOptions = Array()) {
   $sResult = $css;
   
   $sResult = preg_replace("/\/\*[^*]+\*\//", "", $sResult);            // comments
   $sResult = preg_replace("/\/\**\*\//", "", $sResult);                // comments
   $sResult = preg_replace("/\s*(:|,|;|{|}|\t)\s*/", "$1", $sResult);   // whitespaces
   $sResult = preg_replace("/(\t+|\s{2,})/", " ", $sResult);            // tabs and double whitespace
   $sResult = preg_replace("/(\s|:)([\-]{0,1}0px)\s/", " 0 ", $sResult);// zeros
   //$sResult = preg_replace("/#(\w){6};/", "#$1$1$1;", $sResult);      // #dddddd => #ddd

   return $sResult;
}
Здесь, если не установлено свойство страницы "save_kernel = Y" из страницы исключается kernel.css и template.css заменяется на инлайновое представление, так экономится один GET запрос к серверу и страница быстрее отображается. 
Но момент с CSS неоднозначный, т.к. не будь он инлайном, то мог бы и кешироваться на стороне браузера. Я считаю, что если этот файл получается небольшим, то лучше его инлайнить, особенно, если работает gzip. 

P.S. Написал тут обращение разработчикам, что бы добавили события на формирование файла template.css после объединения всех CSS шаблона - дополнительно можно было бы заменить маленькие картинки (скажем, до 2кб) на их base64 аналог. В таком случае нам бы не понадобилось грузить CSS иналайном. Ну или можно было бы разделить - загружать важный css инлайном, а остальное внизу страницы. 

P.P.S. Пытался решить задачу замены цветов типа #dddddd на #ddd с помощью регулярных выражений, но так и не получилось. Вот такая регулярка:
#(\w){6};
забирает любое представление цвета, т.к. \w - это любая буква или число. По идее, регулярным выражением нужно получить 6 одинаковых(!) символов, а не "\w", но как это сделать я не знаю. Может подскажете? :)