Pull to refresh

Ускоряем wordpress

Reading time 11 min
Views 10K
Привет.
Думаю, среди читателей хабра найдется немало тех, кто имеет stand-alone blog на движке wordpress.

Так вот, для вас, дорогие мои, у меня есть две новости, как водится, плохая и хорошая.
Плохая состоит в том, что wordpress — довольно-таки тормознутая штука.
Виноваты в этом в основном криворукие производители тем и, особенно, криворукие производители плагинов. Особенно кривой плагин, на мой вкус, wp-ajax-edit-comments, который является образцом быдлокодинга.

Хорошая — в том, что это можно поправить.


Теория



Сначала немного теории. Уже довольно давно умные люди из компании Yahoo провели исследования на тему «как же нам ускорить наши сайты». И выяснили, что на скорость сайта с точки зрения пользователя в основном влияет оптимизация front-end'a, а не server-side. Подробнее об этом можно почитать на сайте webo.in на русском и на сайте yahoo на английском, я же просто опишу несколько простых шагов, которые позволят существенно ускорить скорость работы своего блога.

Предупреждение: хотя я и старался максимально упростить текст, сведя его к набору инструкций, все же большинство шагов можно выполнить только имея опыт разработки веб-сайтов, так что, если вы не программист, то лучше попросите знакомого программиста выполнить эти шаги за вас. Да, и на всякий случай, не забудьте забэкапиться :)

Перед тем, как мы перейдем к практике, я напомню нашу основную цель: блог на движке wordpress должен работать с точно тем же функционалом, что и раньше, но, с точки зрения пользователя, работать быстрее. Итак, погнали:

Практика



Оптимизируем тему



Да, открытость платформы Wordpress — это очевидное благо. Я серьезно.
Множество прекрасных дизайнеров, верстальщиков, программистов с горящими от энтузиазма глазами вдохновенно, вдумчиво создают темы и плагины для всех, для всего человечества, не требуя ничего взамен. Это действительно прекрасно.

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

Еще большее сожаление прогрессивно мыслящей части человечества вызывает тот факт, что уебанов больше, чем титанов духа, и в связи с этим сеть полна бесплатного говна.

Таким образом, нам надо исправить недостатки, которые (возможно) присущи вашей любимой теме от рождения и поправить ее код.

Итак, для того, чтобы тема стала работать быстрее, надо сделать следующее:
  1. Если тема сверстана на таблицах, переверстать ее на дивы. Я не буду касаться давнего спора «как вестать — дивами и таблицами», замечу только, что точки зрения поставленной перед нами цели (быстро работающий с точки зрения пользователя блог) таблицы проигрывают дивам — потому что таблица отрисовывается браузером только после того, как будет полностью загружена, тогда как дивы отрисовываются сразу, как только браузер получит их с сервера. А значит, если страница сверстана в дивах, пользователь быстрее увидит контент сайта, что нам и нужно, не так ли?Кроме того, как указывает в комментариях len:
    верстка div-ами вместе с разбиением странички на файлы типа left-sidebar, right-sidebar, header, footer etc. позволит быстрее и проще поменять какой-нибудь небольшой кусочек кода прямо из панели управления движком (Дизайн -> Редактор тем), чем попытки из этой же панели управления поменять кусочек своей табличной верстки, в которой можно потеряться за забором из tr и td.
  2. Вы будет смеяться, но нужно убрать все стилевые правила во внешние файлы. И JavaScript — тоже. Это настолько очевидно, что я даже не буду пояснять, зачем это нужно.
  3. Внешний стилевой файл прописываем в блоке head, а JavaScript файл подключаем как можно ближе к закрывающему тэгу «body». И все скрипты аналитиков тоже располагаем пониже.
  4. Сжимаем js и css. Для этого мы будем использовать yui-comressor. Делается это примерно так: качаем последний стабильный релиз YUICompressor'a с официального сайта, устанавливаем, если еще не установлено JRE и выполняем на css/js файл команду следующего вида:

    java -jar /path/to/yuicompressor-*.*.*.jar -o "output_filename" src_file

    * This source code was highlighted with Source Code Highlighter.




