Почему мой 301-й редирект занимает так много времени?


В долгом утомительном стремлении ускорить работу моего сайта я понял, что что-то не так с перенаправлением: в настоящее время мой index.php обрабатывает все перенаправления домашней страницы через местоположение заголовка PHP 301 Перенаправление на постоянной основе: website.com >> website.com/en/home и website.de >> website.de/de/home и так далее и тому подобное (около 20 для этого многоязычного веб-сайта) для перенаправления требуется от 200 до 6000 мс. Посмотрите на водопад!

После этого страница загружается в мгновение ока, как молния! Какая пустая трата времени, не так ли? Что сервер делает все это время? После тщательного изучения, моя лучшая догадка такова: ЭТО СТИРКА БЕЛЬЯ!

Я почти отказываюсь от PHP ради этого! Любые и все подсказки к моей загадочной проблеме очень приветствуются +1

А. Приведенные факты: Apache/2.0.54 Fedora, PHP 5.2.9. базы данных нет: просто плоские php-файлы, содержащие около 15 php, которые дополняют мою страницу верхними и нижними колонтитулами). ИЗлоу Класс: 92/100! Хорошая скорость страницы: 93/100! javascript и css максимально объединены. Элементы управления кэшем также кажутся хорошо установленными (что подтверждается оценками). Чего не хватает в этих 7 пунктах из 100: не использовать Keep-Alive (за пределами моего контроля на общем хостинге и не использовать сеть доставки контента. Я могу смириться с этими недостающими 7 очками, но это большой удар по скорости!

Б. Кроме того: недавно мне здесь дали отличную информацию о том, что я должен использовать переписывание URL-адресов через htacces. Точка принято, НО, возможно, здесь есть что-то еще неправильное, что я должен исправить, прежде чем переходить к более сложным для меня синтаксисам регулярных выражений apache.

С. Более быстрый способ: когда я php include на предназначенную домашнюю страницу вместо перенаправления, все загружается быстро, но URL-адрес не переписывается: он находится на website.com на панели браузера, в то время как я хочу, чтобы после включения он стал website.com/en/home . Возможно ли это с помощью PHP? Включить+изменить текущий адрес URL-адреса, тоже?

screenshot

Выводы: вы можете перенаправить с помощью index.php, или с помощью .htaccess. Софар из моих тестов (исходя из приведенных ниже гениальных ответов!СПАСИБО ВСЕМ!) Последнее кажется непревзойденным по скорости: перенаправление намного быстрее, чем перенаправление php! сокращение перенаправления до более короткого, чем первый поиск dns.

Смотрите здесь, как сделать это правильно для многоязычного сайта

Author: Community, 2010-12-19

3 answers

Черт возьми, я ненавижу сталкиваться с такого рода проблемами. Вам нужно исключить некоторые переменные.

Во-первых, я должен отметить, что PHP не будет удалять все свои собственные заголовки, пока вы не начнете выводить данные (или, если директива output_buffering(?) ini установлена в x байт, пока вы не выведете x байт). Таким образом, следующий скрипт не завершит "отправку заголовков" до самого конца:

<?php
header('Content-Type: text/pants');
sleep(6);
header('Ding-Ding: time to put the socks in the dryer');
echo "z"; // headers are sent here

Что произойдет со звонком в en/home, если вы поместите exit; или echo "wheeeee"; exit; в самый верх этот PHP-скрипт? Тогда что произойдет, если вы замените его простым пустым файлом? Если php-скрипт с exit работает медленно, но простой текстовый файл работает быстро, интерпретатор PHP, вероятно, играет в забавных жукеров. Если вы все еще получаете задержку для обоих, вы устранили фактическую генерацию ответа в качестве причины (но я все еще пытаюсь придумать некоторые идеи, если это так).

Кроме того, вы можете подключиться по ssh к серверу? Если да, можете ли вы попробовать создать ту же страницу изнутри сервера? Если ты может без проблем со скоростью, я бы смотрел на сторону клиента. Если вы не можете использовать SSH, вы можете попробовать выполнить запрос с PHP, хотя я действительно не уверен, что это сработает:

<?php
$context = stream_context_create(array(
    'http'=>array(
        // send request headers if you need to
        'header'=>array(
            'Foo: Bar',
            'Bar: Baz',
        ),
    ),
));
$start = microtime(true);
$response = file_get_contents('http://yourserver.com/', null, context);
$end = microtime(true) - $start;
var_dump($end);

// for some bizarre reason, PHP emits this variable into the local scope.
var_dump($http_response_header);

Пробовали ли вы выполнить тот же запрос с других машин или из других мест в мире? Это может подтвердить или опровергнуть, если это только ваша машина.

Еще одна вещь, которую вы можете попробовать, если это генерация ответа, - это выполнить небольшое профилирование взлома на рабочем сервере. Я ненавижу делать это все такое, но иногда ваш код просто отказывается вести себя на рабочем сервере так, как он ведет себя в вашей среде разработки или на промежуточном этапе. Сделайте это со сценарием, который генерирует /en/home:

<?php
// put this at the very top
$rqid = uniqid('', true);
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [START] '.microtime(true).PHP_EOL);
fclose($h);

// do all that other wonderful stuff, like laundry or making a cup of tea

// put this at the very end
$h = fopen(__DIR__.'/crap.log', 'a');
fwrite($h, $rqid.' [END]   '.microtime(true).PHP_EOL.PHP_EOL);
fclose($h);

Выполните несколько запросов к нему, убедитесь, что в "дерьмо.журнал" записываются данные (проверьте разрешения!!), и тогда у вас будут некоторые данные, которые покажут, есть ли в вашем сценарии что-то, что необходимо дополнительно исследовать как причину медлительности.

О, неужели я упомянуть индексы MySQL? Выполняете ли вы какие-либо запросы во время запроса? Вы добавили все нужные индексы в таблицы?

Стивен Сюй поднимает хороший вопрос в комментариях к вашему вопросу - вы уверены, что программа, которую вы используете для создания водопада, дает вам хорошую информацию? Попробуйте установить Firebug, если вы еще этого не сделали, щелкните маленький значок firebug в правом нижнем углу firefox и убедитесь, что панель "Сеть" открыта, затем повторите свой запрос и посмотрите, будет ли водопад соответствует результатам, которые вы видите в используемой вами программе.

Кроме того, я знаю, что это глупое предложение, и я приношу извинения, но я думаю, что это нужно сказать: ваш хост не разрешает ssh и использует только PHP 4? Я бы серьезно подумал о другом хозяине. Это может даже решить эту конкретную проблему.

Я буду добавлять больше материала по мере того, как буду думать об этом.

 7
Author: Shabbyrobe, 2010-12-19 01:38:47

Я думаю, что у Игнасио Васкеса-Абрамса может быть ответ: после вызова функции header() для перенаправления вам нужно вызвать функцию exit(), чтобы остановить выполнение PHP-скрипта. Без этого скрипт будет продолжать выполняться, отправляя вывод в браузер, до конца. Поскольку браузер должен дождаться завершения сценария на стороне сервера, прежде чем выполнять перенаправление, которое может вызвать проблему.

Обновление

Просто прочитайте обновление Алекса, и он, похоже, прав. То /ru/домашняя страница - это место, где указано время.

 2
Author: Jeremy, 2010-12-19 00:30:52

Если заголовки действительно занимают много времени, то ваш JS/CSS/HTML не имеет значения.

Вы можете выполнить пересылку в .htaccess.

RewriteEngine On
RewriteRule ^$ en/home [R=301]

Это, по сути, отправит тот же заголовок, но сначала не вызовет PHP-движок для этого:)

Обновление

При ближайшем рассмотрении мне кажется, что ваша страница en/home загружается дольше.

 2
Author: alex, 2010-12-19 00:31:32