Последние времена я не только активно изучаю наш любимый modx, но и всячески работаю над улучшением видимости сайта в поисковиках. Каждый год у них что-то меняется и появляются новые веяния и требования (или, как я их называю — мода).

Итак. В данном материале предлагаю поговорить о Google и общих способах привлечь его высокие чувства, получив максимум в процентном соотношении здесь developers.google.com/speed/pagespeed/insights/. О 100% не упоминаю, так только 1 раз я смогла прийти к этому числу, остальные варьируются в основном от 92% до 96%.

Что же влияет на эти данные?

1. Хостинг
Да, к сожалению не все зависит от нас. Я, как коренная белоруска, пользуюсь в основном отечественными поставщиками «места» для файлов. И замечаю, что сложности не только в отношении .htaccess к Apache и Nginx, но и в том «не забыл» ли хостер чего то включить. Чаще всего — это кэширование в Nginx (его «забывает» Бестхост) и GZIP (не напомнишь — не включат), который тоже включается ручками или мольбами к хостинг-дядям.

2. Снова хостинг
Версия php, оборудование хостера, количество человек в техподдержке (и доступность их телефонов) — это тоже важно! А то у меня есть десяток сайтов, которые по ночам «куда — то» исчезают на пару минут и Яндекс Вебмастер забрасывает меня смс, не давая даже пары часов поспать. Так что стабильность важна не менее (хоть и не столько для Корпорации Добра, сколько для своего морального здоровья)

3. Главней всего ОН — htaccess
Да. Именно он! Яркий пример — замена стандартного файлика MODX на свой прибавляет на десяток пунктов (если пункт 1 выполнен верно, то и больше). Что здесь должно быть? Время кэша. Это святое. И не забываем про шрифты, картинки и прочее. Кэш на месяц — Google спокоен и мирно отдает зеленый спектр по загрузке. Например:
RewriteEngine on
	RewriteBase /
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\.mysite\.by [NC]
RewriteRule (.*) http://www.mysite.by/$1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.(php|html|htm)\ HTTP/ 
RewriteRule ^(.*)index\.(php|html|htm)$ $1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

DirectoryIndex index.php

ServerSignature Off
AddDefaultCharset UTF-8

<ifModule mod_php.c>
  php_value	upload_max_filesize	8M
  php_value	post_max_size		10M
  php_value	default_charset utf-8
  php_value	max_execution_time 200
</ifModule>

AddHandler application/x-httpd-php .html
AddHandler cgi-script .pl .py .jsp .asp .htm .shtml .sh .cgi
AddType application/x-javascript .js
AddType text/css .css
AddType text/xml .xml
AddType application/octet-stream .doc .mov .avi .pdf .xls 
# ForceType application/x-httpd-php


<ifModule mod_deflate.c>
	AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
</ifModule>
<ifModule mod_headers.c>
  Header unset Vary
  Header set Vary "Accept-Encoding, X-HTTP-Method-Override, X-Forwarded-For, Remote-Address, X-Real-IP, X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Server"
</ifModule>
<IfModule mod_gzip.c>
	mod_gzip_on         Yes
	mod_gzip_dechunk    Yes
	mod_gzip_item_include file		\.(html?|txt|css|js|php|pl)$
	mod_gzip_item_include mime		^text\.*
	mod_gzip_item_include mime		^application/x-javascript.*
	mod_gzip_item_exclude mime		^image\.*
	mod_gzip_item_exclude rspheader	^Content-Encoding:.*gzip.*
</IfModule>
<IfModule mod_setenvif.c>
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>
<FilesMatch \.(eot|ttf|otf|svg|woff)$>
    ExpiresDefault "access plus 1 year"
  </FilesMatch>
  ExpiresByType application/x-font-ttf    "access plus 1 month"
  ExpiresByType font/opentype             "access plus 1 month"
  ExpiresByType application/x-font-woff   "access plus 1 month"
  ExpiresByType image/svg+xml             "access plus 1 month"
  ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

<ifModule mod_headers.c>
	#кэшировать html и htm файлы на один день
	<FilesMatch "\.(html|htm)$">
		Header set Cache-Control "max-age=43200"
	</FilesMatch>
	#кэшировать css, javascript и текстовые файлы на одну неделю
	<FilesMatch "\.(js|css|txt)$">
		Header set Cache-Control "max-age=604800"
	</FilesMatch>
	#кэшировать флэш и изображени¤ на мес¤ц
	<FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|png)$">
		Header set Cache-Control "max-age=2592000"
	</FilesMatch>
	#отключить кэширование
	<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">		
		Header set Cache-Control "max-age=1"
	</FilesMatch>
</IfModule>

<ifModule mod_expires.c>
	ExpiresActive On
	#по умолчанию кеш в 10 секунд
	ExpiresDefault "access plus 10 seconds"
	#кэшировать флэш и изображени¤ на мес¤ц
	ExpiresByType image/x-icon "access plus 2592000 seconds"
	ExpiresByType image/jpeg "access plus 2592000 seconds"
	ExpiresByType image/png "access plus 2592000 seconds"
	ExpiresByType image/gif "access plus 2592000 seconds"
	ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
	#кэшировать css, javascript и текстовые файлы на одну неделю
	ExpiresByType text/css "access plus 604800 seconds"
	ExpiresByType text/javascript "access plus 604800 seconds"
	ExpiresByType application/javascript "access plus 604800 seconds"
	ExpiresByType application/x-javascript "access plus 604800 seconds"
	#кэшировать html и htm файлы на один день
	ExpiresByType text/html "access plus 43200 seconds"
	#кэшировать xml файлы на дес¤ть минут
	ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>

