Уменьшение времени загрузки js и css файлов

    Каждый разработчик javascript приложений рано или поздно сталкивается с проблемой большого (относительно конечно) времени загрузки подключаемых js и css файлов. Эта проблема, как известно, происходит из двух причин: большого количества подключаемых файлов (браузер имеет ограничение на количество одновременно скачиваемых файлов, поэтому пока не скачается один, браузер не приступит к скачиванию другого) и большого размера используемых библиотек (prototype, extjs и т.д.)

    Решением могло было быть ручное объединение всех подключаемых файлов в один, но это делает неудобным дальнейшие корректировки файлов, поэтому целесообразно использовать автоматическую сборку и компрессию итогового файла. Но, компрессия увеличивает нагрузку на сервер, поэтому желательно использовать кэширование, причем учитывающее возможность изменения файлов…
    Разработчик Niels Leenheer (http://rakaz.nl/) предложил реализацию описанной процедуры в своем скрипте: rakaz.nl/projects/combine/combine.phps
    Настройка скрипта легка и заключается в расположении файла combine.php в корне вашего сайта, создания отдельных директорий для javascript, css и кэш файлов и прописывания этих путей в файле combine.php

    Пример относительных путей от расположения combine.php:
    $cachedir = dirname(__FILE__) . '/cache';
    $cssdir = dirname(__FILE__) . '/css';
    $jsdir = dirname(__FILE__) . '/script';

    Далее необходимо или создать или модифицировать файл .htaccess со следующим содержимым:
    RewriteEngine On
    RewriteBase /
    RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
    RewriteRule ^javascript/(.*\.js) /combine.php?type=javascript&files=$1

    Если файл .htaccess уже существует и используется RewriteEngine, то первые две строчки не нужны.

    Пример использования:
    <script type="text/javascript" src="script/yui-utilities.js,ext-yui-adapter.js,ext-all.js"></script>
    <link rel="stylesheet" type="text/css" href="css/ext-all.css,vista.css,main.css">

    Насколько описанное решение эффективно можете решить сами.
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 58

    • НЛО прилетело и опубликовало эту надпись здесь
        –1
        Я проверял его работу в IE6, FF, Opera и везде получал в итоге эффективную загрузку используемых скриптов и стилей.
        На счет устаревших браузеров я придерживаюсь жесткой позиции: вытаскивать IE3-5 или NN4 нет никакого желания. ;)
        Впрочем приписка в конце топика говорит о том, что читатель сам должен решить для себя насколько это решение эффективно.
        • НЛО прилетело и опубликовало эту надпись здесь
            0
            через php не обязательно, что будет часто грузить. просто в заголовке отдачи файла прописывайте прошедшую дату и сервер определяет файл, как уже загруженный.
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                я уже реализовывал такую вещь. просто проверяешь дату изменения файла-источника: css или js и сравниваешь с текущей, если она изменилась, то даешь заголовок на обновление, если нет, то заголовок без изменений.
                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    ты проверяешь дату изменения файла-источника и в зависимости от этого формировать заголовок.
                    кстати, действительно, игра не стоит того (см. описание ниж))
                    • НЛО прилетело и опубликовало эту надпись здесь
        0
        Мне кажется не вариант. Все загружаемые файлы и так кешируются, пропускать постоянно загружаемые файлы еще через PHP-фильтр не зачем. А если учесть то, что компрессия-декомпрессия не лучшим образом сказывается на производительность сервера, то вариант не особо хороший, имхо.

        Да и еще... Браузер все равно будет загружать много файлов. Если у вас скрипт отдает один и тот же разные файлы, все равно клиент считает это за файлы, а не один файл.
          0
          Кажется вы не поняли, производительность учитывается. Создается файл-кэш и он используется в последующей отдаче, т.е. компрессия происходит только один раз для одного состояния всех подключаемых файлов. Загляните в код.
          Браузер будет загружать ОДИН файл, имя которого будет составлено из названий подключенных файлов. Для приведенного примера файл будет иметь название "yui-utilities.js,ext-yui-adapter.js,ext-all.js"
          • НЛО прилетело и опубликовало эту надпись здесь
              0
              Согласен, статья получилась в стиле "навести на размышления о ...". Пусть хоть не время, но хотя бы траффик пользователям сэкономит ;)
                +2
                В вашем случае удобно зарегистрироваться на google.com/a с субдоменом типа static.rc-dеsign.ru и забросить туда всю статику (там даётся 100мб места под файлы). Проверенно на больших трафиках — сервер разгружается заметно, а google вполне допускает такой способ эксплуатации своих мощностей. =)
                0
                Уже поздно было. Взглянул на код, задумку понял. Весьма не плохо. Как-нибудь проведу эксперимент с замерами нагрузки и времени.
                  0
                  А что тут мерять? со статикой запрос одной страницы занимал 1 вызов php а с этим методом 3! При этом не обрабатывается if-modified-since, что заставляет браузер выгребать эти скрипты при переходе на каждую страницу сайта.

                  Со статикой будет меньше трафика (апач умеет сам отдавать 304 для не изменившихся статических файлов) и меньше нагрузки на сервер (php будет вызван лишь 1 раз на страницу).
                    0
                    Мало того, апач умеет сам сжимать отдаваемые файлы: mod_deflate. Однако все это теория, практика может быть все-таки несколько другой.
                      0
                      Для меня это не теория =) Я уже ставил такие эксперименты.
                      0
                      If-modified-since говорите? А часть кода:


                      $lastmodified = max($lastmodified, filemtime($path));
                      }

                      // Send Etag hash
                      $hash = $lastmodified . '-' . md5($_GET['files']);
                      header ("Etag: \"" . $hash . "\"");

                      if (isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
                      stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) == '"' . $hash . '"')
                      {
                      // Return visit and no modifications, so do not send anything
                      header ("HTTP/1.0 304 Not Modified");
                      header ('Content-Length: 0');
                      }

                      Разве не выполняет аналогичное действие принудительно?
                        0
                        Этот код написан неправильно. можете убедиться с помощью http-снифера. Обработка нужна именно для if-modified-since
                          0
                          Спасибо, посмотрю.
                0



                эта структура на валидность проверку не проходит. правда, проверял только две эти строчки...
                  0
                  кстати, схожий участок кода с LJ (при вырезании остального шума) является валидным XHTML 1.0 Transitional =)
                  там, правда используется чуть-чуть другой URL:

                  <link rel="stylesheet" type="text/css" href="http://stat.livejournal.com/??lj_base.css,contextualhover.css" />
                  0
                  1. посмотреть профиль Vitaly правильно сказал, что нагрузку на сервер вы только увеличите и в ваших же интересах просто объединять все файлы статически на стороне сервера.
                  2. К какому результату приведёт вызов такого вида <iframe src="css/index.php,conf.php,secret.php"> ? Скорее всего это даст беспрепятственно скачать ваши исходники.
                    0
                    Попробуйте ;) Не даст.
                      0
                      сразу не заметил текст скрипта на php. не пробовал, но увидел защиты от выхода в другие каталоги и проверку окончание .js .css (не знаю как сработает ../index.php;main.css — может тут и дырка.)

                      Скрипт переутяжелён и явно даст неоправданную нагрузку на сервер. Тут всё ясно: хотите оптимизировать — скливайте файлы физически и доверяйте их загрузку вэб-серверу, а не php.
                        +1
                        Кажется все зациклились на большие нагрузки. По моему скромному мнению в интернете 90 процентов сайтов не испытывают больших нагрузок.
                          0
                          По моему скромному мнению одна минута на склейку скриптов даст лучший результат, чем написание такой системы. Ваши 90% (а реально 99%) сайтов стоят на shared-хостингах, где один сервер тянет груду таких сайтов и подобные варианты разбазаривания памяти и процессорного времени мешают другим сайтам работать нормально.
                            0
                            У вас что, руки горят заклеймить? :) Да, да, вы правы и будет на этом.
                              0
                              Мне всё равно. Вы высказали мнение, я высказал мнение. Это дискуссия. Стыдно строить из себя обиженного ребёнка лишь по тому, что ваши аргументы оказались слабее. Вы конечно же можете наплевать на мнение высказавшихся, но пожалуйста обойдитесь без апломба.
                                –1
                                Однако жаль, что такие дискуссии и приводят к святым войнам. Ведь каждый волен оставаться при своем мнении, даже если оно слабо аргументировано. Моя задача была не показать "единственно верное решение для", а указать на один из множества существующих методов. Поверьте, есть те, кто не парится большими нагрузками, но хотят получить в итоге некое относительное быстродействие и возможно, повторяю, возможно описанное решение поможет или наведет на мысли, что собственно и произошло чуть выше (посмотрите комментарии). Безо всякой обиды ;)
                                  +1
                                  Никакой обиды, но лично я против тиражирования инструментов с такой низкой эффективностью и с таким количеством побочных эффектов. Квадратное колесо не имеет права на существование не как конкурент (личное мнение) круглого, а как глупость, которая может принести проблемы неразборчивым и плохо понявшим суть.

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

                                  Подумайте конструктивно, если на вашем хостинге все поставят такой скрипт — ваш сайт начнёт тормозить (без шуток). Вам разве выгодно популяризировать такие решения? Мне точно — нет.
                                    0
                                    Каждое мнение имеет право на жизнь. Когда и про интернет говорили в тех же словах что и Вы. да, решение не идеальное, но человек ДУМАЕТ. Пусть даже и не в том направлении что и Вы. Это его право.
                                      0
                                      Я искренне рад, что человек думает. Но зачем же выносить это на публику не разобравшись в том насколько ей это интересно?

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

                                      Все мы периодически уходим со сцены забросанные помидорами, и надо как-то спокойнее к этому относиться и учиться на ошибках.
                                        0
                                        Согласен.
                                          0
                                          Как же еще разобраться в вопросе "интересности" кроме как пустить в народ?
                                            0
                                            Но чую, что правильным решением является полное игнорирование комментариев к топикам. Так и нервы будут на месте и народ не будет так бушевать доказательствами субъективной правоты.
                                              0
                                              А такое поведение в психологии называется неадекватным.

                                              Раз не хочешь слышать обратную связь, так зачем идёшь на трибуну?

                                              Про субъективность. Я готов отстоять свою точку зрения или признать её несостоятельность под натиском аргументов. А вы?
                                                0
                                                Дело в том, что безобидную публикацию с предложением оценить для себя (т.е. или принять или отвергнуть как непригодную) методику вы превратили в какое то навязывание с моей стороны единственно верного решения, озвученного с трибуны в полный голос. Да с чего вы взяли, что все вдруг прислушались к предложенному? Оценка за топик низкая, в топ он не попадает и спокойно себе "погибнет" в потоке новостей. Кого-то она навела на мысли, кто-то открестился и все благополучно забыли, кроме правдоруба ;)
                                              0
                                              Это способ проверки минного поля игрой в футбол. =)

                                              Вы никогда не слышали про метод фокус-групп? Достаточно обсудить идею/программу с несколькими знакомыми специалистами и мин останется значительно меньше. А лучше конечно идти на трибуну будучи настоящим профи в том вопросе, который собираешься освещать, когда ни у кого из знакомых спецов не будет аргументов против. И даже в этом случае есть шанс наловить помидоров. =)
                                                0
                                                Имхо глаголите вы складно, но посудите сами что останется на хабре при поголовном поддерживании правила: молчи или дерись за то, что сказал? Сплошные новости и предложения прикрутить какую-нибудь фишку к движку. В войнах мнений нет выигравших и проигравших, только флуд и потерянные нервные клетки.
                        0
                        Не думаю, что это лучший вариант.

                        Лично я для сжатия JavaScript-а использую JavaScript Packer (http://dean.edwards.name/packer/). Им, в частности, сжат тот же jQuery.

                        Сжимает неплохо, хотя проблему объединения нескольких JS-скриптов в один им не решишь (ну, только если вручную их собрать в кучу).
                          0
                          У всего есть свои плюсы и свои минусы. Попробуйте упаковать Эдвардским упаковщиком js с utf-8 текстом... Сборка в ручную указывалась в качестве решения и насколько она оправдана решать, в конечном итоге разработчику
                            0
                            да тут и к гадалке ходить не надо — у вашего способа нет ни одного реального преимущества (кроме сомнительного в виде лени разработчика собрать файлы статикой).

                            Кстати почему-то вы не рассмотрели вариант написания скрипта, который создаёт статические связки и вызывается только в момент обновления оригиналов. А ведь такой вариант и лень вашу обрадует и неприятностей не создаст.
                              0
                              1. Не моего
                              2. Способ предоставлен на рассмотрение, о чем есть как приписка в топике, так и слова в комментариях
                              3. Я не рассматривал другие варианты написания, поскольку меня устроил вышеописанный.

                              Выбирайте сами, это ваше право.
                                0
                                Если вас устроил вышеописанный вариант, то зачем вы решили обсудить его здесь? А раз вы представили этот вариант на обсуждение. Услышали критику. Делайте с нею что хотите, но не надо затыкать если вам не нравятся чужие аргументы.
                                  0
                                  Я просто не хочу, чтобы мы друг друга расстраивали ;) Вариант предоставлен не на обсуждение, а на рассмотрение. Личное рассмотрение разработчика. Вы предоставили свое мнение, за это вам большое спасибо (без всякого апломба говорю).
                                    0
                                    Извините, если я вас расстроил. В свою очередь вами я не расстроен. Вопрос лишь в том, что при всём "представлении на рассмотрение" вы попытались затеять спор да ещё и перевести его в плоскость вкусов. Впрочем он уже завершён, верно?
                                      0
                                      Да, да ;) Я уже несколько постов пытаюсь это сказать. Спор завершен ;)
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              Есть, есть нюансы. Указанный упаковщик, как я уже упоминал, не дружит с utf-8 и с некоторыми "хитрыми" конструкциями.
                              • НЛО прилетело и опубликовало эту надпись здесь
                                  +1
                                  Попробуйте http://www.dev411.com/blog/2006/07/28/on…
                                  Хотя и у этого есть свои минусы и тоже может не завернуть. Но попробовать стоит ;)
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                  0
                                  Хм… Нет, насколько я помню, никаких дополнительных условий там не налагается.

                                  Не знаю даже…
                                    0
                                    Условия не налагаются, но опыт говорит, что не все так гладко.
                                0
                                Хочу поделиться опытом =)

                                Мы как-то раз пробовали использовать этот метод (немного его доработав):
                                1) Для удобства разработки разбили css и js файлы на маленькие части
                                2) В оригинале массив файлов формировался из запроса, у нас - из сформированного массива PHP, в котором все маленькие части и собирались.

                                Хочу сказать, что это была ошибка =( Когда Apache начинал тормозить (по разным причинам), файлы js и css грузились очень по долгу, от чего страница визуально вообще не отображалась.

                                Проблему решили так:
                                1) В .htaccess настроили mod_rewrite: если файла нет, передавать $REQUEST_URI в PHP
                                2) В PHP файле (в нашем варианте combine.phps) добавили создание статичного файла чтобы он был доступен по запрашиваемому URLу
                                3) Настроили nginx: если нет файла, передавать запрос дальше в Apache
                                4) Сжатие через nginx делать не стали - были проблемы с некоторыми версиями IE6

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

                                Самое читаемое