Кэшируется, PHP генерирует Миниатюры загружаются медленно

179

Вопрос Часть A ▉ (100 наград, награжден)
Главный вопрос заключался в том, как сделать этот сайт более быстрым. Сначала нам нужно было прочитать эти водопады. Спасибо всем за ваши предложения по анализу показаний водопада. Из приведенных здесь графиков различных водопадов видно главное узкое место: миниатюры, генерируемые PHP. Безрецептурная загрузка jquery из CDN по совету Дэвида получила мою награду, хотя в целом мой сайт был только на 3% быстрее, и при этом не отвечал основным узким местам сайта. Время для прояснения моего вопроса и еще одной награды:

Вопрос, часть B ▉ (100 наград, награжден).
Теперь новое внимание было уделено решению проблемы, которую имели 6 изображений jpg, которые вызывают большую часть задержки загрузки. Эти 6 изображений представляют собой миниатюры, сгенерированные PHP, крошечные и всего 3 ~ 5 КБ, но загружаются относительно очень медленно. Обратите внимание на « время первого байта » на различных графиках. Проблема осталась нерешенной, но награда досталась Джеймсу, который исправил ошибку заголовка, которую RedBot подчеркнул : «Условный запрос If-Modified-Since вернул весь контент без изменений». ,

Вопрос Часть C my (моя последняя награда: 250 баллов)
К сожалению, даже после того, как была исправлена ​​даже ошибка заголовка REdbot.org, задержка, вызванная сгенерированными PHP изображениями, осталась нетронутой. О чем думают эти крошечные миниатюрные миниатюры размером 3 ~ 5Кб? Вся эта информация заголовка может послать ракету на Луну и обратно. Любые предложения по поводу этого узкого места очень ценятся и рассматриваются как возможный ответ, так как я застрял в этой узкой проблеме уже семь месяцев. Заранее спасибо

[Некоторая справочная информация на моем сайте: CSS вверху. JS внизу (JQuery, пользовательский интерфейс JQuery, купил движки меню awm / menu.js, движок tabs js, video swfobject.js). Черные линии на втором изображении показывают, что следует загружать. Злой робот мой питомец "ZAM". Он безвреден и часто счастливее.]


Загрузить Водопад: Хронологический | http://webpagetest.org введите описание изображения здесь


Параллельные домены сгруппированы | http://webpagetest.org введите описание изображения здесь


Сайт-Перф Водопад | http://site-perf.com введите описание изображения здесь


Pingdom Инструменты Водопад | http://tools.pingdom.com

введите описание изображения здесь


GTmetrix Водопад | http://gtmetrix.com

введите описание изображения здесь


Сэм
источник
11
Я думаю, что большинство браузеров устанавливают только 20 соединений одновременно, поэтому после 20 первое должно завершиться до следующего запуска, отсюда и замедление после 20
1
Я думаю, что вы забыли отредактировать первый экземпляр вашего домена. По крайней мере, вы получили остальные из них, хотя: D
тридцатое
2
Разве вы не можете объединить некоторые из этих изображений в спрайты?
Марсель Корпель
1
@Dagon, учтите, что HTTP 1.1 RFC запрашивает ( SHOULD), чтобы клиенты HTTP 1.1 использовали не более 2 соединений с серверами HTTP 1.1; HTTP 1.0, конечно, гораздо более открыт.
Сарнольд
1
Браузеры @Dagon также будут устанавливать только 2 одновременных соединения с любым доменом.
Эндофаг

Ответы:

61

Во-первых, использование этих нескольких доменов требует нескольких поисков DNS. Лучше было бы объединить многие из этих изображений в спрайт, а не распространять запросы.

Во-вторых, когда я загружаю вашу страницу, я вижу большую часть блокировок (~ 1.25 с) на all.js. Я вижу, что начинается с (старая версия) jQuery. Вы должны ссылаться на это из Google CDN, чтобы не только уменьшить время загрузки , но и потенциально полностью избежать HTTP-запроса .

