Обслуживание php как css/js: достаточно ли оно достаточно? Какие недостатки есть?

Недавно я начал заниматься оптимизацией производительности и времени загрузки на стороне клиента, сжимаю css/js, gzipping, обращая внимание на YSlow и т.д.

Мне интересно, пытаясь достичь всех этих микро-оптимизаций, каковы плюсы и минусы работы php файлов как css или javascript?

Я не совсем уверен, где узкое место, если оно есть. Я бы предположил, что между идентичным css и php файлом "чистый" css файл будет немного быстрее просто потому, что ему не нужно анализировать PHP-код. Однако в php файле вы можете больше контролировать заголовки, которые могут быть более важными (?).

В настоящее время я выполняю проверку filemtime() файла триггера, а некоторые php voodoo записывают один сжатый css файл из него в сочетании с несколькими другими файлами в определенной группе. Это создает файл типа css/groupname/301469778.css, который шаблон php улавливает и обновляет теги html новым именем файла. Это было похоже на самый безопасный метод, но мне не очень нравится, как кеш сервера заполняется ненужными файлами css после нескольких изменений. Я также не делаю этого для небольших "хелперных" css файлов, которые загружаются только для определенных страниц.

  • Если 99% моего вывода генерируется php в любом случае, какой вред (если есть), используя php для прямого вывода содержимого css/js? (при условии отсутствия ошибок php)
  • Если вы используете php, рекомендуется ли mod_rewrite использовать файлы для расширения css/js для каких-либо случаев кражи неверного истолкования браузера? Не может больно? Не нужно?
  • Существуют ли какие-либо отдельные рекомендации/методы для css и javascript? Я бы предположил, что они будут равны.
  • Что происходит быстрее: один файл css с несколькими @imports или php файл с несколькими вызовами readfile()?
  • Какие еще способы использования php влияют на скорость?
  • Как только файл кэшируется в браузере, это уже имеет значение?

Я бы предпочел использовать php с .htaccess, потому что он намного проще, но в конце я буду использовать любой метод.

Ответ 1

ok, так вот ваши прямые ответы:

  • никакого вреда вообще, пока ваш код в порядке. Браузер не заметит никакой разницы.
  • нет необходимости в mod_rewrite. браузеру обычно не нравится URL (и часто даже не о типе MIME).
  • Файлы CSS обычно меньше и часто одного файла достаточно, поэтому нет необходимости комбинировать. Имейте в виду, что объединение файлов из разных каталогов влияет на изображения, указанные в CSS, поскольку они остаются относительно URL-адреса CSS.
  • Определенно readfile() будет быстрее, так как @import требует нескольких HTTP-запросов и вы хотите уменьшить как можно больше
  • при сравнении одного HTTP-запроса PHP может быть немного медленнее. Но вы теряете возможность комбинировать файлы, если вы не делаете это в автономном режиме.
  • нет, но кеши браузера ненадежны, а неправильная конфигурация веб-сервера может привести к излишнему повторению URL-адреса браузера.

Невозможно дать вам более конкретный ответ, потому что он зависит от лота от деталей вашего проекта.

Ответ 2

Мы разрабатываем действительно большое веб-приложение DHTML/AJAX с примерно 2 МБ кода JavaScript, и они по-прежнему быстро загружаются с некоторыми оптимизациями:

  • попытайтесь уменьшить количество включенных URL Script. Мы используем простой PHP скрипт, который загружает кучу .js файлов и отправляет их за один проход в браузер (все конкатенированные). Это быстрее загрузит вашу страницу лот, когда у вас много файлов .js, так как накладные расходы на настройку HTTP-соединения обычно намного выше, чем фактическая передача содержимого. Обратите внимание, что браузеру необходимо синхронизировать файлы JS.

  • быть дружественным к кэшу. Наша HTML-страница также создается через PHP, а URL-адрес скриптов содержит хэш, зависящий от времени изменения файла. PHP Script выше, который объединяет файлы .js, затем проверяет заголовки кеша HTTP и устанавливает длительное время истечения, чтобы браузеру даже не приходилось загружать внешние скрипты во второй раз, когда пользователь посещает страницу.

  • GZIP сжимает скрипты. Это уменьшит ваш код примерно на 90%. Нам даже не нужно минимизировать код (что облегчает отладку).

Итак, да, использование PHP для отправки файлов CSS/JS может значительно увеличить время загрузки вашей страницы - особенно для больших страниц.

EDIT: этот код можно использовать для объединения файлов:

