— получили HTML

— запросили ресурс A+B+C: T1

— получили ресурс A+B+C: L + R(A + B + C)

Очевидна экономия в 2(T1 + L).Для 20 ресурсов эта экономия составит уже 19(T1 + L). Если взять достаточно типичные сейчас для домашнего/офисного Интернета значения скорости в 256 Кбит/с и пинга ~20-30 мс, получим экономию в 950 мс — одну секунду загрузки страницы. У людей же, пользующихся мобильным или спутниковым интернетом с пингом более 300 мс, разница времен загрузки страниц составит 6-7 секунд.На первый взгляд, теория говорит, что загрузка страниц должна стать быстрее. В чем же она разошлась с практикой?<p>Суровая реальность</p>Пусть у нашего сайта есть три страницы — P1, P2 и P3, поочередно запрашиваемые новым пользователем. P1 использует ресурсы A, B и C, P2 — A, С и D, а P3 — A, С, E и F. Если ресурсы не объединять, получаем следующее:

P1 — тратим время на загрузку A, B и C

P2 — тратим время на загрузку только D

P3 — тратим время на загрузку E и F

Если мы слили воедино абсолютно все JavaScript-модули сайта, получаем:

P1 — тратим время на загрузку (A+B+C+D+E+F)

P2 — внешние ресурсы не требуются

P3 — внешние ресурсы не требуются

Результатом становится увеличение времени загрузки самой первой страницы, на которую попадает пользователь. При типовых значениях скорости/пинга мы начинаем проигрывать уже при дополнительном объеме загрузки в 23 Кб.Если мы объединили только модули, необходимые для текущей страницы, получаем следующее:

P1 — тратим время на загрузку (A+B+C)

P2 — тратим время на загрузку (A+C+D)

P3 — тратим время на загрузку (A+С+E+F)

Каждая отдельно взятая страница при пустом кэше будет загружаться быстрее, но все они вместе — медленнее, чем в исходном случае. Получаем, что слепое использование модного сейчас объединения ресурсов часто только ухудшает жизнь пользователя.<p>Возможное решение</p>Конечно же, выход из сложившегося положения есть. В большинстве случаев для получения реального выигрыша достаточно выделить «ядро» — набор модулей, используемых на всех (или, по крайней мере, на часто загружаемых) страницах сайта. Например, в нашем примере достаточно выделить в ядро ресурсы A и B, чтобы получить преимущество:

P1 — тратим время на загрузку (A + B) и C

P2 — тратим время на загрузку D

P3 — тратим время на загрузку (E + F)

Вдумчивый читатель сейчас возмутится и спросит: «А что, если ядра нет? Или ядро получается слишком маленьким?». Ответ: это легко решается вручную выделением 2-3 независимых групп со своими собственными ядрами. При желании задачу разбиения можно формализовать и получить точное машинное решение — но это обычно не нужно; руководствуясь простейшим правилом — чем больше ядро, тем лучше, — можно добиться вполне приличного результата.<p>Реализация на PHP</p>

После разделения JavaScript- и CSS-кода по файлам для поддержания модульной структуры можно в контроллере создать список файлов, которые надо присоединить к данному документу (вместо того чтобы прописывать это вручную в шаблоне отображения). Но теперь надо сделать так, чтобы до показа шаблона вызывалась функция кэширования, которая проходилась бы по списку, проверяла из него локальные файлы на время изменения, объединяла в один файл и создавала или перезаписывала gz-файл с именем, сформированным из md5-хэша имен входящих файлов.

В качестве рабочего примера можно привести следующую функцию:

function cache_js(){

$arrNewJS=array();

$strHash='';

$strGzipContent='';

$intLastModified=0;

// проходимся по списку файлов

foreach ((array)$this->scripts as $file){

if (substr($file,0,5)=='http:') continue;

if ($file[0]=='/') $strFilename=sys_root.$file;

else $strFilename=sys_root.'app/front/view/'.$file;

$strHash.=$file;

// читаем содержимое в одну строку

$strGzipContent.=file_get_contents($strFilename);

Перейти на страницу:

Похожие книги