В частности, на самые последние библиотеки пользовательского интерфейса jQuery и jQuery можно ссылаться по этим URL-адресам (см. Этот пост, если вам интересно, почему я пропустил http:):

//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js

//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js

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

Оптимизировав хостинг jQuery, вы также должны объединить awmlib2.jsи tooltiplib.jsв один файл.

Если вы решите эти вопросы, вы должны увидеть значительное улучшение.

Дейв Уорд
источник
1
Отличный комментарий, Дэйв! старый 1.3 JQuery был намного меньше, поэтому я подумал, что пока он работает, он может быть быстрее. Но мне нравятся ваши рекомендации: какую из ссылок CDN Google вы предлагаете мне использовать в качестве моей Jqyuery? Могу ли я использовать JQ UI Javascript таким же образом? +1 большое спасибо
Сэм
2
Я определенно рекомендую использовать последнюю версию jQuery (1.4.4 в настоящее время). При минимизации и сжатии разница между ними составляет всего несколько байтов. Я обновил ответ парой ссылок на последние версии jQuery и jQuery UI в Google CDN, которые я бы рекомендовал использовать.
Дэйв Уорд
1
Хороший совет со спрайтом, который должен уменьшить количество открытых соединений с сервером
JamesHalsall
в настоящее время работаем над сокращением открытых соединений (с 40 или 30 до 30 ... окончательный толчок является наиболее сложным, поскольку некоторые изображения перекрашивают фон и не могут перейти в спрайт (или ???)
Сэм
Оценка скорости обновления страницы: (96%) Низкая оценка: (90%) ... и все же эскизы такие же медленные, как и раньше!
Сэм
17

У меня была аналогичная проблема , несколько дней назад и я нашел head.js . Это плагин Javascript, который позволяет загружать все файлы JS paralell. Надеюсь, это поможет.

000
источник
Невероятно! Как я мог не заметить это? +1 Сейчас я собираюсь проверить это. Пахнет как плодотворная ночь. Спасибо Шаттенбаум!
Сэм
1
Могу ли я спросить, являетесь ли вы Schattenbaum от schattenbaum.net?
Пекка
12

Я далеко не эксперт, но ...

В связи с этим: «Условный запрос If-Modified-Since вернул весь контент без изменений». и мои комментарии.

Код, используемый для генерации миниатюр, должен проверять следующее:

  1. Есть ли кешированная версия миниатюры.
  2. Является ли кэшированная версия более новой, чем исходное изображение.

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

  1. Есть ли заголовок HTTP_IF_MODIFIED_SINCE?
  2. Последнее измененное время в кэшированной версии совпадает с HTTP_IF_MODIFIED_SINCE

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

Если оба они верны, то должен быть возвращен статус 304 http. Я не уверен, требуется ли это, но я также лично возвращаю заголовки Cache-Control, Expires и Last-Modified вместе с 304.

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

Изменить: я не заметил ваше добавление к вашему сообщению.

session_cache_limiter('public');
header("Content-type: " . $this->_mime);
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 2419200) . " GMT");
// I'm sure Last-Modified should be a static value. not dynamic as you have it here.
header("Last-Modified: " . gmdate("D, d M Y H:i:s",time() - 404800000) . " GMT");

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

Я думаю, вам нужно что-то вроде этого:

$date = 'D, d M Y H:i:s T'; // DATE_RFC850
$modified = filemtime($filename);
$expires = strtotime('1 year'); // 1 Year

