Подтвердить что ты не робот

Улучшение времени загрузки Javascript - Конкатенация против многих + кэш

Мне интересно, какое из следующих действий приведет к повышению производительности для страницы, которая загружает большое количество javascript (jQuery + jQuery UI + различные другие файлы javascript). Я прошел через большинство материалов YSlow и Google Page Speed, но я не стал задаваться вопросом о конкретной детали.

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

Прежде всего, стандартный подход, рекомендованный такими инструментами, как YSlow, заключается в том, чтобы объединить его, сжать и обслуживать в одном файле, загруженном в конце вашей страницы. Этот подход звучит достаточно эффективно, но я думаю, что ключевая часть рассуждений здесь заключается в повышении производительности для пользователей без кэшированных данных.

В моей системе в настоящее время есть что-то вроде этого

  • Все файлы javascript сжаты и загружены в нижней части страницы
  • Все файлы javascript имеют датированные даты истечения срока действия кеша, поэтому в течение длительного времени они останутся (для большинства пользователей)
  • Страницы загружают только файлы javascript, которые им нужны, а не загружают один монолитный файл, большая часть которого не требуется.

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

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

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

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

Конкретные вопросы

  • Если есть много тегов, но все файлы загружаются из локального кеша, а в целом загружается меньше javascript, это будет быстрее, чем один тег, который также загружается из кеша, но содержит все javascript необходимо в любом месте сайта, а не в соответствующем подмножестве?
  • Есть ли другие причины, чтобы предпочесть друг друга?
  • Использует ли подобное отношение к CSS? (В настоящее время я использую гораздо более монолитный подход к CSS)
4b9b3361

Ответ 1

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

Первое, что нужно учитывать, нет win-win формулы, но порог, в котором файл javascript растет до такого размера, что он может (и должен) быть разделен.

GWT использует это, и они называют это кодом DFN (Dead-for-now). Здесь не так много волшебства. Вам просто нужно определить вручную, когда вам понадобится новый кусок кода, и если он понадобится пользователю, просто вызовите этот файл.

Как, когда, где вам понадобится?
Benchmark. У Chrome есть отличный инструмент для бенчмаркинга. Используйте его экстенсивно. Посмотрите, будет ли только небольшой файл javascript значительно улучшить загрузку этой конкретной страницы. Если это все равно, начните DFNing вашего кода.

Кроме того, все это касается восприятия.

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

Отложить javascript!
Все основные библиотеки могут ждать загрузки страницы перед выполнением javascript. Используй это. jQuery выглядит как $(document).ready(function(){ ... }). Он не дожидается разбора кода, но делает синтаксический код, когда он должен. После загрузки страницы перед загрузкой изображения.

Важные вещи, которые необходимо учитывать:

  • Убедитесь, что файлы js кэшируются клиентом (все остальные стоят немного по сравнению с этим)
  • Скомпилируйте свой код с помощью Closure Compiler
  • Дефляция вашего кода; он быстрее, чем Gziping (с обоих концов).

Пример кэширования Apache:

// Set up caching on media files for 1 month
<FilesMatch "\.(gif|jpg|jpeg|png|swf|js|css)$">
    ExpiresDefault A2629744
    Header append Cache-Control "public, proxy-revalidate"
    Header append Vary "Accept-Encoding: *"
</FilesMatch>

Пример дефляции Apache:

// compresses all files for faster transfer
LoadModule deflate_module modules/mod_deflate.so
AddOutputFilterByType DEFLATE text/html text/plain text/xml font/opentype font/truetype font/woff
<FilesMatch "\.(js|css|html|htm|php|xml)$">
   SetOutputFilter DEFLATE
</FilesMatch>

И, наконец, и, возможно, наименее, обслуживайте свой Javascript из домена без файлов cookie.

И чтобы держать ваш вопрос в фокусе, помните, что когда у вас есть код DFN, у вас будет несколько небольших файлов javascript, которые, точно для разделения, не будут иметь уровень сжатия. Closure может дать вам один, Сумма этих частей не равна целому в этом сценарии.

Надеюсь, что это поможет!

Ответ 2

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

Сначала проанализируйте свои журналы, чтобы узнать, действительно ли ваша скорость кеша так хороша, как вы ожидали бы для своей пользовательской базы. Например, если каждая html-страница включает jquery.js, просмотрите журналы в течение дня - сколько запросов было для html-страниц? Сколько для jquery.js? Если уровень кеша хорош, вы должны увидеть гораздо меньше запросов для jquery.js, чем для html-страниц. Вероятно, вы захотите сделать это в течение дня сразу после обновления, а также через несколько недель после обновления, чтобы увидеть, как это влияет на скорость кеша.

Затем добавьте некоторые простые измерения на вашу страницу в JavaScript. Вы сказали, что теги script находятся внизу, поэтому я предполагаю, что это выглядит примерно так?

<html>
<!-- all your HTML content... -->
<script src="jquery.js"></script>
<script src="jquery-ui.js"></script>
<script src="mycode.js"></script>

