Поговоримо трішки про оптимізацію завантаження сторінки в 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 хз, не розглядав, та й пора вже забути про неї))). Та й вищеописана техніка зовсім не панацея, до кожного потрібен індивідуальних підхід.
Дякую за увагу!