header(sprintf('Cache-Control: %s, max-age=%s', 'public', $expires - time()));
header(sprintf('Expires: %s', date($date, $expires)));
header(sprintf('Last-Modified: %s', date($date, $modified)));
header(sprintf('Content-Type: %s', $mime));

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $modified) {
        header('HTTP/1.1 304 Not Modified', true, 304);
        // Should have been an exit not a return. After sending the not modified http
        // code, the script should end and return no content.
        exit();
    }
}
// Render image data
Джеймс
источник
Джеймс, ты прибил суть проблемы после того, как отредактировал в своем ответе! If Modified Sinceвопрос , кажется, работает сейчас Тем не менее, длинные заголовки / время ожидания для крошечных больших пальцев еще не решены ...
Сэм,
@James PS REdbot.org говорит, что ваш заголовок Expires имеет неверное значение. Я думаю, что это должно быть GMT, а не CET?
Сэм
@Sam Извините, мой сервер находится в Великобритании, поэтому он автоматически генерирует даты по Гринвичу. Просто используйте функцию PHP gmdate вместо даты. Это должно привести к дате GMT ​​относительно вашего времени сервера.
Джеймс
1
@ Сам, Ваше время ожидания - это время выполнения скрипта. Либо требуется много времени, чтобы пройти через ваш код до того момента, когда вы отправляете свои заголовки, либо вы не выходите после того, как отправили свои заголовки.
Джеймс
@ Джеймс, я вижу ... Но кроме этого генератора миниатюр php, есть много других одинаково длинных скриптов, которые делают различные другие вещи (переводы, загрузка меню и т. Д.) Все за долю времени ... ОНИ Кажется, что это не является узким местом вообще ... Это значит, что проблема направлена ​​ТОЛЬКО на генератор миниатюр php?
Сэм
6

Вау, сложно объяснить что-либо с помощью этого изображения ... Но здесь некоторые попытки:

  • файлы 33-36 загружаются так поздно, потому что они динамически загружаются в SWF, и SWF (25) загружается сначала полностью, прежде чем загружает какой-либо дополнительный контент
  • файлы 20 и 21 могут быть (я не знаю, потому что я не знаю ваш код) библиотеки, которые загружаются all.js (11), но для выполнения 11, он ждет всю страницу (и ресурсы) загрузить (вы должны изменить это на domready)
  • файлы 22-32 загружаются этими двумя библиотеками, опять же после того, как они полностью загружены
совать
источник
Интересный момент. Я предполагаю, что ничего нет вокруг SWF ... Как я могу изменить то, что domready? У меня есть догадка, что ты имеешь в виду. Это о том, когда javascript готов и рассказывает о документе, готовом тот или иной? следует ли заменить этот документ на dom.ready?
Сэм
@Sam, если вы используете кэширование на стороне клиента (и вы должны это делать), вы можете загрузить ресурсы, используемые swf в js или hidden divs на своей странице, чтобы, когда swf запрашивал их, они уже были на клиенте.
Эндофаг
4

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

Это будет означать, что либо веб-сайт .ch плохо размещен, либо у вашего интернет-провайдера нет хорошего пути к ним.

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

Кстати , есть этот крутой инструмент cuzillion, который может помочь вам разобраться с вещами в зависимости от того, какой порядок загрузки ресурсов у вас есть.

Джером ВАГНЕР
источник
4

Попробуйте запустить тесты Y! Slow и Page Speed ​​на своем сайте / странице и следуйте инструкциям, чтобы устранить возможные узкие места в производительности. Вы должны получить огромный прирост производительности, как только наберете больше очков в Y! Slow или Page Speed.

Эти тесты подскажут вам, что не так и что нужно изменить.

Ливингстон Самуэль
источник
Спасибо! баллы: 92 на Page Speed ​​и 93 на Ylow. Чего не хватает: KEEP ALIVE = выключен и не использует CDN.
Сэм
ОБНОВЛЕНИЕ: 96 и 90 соответственно в настоящее время
Сэм
4

