Joomla 2.5: Оптимизация js и Асинхронная загрузка JavaScript
Поговорим немножко об оптимизации загрузки страницы в Joomla. На сегодня это будет подключение JavaScript. Во первых обращу внимание верстальщиков, на правильность построения шаблона. А потом рассмотрим встроенную в движок возможность использовать асинхронную загрузку внешних скриптов. Разглагольствовать для чего нужна оптимизация не буду.
Построение шаблона
Как правило верстальщики на Joomla не обращают внимание на порядок загрузки стилей и скриптов, а это важный аспект оптимизации для распараллеливания загрузки. CSS файлы следует всегда включать перед файлами JavaScript.
Если в Вашем шаблоне загрузка css и javascript выглядит следующим образом:
<!DOCTYPE html> <html> <head> <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico"> <jdoc:include type="head" /> <link rel="stylesheet" href="/templates/beez_20/css/style.css" type="text/css" /> <script src="/templates/beez_20/js/jquery-latest.min.js" type="text/javascript"></script> </head>
хочу вас заверить, это не правильно! Потому что вы загружаете внешние файлы после рендеринга страницы, а это значит что формирование блока head уже прошло, отсюда возникает хаос загрузки в шахматном порядке.
А вот как правильно включать файлы в рендеринг:
<?php defined( '_JEXEC' ) or die( 'Restricted access' ); $this->addStyleSheet($this->baseurl.'/templates/'.$this->template.'/css/style.css'); $this->addScript($this->baseurl.'/templates/'.$this->template.'/js/jquery-latest.min.js'); ?> <!DOCTYPE html> <html> <head> <jdoc:include type="head" /> </head>
Не обращаем внимание на валидность doctype и html, писал сокращенно для примера.
Асинхронная загрузка
А вот тут я бы больше заострил внимание и дочитал статью до конца! Часто заказчик на оптимизацию требует реализовывать асинхронную загрузку javascript. Как ни странно разработчики Joomla предусмотрели и такую возможность, а вот разработчики сторонних компонентом, модулей и плагинов забывают про данный функционал, видимо поэтому Jooml'у часто и критикуют за низкую оптимизацию, с чем бы я и поспорил.
Как рассматривалось ранее в рендеринге документа существует функция addScript();. Но видимо некоторые и не подозревают что она имеет четыре переменные - $url, $type, $defer, $async.
Если асинхронная загрузка скриптов нам не нужна достаточно использовать один атрибут $url, остальные подставляются по умолчанию ($type = "text/javascript", $defer = false, $async = false)
$this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js"); $this->addScript($this->baseurl."/templates/beez_20/js/script.js");
Но в нашем случае нам необходимо загрузку скриптов браузером поставить в очередь, для этого необходимо использовать атрибут async и/или defer. Оба отличаются лишь тем что defer сохраняет порядок выполнения скриптов. Defer нужен в том случае если script.js используется фреймворк jQuery, который предотвратит его загрузку раньше самой библиотеки, ну и если необходимо сохранить некую последовательность.
И так что бы включить асинхронную загрузку необходимо использовать все переменные
$this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript"); // или $this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript", false, false); // Выводит <script src="/templates/beez_20/js/jquery-latest.min.js" type="text/javascript"></script> $this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript", true, false); // Выводит <script src="/templates/beez_20/js/jquery-latest.min.js" type="text/javascript" defer="defer"></script> $this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript", false, true); // Выводит <script src="/templates/beez_20/js/jquery-latest.min.js" type="text/javascript" async="async"></script>
И еще один маленький моментик. В принципе данные атрибуты это элементы HTML5, следовательно нет смысла использовать вид async="async" и defer="defer", достаточно async и defer соответственно.
Внесем коррективы в библиотеку joomla. Открываем сайт.ру/libraries/joomla/document/html/renderer/head.php
Ищем (примерно строка 150):
// Generate script file links foreach ($document->_scripts as $strSrc => $strAttr) { $buffer .= $tab . '<script src="' . $strSrc . '"'; if (!is_null($strAttr['mime'])) { $buffer .= ' type="' . $strAttr['mime'] . '"'; } if ($strAttr['defer']) { $buffer .= ' defer="defer"'; } if ($strAttr['async']) { $buffer .= ' async="async"'; } $buffer .= '></script>' . $lnEnd; }
заменяем на:
// Generate script file links foreach ($document->_scripts as $strSrc => $strAttr) { $buffer .= $tab . '<script src="' . $strSrc . '"'; if (!is_null($strAttr['mime'])) { $buffer .= ' type="' . $strAttr['mime'] . '"'; } if ($strAttr['defer']) { $buffer .= ' defer'; } if ($strAttr['async']) { $buffer .= ' async'; } $buffer .= '></script>' . $lnEnd; }
Вот и вся соль. Все манипуляции мной проводились в Joomla 2.5, как это будет работать в 1.5 хз, не рассматривал, да и пора уже забыть про нее ))). Да и вышеописанная техника совсем не панацея, к каждому нужен индивидуальных подход.
Спасибо за внимание!