Почему мой 301 Redirect занимает так много времени? - PullRequest
27 голосов
/ 19 декабря 2010

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

После этого страница загружается в мгновение ока молнии!Что за пустая трата времени ты бы не сказал?Что сервер делает все это время?После тщательного изучения моя лучшая догадка: ЕГО ДЕЛАЕТ ПРАЧЕЧНУЮ !

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

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

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

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

screenshot

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

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

Ответы [ 3 ]

7 голосов
/ 19 декабря 2010

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

Сначала я должен указать, что PHP не будет сбрасывать все свои собственные заголовки, пока вы не начнете выводить вещи (или, если директива output_buffering (?) Установлена ​​в 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);

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

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

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

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

Я добавлю больше вещей, как только подумаю.

2 голосов
/ 19 декабря 2010

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

Обновление

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

2 голосов
/ 19 декабря 2010

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

Вы можете сделать переадресацию в .htaccess.

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

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

Обновление

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

...