То есть ваш скрипт PHP генерирует миниатюры при каждой загрузке страницы? Во-первых, если изображения, которые обрабатываются с помощью большого пальца, меняются не так часто, не могли бы вы настроить кеш так, чтобы их не нужно было анализировать при каждой загрузке страницы? Во-вторых, использует ли ваш PHP-скрипт что-то вроде imagecopyresampled()создания миниатюр? Это нетривиальный пример, и PHP-скрипт не будет ничего возвращать, пока не прекратит работу. Использование imagecopymerged()вместо этого снизит качество изображения, но ускорит процесс. И сколько вы делаете сокращения? Являются ли эти миниатюры 5% размером исходного изображения или 50%? Большой размер исходного изображения, вероятно, приводит к замедлению, поскольку PHP-скрипт должен получить исходное изображение в памяти, прежде чем он сможет уменьшить его и вывести уменьшенный эскиз.

MidnightLightning
источник
Спасибо MidnightLightning! Есть папка кеша, в которой создаются и повторно используются эскизы JPG, хотя у меня есть ощущение, что проблема заключается в том, что купленный мной скрипт (и, похоже, отлично работает для других)
Sam
2
Если миниатюры кэшируются, убедитесь, что сценарий, который извлекает их из кэша, использует, readfile()а не file_get_contents()сопровождается эхом, который ожидает вывода чего-либо, пока весь файл не будет перемещен в память сценария PHP.
MidnightLightning
Еще лучше - если файлы кэшируются, генерируйте HTML так, чтобы напрямую извлекать кэшированное изображение с диска без использования PHP. Это то, что я делаю в своих сценариях для videodb.net
andig
«Там есть папка кеша, где ...» и как быстро они разыменовываются? Ваш URL указывает непосредственно на кэшированный файл или скрипт PHP? Вы перенаправляете или используете readfile ()? Содержит ли тот же PHP-скрипт код генерации миниатюр - или вы откладываете загрузку большей части кода с помощью include / erquire?
Symcbean
4

Я нашел URL вашего сайта и проверил отдельный файл jpg с домашней страницы. Хотя время загрузки сейчас разумное (161 мс), оно ожидает 126 мс, что слишком много.

Все ваши последние измененные заголовки установлены в субботу, 01 января 2011 г., 12:00:00 по Гринвичу, которая выглядит слишком «круглой» для реальной даты генерации ;-)

Поскольку Cache-control "public, max-age = 14515200", произвольные последние измененные заголовки могут вызвать проблемы через 168 дней.

Во всяком случае, это не настоящая причина задержек.

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

Вы можете установить xdebug чтобы профилировать скрипт и увидеть узкие места.

Может быть, все это использует фреймворк или подключается к какой-либо базе данных даром. Я видел очень медленный mysql_connect () на некоторых серверах, в основном потому, что они подключались с использованием TCP, а не сокетов, иногда с некоторыми проблемами DNS.

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

капсула
источник
Спасибо за ваш детектив и место для подсказки капсулы! Перво-наперво: нет базы данных. Ваши выводы совпадают с моими: его ждет 90% времени? Сумасшедшие маленькие пальцы. Интересные мысли о последних измененных заголовках, потому что, согласно сообщению Джеймса, мне пришлось установить для этих последних измененных заголовков значение STATIC (фиксированное), а не динамическое / всегда меняющееся время, установленное генераторами php gmdate. Или, может быть, вы имеете в виду что-то еще здесь? (Номинация за награду)
Сэм
1
Чтобы быть идеальным, он должен отражать реальную дату генерации, например, путем получения filemtime () из кэшированного эскиза. Что было бы интересно проверить, так это получить доступ к пустому файлу PHP или файлу PHP, просто повторяющему «тест», и посмотреть, сколько времени вы ожидаете от этого. Возможно, весь сервер работает медленно и влияет на каждый скрипт PHP, что бы он ни делал.
капсула
1
Я также вижу относительно длительную задержку для чисто статических файлов (например, изображений, связанных с большими пальцами), например, 36 мс. На одном из серверов, которые я администрирую (это не чудовище ... двухъядерный с 2 ​​ГБ RAL), я получаю почти половину этого, как 20 мс для статических файлов.
Капсула
Интересно ... 1. Какое программное обеспечение / онлайн-инструмент вы используете для измерения? 2. Являются ли ваши более быстрые измерения за 20 мс последовательными (сколько ± xx%), по вашему мнению, ваши результаты могут отличаться? В моем случае это действительно сильно зависит от того, какой инструмент тестирования я использую. некоторые очень непротиворечивы ( gtmetrix.com ), некоторые действительно различны ( pingdom.com ), и трудно давать времена в XX мс, так как они меняются каждый раз ...
Сэм
Я использую вкладку NET Firebug. 20 мс - самое быстрое время, которое я получаю. Она варьируется от 20 до 28. Конечно, 36 мс, которые я измерял на вашем сервере, были самыми быстрыми.
Капсула
4