Бездумно не копируем!!! Сайты без www в начале замрите и присмотритесь к верхней части кода.

4. Сжатие
Да, мне тоже удобно, когда CSS каждая строка с новой, а вот поиску это не нравится. Закончили проект — минифицируемся. Хорошо зарекомендовал себя csscompressor.com/ для стилей. Скрипты не ломает сам Гугл Speed (скачиваем на закладке ДЛЯ КОМПЬЮТЕРОВ), когда-то находила еще минификатор JS, но умудрилась ссылку где-то затерять. Для картинок хороши optimizilla.com/ru/ онлайн, Light Image Resizer и Caesium для jpg (скачиваются и ставятся на ПК).
Если удаленно лень, то посмотрите на modstore.pro/packages/utilities/minifyx и что-то на основе THUMB для сжатия и обрезки фото.

5. Убираем скрипты и стили из HEAD
И Вы не ослышались. Стили убираем. Серьезно убираем. Все!
Да, согласно, страница а-ля собираться стала. Но. Гугл нам явно говорит — нет подключению стилей в голове, при этом инлайн — только ЗА. Т.е. что мы делаем: берем сайт, выносим ВСЕ стили, касающиеся его верхней части в отдельный файл, убеждаемся, что все нашли. Теперь то, что есть — максимально сжимаем и подключаем в HEAD через
<style>navbar{color:blue}</style>

Здесь же может быть и сетка бутстрапа, чтобы ничего не плыло. Перебарщивать тоже не желательно. Всегда помните о капризе Корпорации Добра:
Удалось загрузить страницу только на **%
Это значит, что все, пора остановиться и дать пользователю немного из BODY

6. Статистику в кэш!
Есть еще одна штука — Яндекс Метрика или тот же Гугл Аналитик, которые всего то на 30 минут кэшируются. Да, это противоречит само себе, но есть и на это решение. Нужен будет крон (запланированные задания). Что делаем? Качаем пару раз в сутки новый скрипт от статистики и спокойно его в кэш. Первое время мои хостеры оф… ли, но потом ко мне привыккли, а Google и того сильнее стал мои сайты «любить».
Порядок действий:

Выбираем место для хранения. Например assets/templates/cachejs
В нем создаем файлик *.php (по сути можно и средствами MODX, но по мне — так шустрее):
downloadjs.php
<?php
 
function downloadJs($file_url, $save_to)
{
    $content = file_get_contents($file_url);
    file_put_contents($save_to, $content);
}
downloadJs('https://mc.yandex.ru/metrika/watch.js', realpath("") . '/watch.js');
downloadJs('https://www.google-analytics.com/analytics.js', realpath("") . '/analytics.js');
downloadJs('http://adlik.akavita.com/acode.js', realpath("") . '/acode.js');
downloadJs('http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js', realpath("") . '/adsbygoogle.js');
downloadJs('https://pagead2.googlesyndication.com/pagead/osd.js', realpath("") . '/osd.js');
?>

Здесь мы перечисляем все внешние скрипты и их новые имена. Т.е. берем адрес к js у самого кода от сторонней системы и меняем его на свой.
В чанке, ребята, в чанке, где статистика у нас. Т.е. мы адрес mc.yandex.ru/metrika/watch.js на самом сайте меняем на site.ru/assets/templates/cachejs/watch.js
Дальше вызываем файлик, в котором мы перечислили ТОЛЬКО нужные нам скрипты, а не все из этого поста.
Проверяем, чтобы в его папке появились скачанные нами файлы.
Находим на сервере крон (может называться ЗАПЛАНИРОВАННЫЕ ЗАДАНИЯ) и указываем путь от корня сервера к нашему файлу с php
Cron — это такая штука, которая по указанному времени приходит и сама что-то делает. :)
0 	10,22 	* 	* 	* /usr/bin/php -f /home/mysite/public_html/assets/templates/js/cashe/downloadjs.php 

Выше я указала — приходить каждый день в 10 и 22 часа 00 минут и запускать файл по данному адресу.
У хостеров данная строка может отличаться. Лучше тестируйте или просите самого Хостера проверить ее. Данная работает на hoster.by

7. Мобильная версия
В мире бываю те, кто забывает о такой мелочи, как телефон. А Гугл помнит! Всегда помнит. Дайте ему
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi">
<meta name="MobileOptimized" content="320">

И проследите, чтобы все сжималось и летало быстро. Не надо телефонам Ваши бакграунды, особенно с видео. Не надо огромных и мелких букв. Будьте людьми, дайте человекам нормальное отображение и Добро будет с Вами.

На сегодня пока все, иначе на улице ночь, а я не работаю :) Нюансов на самом деле очень не мало, но я попробую в следующий раз дойти и до них :)
А если есть у кого свои наработки по ускорению — пишите! Будем разгоняться вместе с MODX!