function combine_files($list, $mime) {

  if (!is_array($list))
    throw new Exception("Invalid list parameter");

  ob_start();

  $lastmod = filemtime(__FILE__);

  foreach ($list as $fname) {
    $fm = @filemtime($fname);

    if ($fm === false) {
      $msg = $_SERVER["SCRIPT_NAME"].": Failed to load file '$fname'";
      if ($mime == "application/x-javascript") {
        echo 'alert("'.addcslashes($msg, "\0..\37\"\\").'");';
        exit(1);
      } else {
        die("*** ERROR: $msg");
      }        
    }

    if ($fm > $lastmod)
      $lastmod = $fm;
  }

  //--

  $if_modified_since = preg_replace('/;.*$/', '', 
    $_SERVER["HTTP_IF_MODIFIED_SINCE"]);


  $gmdate_mod = gmdate('D, d M Y H:i:s', $lastmod) . ' GMT';
  $etag = '"'.md5($gmdate_mod).'"';

  if (headers_sent())
    die("ABORTING - headers already sent");

    if (($if_modified_since == $gmdate_mod) or 
    ($etag == $_SERVER["HTTP_IF_NONE_MATCH"])) {
        if (php_sapi_name()=='CGI') {
        Header("Status: 304 Not Modified");
      } else {
        Header("HTTP/1.0 304 Not Modified");
      }
    exit();
    }
    header("Last-Modified: $gmdate_mod");
    header("ETag: $etag");

    fc_enable_gzip();

    // Cache-Control
    $maxage = 30*24*60*60;   // 30 Tage (Versions-Unterstützung im HTML Code!)

    $expire = gmdate('D, d M Y H:i:s', time() + $maxage) . ' GMT';
    header("Expires: $expire");
    header("Cache-Control: max-age=$maxage, must-revalidate");

  header("Content-Type: $mime");

  echo "/* ".date("r")." */\n";
  foreach ($list as $fname) {
    echo "\n\n/***** $fname *****/\n\n";
    readfile($fname);
  }
}


function files_hash($list, $basedir="") {
  $temp = array();
  $incomplete = false;

  if (!is_array($list))
    $list = array($list);

  if ($basedir!="")
    $basedir="$basedir/";

  foreach ($list as $fname) {
    $t = @filemtime($basedir.$fname);
    if ($t===false)
      $incomplete = true;
    else
      $temp[] = $t;
  }

  if (!count($temp))
    return "ERROR";

  return md5(implode(",",$temp)) . ($incomplete ? "-INCOMPLETE" : "");
}


function fc_compress_output_gzip($output) {
  $compressed = gzencode($output);

  $olen = strlen($output);
  $clen = strlen($compressed);

  if ($olen)
    header("X-Compression-Info: original $olen bytes, gzipped $clen bytes ".
      '('.round(100/$olen*$clen).'%)'); 

  return $compressed;
}
function fc_compress_output_deflate($output) {

  $compressed = gzdeflate($output, 9);

  $olen = strlen($output);
  $clen = strlen($compressed);

  if ($olen)
    header("X-Compression-Info: original $olen bytes, deflated $clen bytes ".
      '('.round(100/$olen*$clen).'%)'); 

  return $compressed;

}

function fc_enable_gzip() {
  if(isset($_SERVER['HTTP_ACCEPT_ENCODING']))
    $AE = $_SERVER['HTTP_ACCEPT_ENCODING'];
   else
    $AE = $_SERVER['HTTP_TE'];
  $support_gzip = !(strpos($AE, 'gzip')===FALSE);
  $support_deflate = !(strpos($AE, 'deflate')===FALSE);
  if($support_gzip && $support_deflate) {
    $support_deflate = $PREFER_DEFLATE;
  }
  if ($support_deflate) {
      header("Content-Encoding: deflate");
      ob_start("fc_compress_output_deflate");
  } else{
    if($support_gzip){
      header("Content-Encoding: gzip");
      ob_start("fc_compress_output_gzip");
    } else{
      ob_start();
    }
  }
}

Используйте files_hash() для создания уникальной строки хеша, которая изменяется всякий раз, когда ваши исходные файлы меняются, и comb_files() для отправки объединенных файлов в браузер. Поэтому при создании кода HTML для тега и comb_files() в PHP Script, который загружается через этот тег, используйте файлы_файлов(). Просто поместите хэш в строку запроса URL.

<script language="JavaScript" src="get_the_code.php?hash=<?=files_hash($list_of_js_files)?>"></script>

Убедитесь, что вы указали один и тот же список $в обоих случаях.

Ответ 3

Вы говорите об обслуживании статических файлов через PHP, там действительно мало смысла делать это, поскольку он всегда будет медленнее, чем Apache, обслуживающий обычный файл. CSS @import будет быстрее, чем PHP readfile(), но лучшая производительность будет достигнута за счет обслуживания одного мини файла CSS, который объединяет все CSS, которые вам нужно использовать.

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

Чтобы избежать много кешированных файлов, вы можете использовать простой протокол имен файлов для вашего мини-CSS. Например, если ваш основной файл CSS, называемый main.css, и он ссылается на reset.css и forms.css через @imports, миниатюрная версия может быть вызвана main.min.css

Когда этот файл регенерируется, он просто заменяет его. Если вы включаете ссылку на этот файл в свой HTML, вы можете отправить запрос на PHP, если файл не существует, объедините и уменьшите файл (через что-то вроде Компрессор YUI) и сохраните его на диск и, следовательно, обслуживайте через обычный HTTP для всех будущих запросов.

Когда вы обновляете свой CSS, просто удаляйте версию main.min.css и он будет автоматически регенерировать.

Ответ 4

Вы можете выполнить предварительную обработку с помощью ANT Build. Извините, сообщение является немецким, но я пробовал translate.google.com, и он отлично работал:-) Таким образом, вы можете использовать пост в качестве учебника для достижения лучшей производительности... Я бы предварительно обработал файлы и сохранил их на диск, как сказал simonrjones. Кэширование и т.д. Должны выполняться выделенными элементами, такими как Apache WebServer, заголовки и браузер.

Ответ 5

В то время как медленнее, одно преимущество/причина, по которой вам, возможно, придется сделать это, - это разместить динамический контент в файлы на сервере, но все же они кажутся js или css с точки зрения клиента.

Как это, например, передача среды с php на javascript:

var environment = <?=getenv('APPLICATION_ENV');?>

// More JS code here ...