Если нет действительно веской причины (обычно ее нет), ваши изображения не должны вызывать интерпретатор PHP.

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

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

Горан Юрич
источник
Спасибо Горану, однако, это не элегантное решение, которого я желаю: я думаю, что в моем случае есть что-то подозрительное, и что обычно PHP-скрипту не нужно много времени, чтобы узнать, нужно ли передать заголовок 304 или испечь В любом случае, спасибо за ваше предложение, поскольку оно направляет проблему с совершенно новой точки зрения! Что само по себе ценно +1
Сэм
3

Исследовать использование PHP данных сеанса. Может быть (просто возможно), генерирующий изображение PHP-скрипт ожидает блокировки данных сеанса, который блокируется главной страницей, выполняющей рендеринг, или другими сценариями рендеринга изображений. Это сделало бы все оптимизации JavaScript / браузера практически неактуальными, так как браузер ждет сервера.

PHP блокирует данные сеанса для каждого выполняемого сценария, с момента начала обработки сеанса, до момента завершения сценария или при вызове session_write_close (). Это эффективно сериализует вещи. Проверьте страницу PHP на сессиях, особенно комментарии, как этот .

Рикардо Пардини
источник
Спасибо за предложение Рикардо! Кажется, Аликс предлагает то же самое, что и вы (верно?). С практической точки зрения, что вы предлагаете мне добавить / удалить из кода, затем снова протестировать графики и затем отчитаться? Очень признателен.
Сэм
1
Да, я так думаю. Я предлагаю вам изменить сценарии создания изображений, чтобы они не зависели от данных $ _SESSION или подобных (возможно, они уже не зависят). Затем используйте session_write_close () как можно скорее , или, что еще лучше, вообще не используйте сессии в этих сценариях. Проверьте php.net/manual/en/function.session-write-close.php
Рикардо Пардини
3

Это просто дикое предположение, так как я не смотрел на ваш код, но я подозреваю, что здесь могут играть роль сессии, следующее из записи PHP Manual session_write_close():

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

Как я уже сказал, я не знаю, что делает ваш код, но эти графики кажутся странно подозрительными. У меня была похожая проблема, когда я закодировал функцию обработки файлов из нескольких частей, и у меня была та же проблема. При обслуживании большого файла я не мог заставить работать многокомпонентную функциональность, и не мог открыть другую страницу, пока загрузка не была завершена. Звонок session_write_close()исправил обе мои проблемы.

Аликс Аксель
источник
Спасибо Аликс за ваше предложение. Вопрос: exit();функция в таких же строках, как и session_write_close();? в настоящее время автор исходного кода исследует эту проблему, но, похоже, он тоже немного не в курсе, поскольку его щедрое обновление кода с улучшенной обработкой If-Modified-Since, похоже, имеет те же задержки (новый водопад) Графики производили те же графики, хотя реальные результаты выглядели / чувствовались быстрее загрузки! Это очень странная проблема ...
Сэм
1
@Sam: Я не могу дать вам никаких источников прямо сейчас, но я полагаю, что exit () сначала вызывает любые деструкторы и / или функции, зарегистрированные для отключения, и только после этого сессия закрывается. В любом случае, держу пари, что ваша проблема, вероятно, лежит перед вызовом exit (). Смотрите также: stackoverflow.com/questions/1674314/…
Аликс Аксель
2