В этом случае вам нужно время, необходимое для загрузки JS, и пинг сервера следующим образом:

<html>
<!-- all your HTML content... -->

<script>var startTime = new Date().getTime();</script>

<script src="jquery.js"></script>
<script src="jquery-ui.js"></script>
<script src="mycode.js"></script>

<script>
var endTime = new Date().getTime();
var totalTime = endTime - startTime; // In milliseconds
new Image().src = "/time_tracker?script_load=" + totalTime;
</script>

Затем вы можете просмотреть журналы для /time _tracker (или того, что вы хотите назвать), и посмотреть, как долго он забирает людей для загрузки сценариев.

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

Ответ 3

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

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

Что касается вопроса браузера "если дата истечения срока хранения для файла javascript не была достигнута, тогда кешированная версия будет использоваться немедленно, а HTTP-запрос не будет отправлен на сервер вообще", я думаю, что там это запрос HTTP, но с ответом "NOT MODIFIED". Чтобы убедиться, что вы должны проверить все Запросы, сделанные на Веб-сервере (используя один из доступных инструментов). После получения ответа браузер использует немодифицированный ресурс - файл или изображение js или другое.

Удачи вам в B2B.

Ответ 4

Вы пытались закрыть Google? Из того, что я читал об этом, это выглядит довольно многообещающе.

Ответ 5

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

Слияние и минитипирование вашего script не должно быть обременительным процессом. Я пишу свой JavaScript в отдельных файлах, хорошо различимых для чтения для меня, поэтому его легче поддерживать. Тем не менее, я обслуживаю его с помощью страницы script, которая объединяет все сценарии в один script и мини-все это, поэтому один script отправляется в браузер со всеми моими скриптами. Это лучший из обоих миров, когда я работаю над коллекцией файлов JavaScript, которые все читаемы, и посетитель получает один сжатый файл JavaScript, что является рекомендацией по сокращению HTTP-запросов (и, следовательно, времени очереди).

Ответ 6

Как правило, лучше иметь меньше запросов большего размера, чем иметь множество небольших запросов, поскольку браузер будет выполнять только два (?) запроса параллельно с определенным доменом.

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

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

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

Если вы беспокоитесь о том, что при первом загрузке загрузите "большой" файл javascript, попробуйте загрузить его асинхронно, используя описанный здесь метод: http://www.webmaster-source.com/2010/06/07/loading-javascript-asynchronously/

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

PS: Профилируйте его в разных браузерах с помощью разных методов и напишите его, так как это окажется полезным для тех, кто также застрял на медленных JS-движках, таких как IE6:)

Ответ 7

Я использовал следующие для CSS и Javascript - большинство моих страниц в отчете Google Speed ​​составляют 94-96/100, и они загружаются очень быстро (всегда в течение секунды, даже если есть 100 КБ Javascript).

1. У меня есть функция PHP для вызова файлов - это класс и хранит все уникальные файлы, которые запрашиваются. Мой вызов выглядит примерно так:

javascript( 'jquery', 'jquery.ui', 'home-page' );

2. Я выплюнул версию этих строк, закодированную в url, вместе взятую для вызова динамической страницы PHP:

<script type="text/javascript" src="/js/?files=eNptkFsSgjAMRffCP4zlTVmDi4iQkVwibbEUHzju3UYEHMffc5r05gJnEX8IvisHnnHPQN9cMHZeKThzJOVeex7R3AmEDhQLCEZBLHLMLVhgpaXUikRMXCJbhdTjgNcG59UJyWSVPSh_0lqSSp0KN6XNEZSYwAqt_KoBY-lRRvNblBZrYeHQYdAOpHPS-VeoTpteVFwnNGSLX6ss3uwe1fi-mopg8aqt7P0LzIWwz-T_UCycC2sQavrp-QIsrnKh"></script>

3.. Эта динамическая страница PHP принимает декодирование строки и создает массив файлов, которые нужно будет вызывать. Создается путь cache_file:

$compressed_js_file_path = $_SERVER['DOCUMENT_ROOT'] . '/cache/js/' . md5( implode( '|', $js_files ) ) . '.js';

4. Он проверяет, существует ли этот путь кэш в кеше, если это так, он просто читает файл:

if( file_exists( $compressed_js_file_path ) ) {
    echo file_get_contents( $compressed_js_file_path );
} else {

5. Если он не существует, он сжимает все javascript в один файл "монолит", но понимает, что у него есть ТОЛЬКО необходимый javascript для этой страницы, а не для всего сайта.

if( $fh = @fopen( $compressed_js_file_path, 'w' ) ) {
    fwrite( $fh, $js );
    fclose( $fh );
}

// Echo the compressed Javascript
echo $js;

Я дал вам выдержки из кода. Программа, которую вы используете для сжатия javascript, полностью зависит от вас. Я использую это как с CSS, так и с Javascript, так что для всего этого файла требуется 1 HTTP-запрос, когда-либо, результат кэшируется на сервере (просто удалите этот файл, если вы что-то измените), и для этой страницы есть только необходимые Javascript и CSS.