можно использовать флаг -type, который указывает, какой тип файла (css или js). Если флаг не указан, то тип файла определяется по расширению.

Можете использовать тему моего блога как пример. Ниже я привел пример shell-скрипта, который можно натравить на директорию, в которой расположена тема, и он все сделает за вас.

Уменьшаем количество файлов



Так как мы можем серьезно ускорить скорость загрузки файлов, уменьшив число этих файлов (удивительно, правда? :), то разумнее всего будет слить все css-файлы и js-файлы в один. Если эти файлы размером больше ~70 килобайт, то лучше разбить их на два куска.

Если нужно уменьшить количество картинок, используя технику css спрайтов и технику image map.

Тут надо отдельно заметить, что у многих (практически у всех) плагинов есть совершенно идиотская особенность — прописывать свои js и css файлы. Идиотизм заключается в том, что очень часто разные плагины используют одну и ту же библиотеку, и подключают ее по нескольку раз. И пользователь, просматривающий ваш блог, вынужден по два-три раза грузить, к примеру, prototype или jquery. Лишние ~30-160+ KB. Неслабо, прадва?

Тех. заметка: при этом совершенно непонятно, что мешало создателям wordpress сделать контроль надо всеми ресурсами, что прописывают плагины, как сделано, к примеру, в RichFaces. К примеру, если один плагин, которому нужен jQuery, прописывает тэг script с jQuery и рапортует — «Вот мол, подгрузил, все, кому надо, могут использовать», а другой, которому тоже нужен jQuery уже знает об этом и не подгружает свой вариант.

Лечится это так — все скрипты, что подгружают плагины слейте с теми, что написали сами и воткните в футер, а плагинам запретите их подгружать. Тоже самое сделайте с css, только воткните в header.

Оптимизируем графику



Картинки в png и jpg форматах довольно часто неоптимизированы и хранят много лишней информации. Было бы неплохо избавиться от этой лишней информации и таким образом сжать файлы. Делается это с помощью специальных утилит. Это позволит нам уменьшить их размер в отдельных случаях на 50 процентов. Неслабо, правда?

При этом сами картинки не изменятся и все так же будут радовать глаз пользователей.

Информацию об этих утилитах и команду я позаимствовал у Дмитрия Ищенко. Надеюсь, он не в обиде :)

Итак, для оптимизации всего png картинок мы будем использовать pngcrush. Я затрудняюсь ответить, как ее инсталлировать на windows или linux, но я на своем mac'e без проблем установил эту утилиту из портов.

Чтобы сжать png-файлы без потери качества, используйте следующую команду:
pngcrush -rem alla -reduce -brute image.png result.png

* This source code was highlighted with Source Code Highlighter.


Для сжатия jp(e)g-файлов используйте jpegtran, которая входит в пакет libjpg, который я также установил из портов. Команда для сжатия jp(e)g-файлов без потери качества:

jpegtran -copy none -optimize -perfect src.jpg dest.jpg

* This source code was highlighted with Source Code Highlighter.


Я тут набросал shell-скрипт, который рекурсивно пройдет по директории и оптимизирует все png/jp(e)g картинки в ней:

for file in `find . -iname "*.jpg" -or -iname "*.png" -or -iname "*.jpeg"`;do
  ext=${file##*.}
  if [ -n "$ext" ]; then
    if [ "$ext" = "jpg" ]; then
      echo "optimizing ${file} as jpeg file with jpegtran"
      jpegtran -copy none -optimize -perfect -outfile temp_abracadabra_filename.jpg $file
      mv -f temp_abracadabra_filename.jpg $file;
    fi
    if [ "$ext" = "jpeg" ]; then
      echo "optimizing ${file} as jpeg file with jpegtran"
      jpegtran -copy none -optimize -perfect -outfile temp_abracadabra_filename.jpeg $file
      mv -f temp_abracadabra_filename.jpeg $file;
    fi
    if [ "$ext" = "png" ]; then
      echo "optimizing ${file} as png file with pngcrush"
      pngcrush -rem alla -reduce -brute "$file" temp_abracadabra_filename.png;
      mv -f temp_abracadabra_filename.png $file;
    fi
  fi
done;


* This source code was highlighted with Source Code Highlighter.


Просто выполните его в директории uploads что в папке wp-content и все будет хорошо. Можно даже повесить его на cron-job и больше не париться на этот счет — все вновь прибывшие файлы будут оптимизироваться.

Разумеется, надо оптимизировать графику, используемую в теме, так что вот еще один shell-скрипт, который рекурсивно пройдет по директории, сожмет css, js файлы и оптимизирует jp(e)g/png файлы. На всякий случай перед его использованием не забудьте забэкапиться:

for file in `find . -iname "*.jpg" -or -iname "*.jpeg" -or -iname "*.png" -or -iname "*.js" -or -iname "*.css" `;do
  ext=${file##*.}
  if [ -n "$ext" ]; then
    if [ "$ext" = "css" ]; then
      echo "compressing ${file} as css file with yui compressor"
      java -jar /opt/yuicompressor/yuicompressor-2.3.5.jar --type css -o "temp_abracadabra_filename.css" $file
      mv -f temp_abracadabra_filename.css $file;
    fi
    if [ "$ext" = "js" ]; then
      echo "compressing ${file} as js file with yui compressor"
      java -jar /opt/yuicompressor/yuicompressor-2.3.5.jar --type js -o "temp_abracadabra_filename.js" $file
      mv -f temp_abracadabra_filename.js $file;
    fi
    if [ "$ext" = "jpg" ]; then
      echo "optimizing ${file} as jpeg file with jpegtran"
      jpegtran -copy none -optimize -perfect -outfile temp_abracadabra_filename.jpg $file
      mv -f temp_abracadabra_filename.jpg $file;
    fi
    if [ "$ext" = "jpeg" ]; then
      echo "optimizing ${file} as jpeg file with jpegtran"
      jpegtran -copy none -optimize -perfect -outfile temp_abracadabra_filename.jpeg $file
      mv -f temp_abracadabra_filename.jpeg $file;
    fi
    if [ "$ext" = "png" ]; then
      echo "optimizing ${file} as png file with pngcrush"
      pngcrush -rem alla -reduce -brute "$file" temp_abracadabra_filename.png;
      mv -f temp_abracadabra_filename.png $file;
    fi
  fi
done;


* This source code was highlighted with Source Code Highlighter.


Используйте меньше dns-lookups. Не выкладывайте картинки, src которых указывает на другой ресурс, лучше загрузите их к себе и пропишите ссылку на автора. Работать будет быстрее.

Сжатие



Все современные браузеры поддерживают сжатие, так что можно существенно уменьшить размер отдаваемых файлов (а значит, и время их загрузки) при помощи mod_deflate (для Apache 2.2 для Apache 1.3 надо использовать mod_gzip). Так что включите mod_deflate. Если же вы используете Apache 1.3, ниже приведенный код вам не не нужен, вам поможет статья «mod_gzip — сжатие html страниц 'на лету'» на сайте webo.in.

Найдите файл .htaccess в корневой директории установки wordpress и добавьте в конец следующее:

<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml
  SetOutputFilter DEFLATE
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
  SetEnvIfNoCase Request_URI \.(?:gif|png)$ no-gzip dont-vary
  Header append Vary User-Agent env=!dont-vary
</IfModule>


* This source code was highlighted with Source Code Highlighter.


Таким способом можно добиться уменьшения js/css/html файлов на 70-80%, и примерно 10% уменьшения jpeg-файлов, что значительно ускоряет загрузку сайта. Следует, правда, помнить, что использования mod_deflate увеличивает нагрузку на сервер, так как ему нужно сжать файлы перед тем, как отдать их, так что стоит проконтролировать, что использование mod_deflate не создает чрезмерной нагрузки на сервер.

Кеширование



Ну и последнее — для того, чтобы ускорить серфинг по вашему сайта нужно врубить кеширование. Это не ускорит загрузку сайта у пользователя, который первый раз пришел на ваш сайт, но положит все внешние js, css файлы, картинки к нему в кеш, и в следующий раз, когда он будет бродить по вашему сайту, ресурсы будут грузиться не с сервера, а из кеша, что значительно ускорит скорость работы вашего сайта с _точки зрения пользователя_, а также значительно снизит нагрузку на ваш сервер. Помните, что закешированные у пользователя файлы берутся из кеша браузера, поэтому, если вы внесете изменения в файл, скажем, стилей, пользователь, закешировавший style.css, не увидит их. Так что лучше включать кеширование после того, как вы доработали тему.

Опять же, добавьте следующие строчки в конец файла .htaccess и не забудьте включить mod_headers и mod_expires (или хотя бы один из них):

# используем mod_expires
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault A86400    
  ExpiresByType image/x-icon A2592000
  ExpiresByType application/x-javascript A2592000
  ExpiresByType text/css A2592000
  ExpiresByType image/gif A604800
  ExpiresByType image/png A604800
  ExpiresByType image/jpeg A604800
  ExpiresByType text/plain A604800
  ExpiresByType application/x-shockwave-flash A604800
  ExpiresByType video/x-flv A604800
  ExpiresByType application/pdf A604800
  ExpiresByType text/html A900
</IfModule>

# используем mod_header
<IfModule mod_header.c>
  # 3 Month
  <FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|swf)$">
    Header set Cache-Control "max-age=7257600"
  </FilesMatch>
  # 1 Week
  <FilesMatch "\.(js|css|pdf|txt)$">
    Header set Cache-Control "max-age=604800"
  </FilesMatch>
  # 10 Minutes
  <FilesMatch "\.(html|htm)$">
    Header set Cache-Control "max-age=600"
  </FilesMatch>
  # NONE
  <FilesMatch "\.(pl|php|cgi|spl)$">
    Header unset Cache-Control
    Header unset Expires
    Header unset Last-Modified
    FileETag None
    Header unset Pragma
  </FilesMatch>
</IfModule>


* This source code was highlighted with Source Code Highlighter.


Кеширование на стороне сервера



Осторожно: этот пункт выполняйте с осторожностью (или, если вы не уверены в том, что делаете, вообще его пропустите), у многих использование перечисленых ниже плагинов вызывает проблемы.

Есть несколько плагинов к wordpress'у, которые позволяют кешировать файлы на стороне сервера. Работают они по такому принципу: как только какая-то из ваших страниц запрашвается на сервере, она динамически строится и создается html-файл со всеми данными, который ложится в кеш. Как только приходит запрос на эту страницы, пользователю отдается html файл вместо того, чтобы динамически строить страничку, что значительно снижает нагрузку на сервер (теперь ведь не прогоняются php-скрипты и не нагружается база данных).
К сожалению, все эти плагины работают как-то очень странно, во всяком случае, у меня не работали должным образом ни wp-cache, ни работающий на его основе wp-super-cache.
Зато работает 1 Blog Cacher, правда, у него достаточно сложная настройка. Надеюсь, вы разберетесь. Я использую его.

Итого



После того, как я провел над своим блогом ряд этих нехитрых действий, блог стал загружаться на 80% быстрее.
Теперь perfomance meter моего сайта с точки зрения плагина к firebug'у YSlow равен B(85), был F(33). Думаю, неплохой результат.
Кросс-пост в моем блоге.
Tags:
Hubs:
+41
Comments 35
Comments Comments 35

Articles