Вы пытались заменить созданные php thumnails обычными изображениями, чтобы увидеть, есть ли разница? Проблема может быть вокруг - ошибка в вашем php-коде, приводящая к регенерации миниатюры при каждом вызове сервера - задержка в вашем коде (sleep ()?), Связанная с проблемой синхронизации - проблема жесткого диска, приводящая к очень плохому состоянию гонки так как все миниатюры загружаются / генерируются одновременно.

Джером ВАГНЕР
источник
Кое-что, что я когда-то думал, давая попытку +1 для чтения моих мыслей и раскрытия первого решения, которое я уже сделал. Я надеялся, что нормальные изображения также будут загружаться медленно, так что это может быть скорость загрузки со скоростью или что-то физически ограничивающее, но вместо этого я обнаружил, что обычные статические изображения дампа (я сохранял сгенерированные большие пальцы и загружал как статические), они загружали ЧРЕЗВЫЧАЙНО быстро. Так что его нужно делать с тем, что генератор миниатюр php!
Сэм
2

Я думаю, что вместо того, чтобы использовать этот скрипт-генератор миниатюр, вы должны попробовать TinySRC для быстрого и быстрого создания миниатюр в облаке. Он имеет очень простой и удобный API, вы можете использовать как: -

http://i.tinysrc.mobi/ [высота] / [ширина] /http://domain.tld/path_to_img.jpg

[ширина] (необязательно): - это ширина в пикселях (которая переопределяет адаптивный или семейный размер). Если префикс «-» или «x», он будет вычитаться или уменьшаться до определенного процента от определенного размера.

[рост] (необязательно): - это высота в пикселях, если ширина также присутствует. Он также отменяет адаптивный или семейный размер и может иметь префикс «-» или «x».

Вы можете проверить сводку API здесь


Вопросы-Ответы

Сколько стоит tinySrc?

Ничего.

Когда я могу начать использовать tinySrc?

Сейчас.

Насколько надежен сервис?

Мы не даем никаких гарантий относительно сервиса tinySrc. Однако он работает в крупной распределенной облачной инфраструктуре , поэтому обеспечивает высокую доступность по всему миру. Этого должно быть достаточно для всех ваших потребностей.

Как быстро это?

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


Удачи. Просто предложение, так как вы не показываете нам код: p

Салман фон Аббас
источник
2

Поскольку некоторые браузеры загружают только 2 параллельных загрузки для каждого домена, не могли бы вы добавить дополнительные домены для разделения запросов на два-три разных имени хоста. например, 1.imagecdn.com 2.imagecdn.com

Том
источник
+1 за ваше предложение: спасибо, но если вы присмотритесь к моим (допускается: очень хаотичные рисунки), вы увидите, что некоторые предметы происходят из ....... а некоторые из ........ ком .......... де НО, возможно, это не делает трюк так, как ваше предложение? (Я вижу, вы предлагаете субдомены, а не просто разные домены.)
Сэм
1

Прежде всего, вам нужно обрабатывать If-Modified-Sinceзапросы и тому подобное, как сказал Джеймс. Эта ошибка гласит: «Когда я спрашиваю ваш сервер, изменено ли это изображение с прошлого раза, оно отправляет все изображение вместо простого да / нет».

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

  1. Рассматривали ли вы его профилирование? Это может иметь некоторые проблемы.
  2. В сочетании с вышеуказанной проблемой ваш сценарий может выполняться намного больше, чем необходимо. В идеале, он должен генерировать большие пальцы, только если исходное изображение было изменено, и отправлять кэшированные большие пальцы для каждого другого запроса. Вы проверили, что скрипт генерирует изображения без необходимости (например, для каждого запроса)?

Генерировать правильные заголовки через приложение немного сложно, плюс они могут быть перезаписаны сервером. И вы подвержены злоупотреблениям, так как любой, кто отправляет заголовки запросов без кэширования, заставит ваш генератор миниатюр работать непрерывно (и поднимать нагрузки). Поэтому, если возможно, попытайтесь сохранить сгенерированные превью, вызывайте сохраненные изображения прямо со своих страниц и управляйте заголовками .htaccess. В этом случае вам даже не понадобится ничего, .htaccessесли ваш сервер настроен правильно.

Кроме этого, вы можете применить некоторые из ярких идей оптимизации из частей производительности этого общего вопроса о том, как правильно делать сайты , например, разделить ваши ресурсы на поддоменах без файлов cookie и т. Д. Но, во всяком случае, изображение 3k загрузка не должна занимать секунды, это очевидно по сравнению с другими элементами на графиках. Вы должны попытаться определить проблему до оптимизации.

Халил Озгюр
источник
-1: Ответ на условный запрос с «Не изменено» и без пересмотренного срока действия замедлит ваш сайт в 99,9% случаев (КСТАТИ, AFAIK, нет способа заставить Apache выдать пересмотренную информацию о кэшировании с ответом 304)
symcbean
И какое это имеет отношение к моему ответу?
Халил Озгюр
1

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

nefo_x
источник
Спасибо! Однако после некоторых исследований выяснилось, что настройка поддоменов для статических файлов cookie сервера делает сайт быстрее, когда имеется много изображений, и требует дополнительных затрат. В моем случае я готов поспорить, что 6 изображений не будут загружаться быстрее, чем затраты на дополнительный / дополнительный домен. Правильно?
Сэм
1
NGinx поддерживает системный вызов sendfile, который может отправлять файлы прямо с жесткого диска. см. следующий документ wiki.nginx.org/HttpCoreModule по директивам 'sendfile', 'aio'. Этот веб-сервер обслуживает статические файлы, такие как изображения, намного быстрее, чем Apache.
nefo_x
интересно ... я не знал, что может быть что-то лучше, чем Apache. Кстати, что вы подразумеваете под straight from hdd. вы имеете в виду вместо этого straight from DDR3 RAM/ straight from Solid State Diskя знаю, что жесткие диски, в отличие от оперативной памяти DDR3 или твердотельных дисков, имеют очень медленное время доступа. Но я чувствую, что это не узкое место здесь ...
Сэм
1
Дело в том, что nginx не буферизует вывод статических данных, как это делает apache.
nefo_x
1

Что касается отложенных миниатюр, попробуйте сделать вызов flush () сразу после последнего вызова header () в вашем скрипте генерации миниатюр. После этого восстановите график водопадов и посмотрите, есть ли задержка на теле вместо заголовков. Если это так, вам нужно внимательно взглянуть на логику, которая генерирует и / или выводит данные изображения.

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

AR Younce
источник
+1 Увлекательная догадка, попробую сейчас! сообщит, когда у меня будет течь новый водопад ...
Сэм
К сожалению, после добавления flush();сразу после заголовков изменений, похоже, нет вообще! Что бы это могло значить?
Сэм
Точно сказать не могу. Есть ли способ, которым вы можете связать нас с PHP-скриптом? Я знаю, что вы заплатили за это, но невероятно сложно сказать, что может быть причиной поведения, не зная, что оно делает.
AR Younce
Упоминаются ли эскизы в CSS или в тегах <img>?
AR Younce
Что вы подразумеваете под ссылками в css? они находятся в теле html и следующим образом: <img src="thumbprocessor.php?src=/folder/image.jpg&w=100&h=200" id="thumbnail"/>
Сэм
1

Большая часть медленной проблемы - ваш TTFB (время до первого байта) слишком высокий. С этим трудно справиться, не разбираясь в файлах конфигурации вашего сервера, коде и базовом оборудовании, но я вижу, что он свирепствует при каждом запросе. У вас слишком много зеленых полос (плохо) и очень маленьких синих полос (хорошо). Возможно, вы захотите немного прекратить оптимизацию интерфейса, так как я считаю, что вы многое сделали в этой области. Несмотря на то, что « 80% -90% времени отклика конечного пользователя тратится на внешний интерфейс », я полагаю, что ваше происходит в бэкэнде.

TTFB - это бэкэнд, сервер, предварительная обработка перед выводом и квитирование.

Время выполнения вашего кода, чтобы найти медленные вещи, такие как медленные запросы к базе данных, время входа и выхода из функций / методов, чтобы найти медленные функции. Если вы используете php, попробуйте Firephp . Иногда это один или два медленных запроса, выполняемых во время запуска или инициализации, таких как получение информации о сеансе или проверка аутентификации, а что нет. Оптимизация запросов может привести к хорошим результатам. Иногда код запускается с использованием php prepend или spl автозагрузки, поэтому они запускаются на всем. В других случаях это может быть неправильно настроенный Apache Conf и настройка, которая спасает день.

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

Вы можете попробовать DNS Prefetching для борьбы со многими доменами и ресурсами, http://html5boilerplate.com/docs/DNS-Prefetching/

Является ли ваш собственный сервер хорошим / достойным сервером? Иногда лучший сервер может решить множество проблем. Я болею за менталитет « аппаратное обеспечение дешевое, программисты - дорогое », если у вас есть возможность и деньги обновить сервер. И / или использовать CDN , как maxcdn или CloudFlare или аналогичный.

Удачи!

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

Энтони Хатзопулос
источник
Дорогой Энтони, большое спасибо за это глубокое знание. Я согласен, что иногда узким местом является аппаратное обеспечение, и это менее очевидно для измерения, особенно когда хостинговая компания размещает серверную часть в среде общего хостинга. Я думаю, что cloudflare - хороший вариант для тестирования в сочетании с оптимизацией конфигурации apache. Приветствую!
Сэм
-1

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

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

НИКОГДА НЕ ПОТОКА ИЗОБРАЖЕНИЙ С PHP. Это замедлит работу вашего сервера, независимо от способа его использования.

Поместите их в доступную папку со значимым URI. Затем позвоните им напрямую с их реальным URI. Если вам нужно генерировать на лету, вы должны поместить .htaccess в каталог images, который перенаправляет на php-скрипт генератора, только если изображение запроса отсутствует. (это называется стратегией кэширования по запросу).

Это исправит сессию php, прокси-браузер, кеширование, ETAGS, что угодно одновременно.

WP-Supercache использует эту стратегию, если она правильно настроена.

Я написал это некоторое время назад ( http://code.google.com/p/cache-on-request/source/detail?r=8 ), последние версии не работают, но я думаю, что 8 или меньше должны работать, и вы можете возьмите .htaccess в качестве примера просто для проверки (хотя есть и лучшие способы настроить .htaccess, чем я привык).

Я описал эту стратегию в этом посте в блоге ( http://www.stefanoforenza.com/need-for-cache/ ). Это, вероятно, плохо написано, но это может помочь прояснить ситуацию.

Дополнительная информация: http://meta.wikimedia.org/wiki/404_handler_caching

tacone
источник
Имейте в виду, ErrorDocument - не самая лучшая вещь, которую вы можете сделать, так как она генерирует записи в журнале ошибок apache, перенаправление -f было бы лучше.
Таконе
Спасибо за ваш вклад таконе. Вы говорите, что независимо от того, насколько хорош будет скрипт php, он будет замедлять работу сервера, или, как вы сказали в своем посте: «Он убьет ваш сервер, несмотря ни на что».
Сэм
это замедлит работу сервера независимо от того, насколько хорош скрипт. Для каждого изображения сервер должен будет загрузить php и сделать так, чтобы оно передавало изображение байт за байтом. Пусть apache сделает работу, даже не пройдя мимо интерпретатора php. Как побочный результат, многие другие возможные ошибки будут автоматически исключены, такие как сеансы, длина контента, кэширование, mime / type и т. Д. Когда производительность критична, вы даже не должны загружать php (но во время генерации).
Таконе
Проголосовать против, не могли бы вы объяснить, почему?
Таконе