Как стать автором
Обновить

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

Трудность отладки не минус — нечего на продакшн-сервере изменения делать (научен горьким опытом)
А в том же Yii можно настроить Script Mapping.
Мы используем такую штуку github.com/andrewdavey/cassette
При компиляции в debug все скрипты идут отдельными файлами. А при компиляции в public — объединяются в один файл
Согласен — нужно по-любому делать механизм работы как со сжатой версией как и с несжатой. И желательно простой механизм переключения между ними. Иначе дебажить крайне неудобно.
Для вашего кейса я бы рекомендовал посмортеть StealJS. Если бы была возможность конвретировать код в модули, то тогда бы лучше подошел RequireJS.
обфускация не панацея, любой eval меняем на document.write и весь чистый js как на ладони.
обфускация мною и не рассматривается как панацея, не зря же я расписал про чудо по чудо опцию по «антиобфускации» в chrome :) Но она помогает слегка сэкономить трафик, привести js файл к одной строке (для удобства), и помешать другим использовать ваши наработки как свои. Обфускация скорее бонус, нежели суть.
использую Google Closure Compiler.
Для debug'a есть ряд удобных ключей.
Сейчас уже не найду ссылку, но у какого-то зарубежного спеца по clienside'у читал, что уже не модно (читай эффективно) складывать все скрипты в один файл, а правильно подгружать нужные для разных страниц. Не зря же столько загрузчиков скриптов появилось. Впрочем, не знаю, насколько его мнение истина, т.к. он автор одного из загрузчиков :)
таки нашел ссылку. Не совсем точно сказал, как оказалось. Правильно — объединять скрипты, используемые вместе, в один, а уникальные для страниц грузить через асинхронные загрузчики.
Я думаю это очевидно, что таких групп файлов должно быть несколько в сложном приложении.
Тоже неплохой вариант, но специфический :) Пример применения — движок 10-15 файлов и 1-2 файла js-ки для текущего модуля. С другой стороны единый файл мне симпатизирует ещё тем, что если сервер тупит, то пользователю достаточно всего 1 раз загрузить страницу вашего сайта, и все остальные будут загружаться гораздо быстрее.
А что, если пользователю не нужны другие страницы? Охота, чтобы каждая страница загружалась быстро, независимо от того записан файл в кэш браузера или нет! имхо
> Охота, чтобы каждая страница загружалась быстро

В случае единого скрипта даже первая страница загрузится быстрее, чем если js-ок будет 15-30 штук. В дальнейшем скорость значительно увеличится (в завис. от скорости клиента и размера файла). Живой пример, на момент отдельных js-ок сайт загружался от 30сек до 1мин 40сек, после объединения около ~20сек. Я полагаю, что даже в случае нормального быстрого сервера, не страдающего большой нагрузкой, прирост ( даже в случае первой загрузки ) страницы будет ощутим.
Хм, пардон. Я думал что отвечаю не вам. Если речь идёт о «базовые скрипты в одном файле» + скрипты текущего модуля, то ситуация получается специфичная для конкретного сайта. К примеру, если 80% кода занимает базовый файл, а 20% кода отдельные модули, то скорее всего, лучше поместить весь оставшийся код в основной файл, если хотя бы 50 на 50, полагаю, следует провести замеры производительности :)
Какое-то у вас неправильное представление о вебдванольности.
Объединив, скажем, все js-файлы в один 200-килобайтный файл и подключив его в секции head, вы заставите браузер приостанавливать рендеринг страницы до тех пор, пока этот файл не будет загружен и распарсен. Учитывая, что на странице кроме этого обычно есть еще и картинки, то даже на канале 1мбит/с будет ощутимая задержка рендеринга (я даже не говорю про относительно маломощные клиенты типа телефонов и планшетов), когда ваш пользователь видит пустую, неотрендеренную страницу.

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

> Суровая реальность такова, что если скриптов много, то их нужно разбивать на модули и подгружать эти модули асинхронно, по мере того, как появляется потребность в модуле на странице.

У нас почти так и было (только синхронно). + у нас сильно тормозил и тупил сервак (не справлялся с нагрузкой), а это приводило к тому, что треть js-файлов отдавалось с 503, и либо отдельные части сайта не функционировали, либо он не работал полностью (в случае если модуль из главных). После объединения — сайт стал загружаться значительно быстрее (до 10 раз). В случае нормального сервера такого контраста, конечно, не будет, но выгода должна быть весьма существенной.

В новых сайтах я применяю DataURi и объединение js, это уменьшает количество загружаемых файлов (не учитывая контентных картинок) до 4-6 файлов (вместо 70, к примеру). Конечно тут есть альтернативы, но мне данный способ показался значительно удобнее и в разработке (не люблю спрайты), и в публикации.

В общем «суровые реальности» у нас с вами разные.
При сборке проекта средствами Maven можно воспользоваться плагином maven-minify, который позволяет объединять и минифицировать js и css файлы, и при этом обладает широкими возможностями конфигурации.

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

Обратитесь к книге Стояна Стефанова JavaScript Patterns, там хорошо описаны шаблоны модуляризации кода.
> если это позволяют сроки реализации проекта

В этом как раз и заключается проблема, ибо в противном случае лучше было бы переписать весь плохой код, соблюдая модульность :)
НЛО прилетело и опубликовало эту надпись здесь
Стоит испонить eval(src + "\n//@ sourceURL=" + name);
И что в хроме, что в ФФ вы получите именованный скрипт.
Не надо было его в /*… */ оборачивать и все
Так я изначально и пробовал, но не срабатывало. Погуглив я нашёл массу тем с подобной проблемой на англоязычных форумах, и ни 1го ответа. Только предположение, что мол виноват многострочный js-код. А в комментарии я поместил эту конструкцию уже позже, столкнувшись с неадекватным поведением IE :)
Ну вообще-то еще есть такая штука как Google Minify — она объединяет и минифицирует и сжимает в gzip файлы «налету» при первом обращении к ним, и кеширует сжатый итоговый файл на диск и в дальнейшем отдает только его, пока какой-либо из исходных файлов не изменится.
В итоге вы работаете с отдельными неминифицированными и несжатыми файлами, а в браузер отдается один объединенный файл, минифицированный и сжатый.
У Google Minify есть плагины под некоторые распространенные CMS — например WordPress, Zend Framework, Yii, HostCMS, с остальными системами Minify можно использовать в чистом виде, с помощью входящего в комплект билдера
в качестве дополнительного плюса можно добавить еще и решение проблемы с зависимостями
Есть же мягкий и пушистый minify

Вкратце: делаем ссылку вида /minify/?f=скрипт1.js, скрипт2.js, скрипт3.js, скрипт4.js… и вставляем ее в HEAD. Minify сам смотрит изменения файлов, кэширует и выдает весь код в виде одного сжатого файла. А разработчик продолжает работать с отдельными файлами как и раньше. Поддерживает кэширование на стороне клиента и прочие прелести. В качестве бонуса делает то же самое и с CSS.
Упс, не заметил комментарий тов. jameskotov, пардон
В комментариях приведено множество других решений, в том числе и лучших, чем предложенный мною. Мне же было интересно написать это самому :)

По поводу minify, у меня возник вопрос — поддерживается ли раздача файла как статику? Без выполнения проверяющих скриптов?
Эт понятно )

Сразу как статику — нет, в любом случае вызывается .php. Впрочем, это можно достаточно просто прикрутить самому — расковырять где у него лежит файл кэша и прописать на него редирект в .htaccess (если не существует — вызов .php). Но это, имхо, уже излишне. Учти что Minify умеет кэшировать на стороне клиента, так что обычно вся загрузка всех .js пользователю уложится в один запрос, в ответ на который придет «304 Not modified» заголовок и все. В моем случае — ~0.09 сек.
В целом отличный вариант :) минимум геморроя. Но подойдёт не всем, пример:
1. Распределение js на несколько серверов. В зависимости от реализации могут возникнуть сложности.
2. В моём случае js-ки подключаются в шаблонах, а не в head-е, и для применения minify пришлось бы перелопатить уйму кода :)
1. Все что на других доменах однозначно нужно или копировать к себе или подключать отдельно — через Minify будет плохо.
2. Может, как вариант, выловить и объединить самые отъявленные .js?
ИМХО, при этом теряется вся прелесть подхода (отсутствие геммороя, и необходимость что-то менять). К прошлому посту ещё два варианта:

1. ajax-сайт. Пилю себе на локалхосте stand-alone блог, с рассчётом на full ajax. js-ки дёргаются на событийной основе. Из вариантов: либо грузить всё сразу, либо всё по отдельности. Ну или основное сразу, остальное по отдельности. Лично мне симпатизирает только первый вариант (+- 30 Мб, ИМХО, ерунда).

2. большое количество комбинаций файлов (завалы кешей на все случаи жизни, низкая скорость отдачи ранее невостребованной комбинации).
1. Я очень слабо себе представляю блог, которому действительно необходимо было бы что-то подгружать событийно — проще и правильнее все подгрузить все сразу. Но для абстрактной задачи я бы посоветовал прогонять через Minify исходно загружаемые вещи (фреймворк + общий js-код, к примеру), а дальнейшее дергать как отдельные файлы — они будут раздаваться как статика и уж никак не повлияют на время загрузки страницы. Для красоты картины на боевом сервере их можно прогнать через любой JS-компрессор, но это уже мелочи.

2. Иногда лучше пристрелить, чтоб не мучалось. Если в проекте такой бардак, то врядли стоит тратить ощутимое время на допиливание частностей.
1. Согласен это излишне, мне нужно просто для самообучения :) Касательно предложенного вами способа я уже писал выше товарищу Sytrus-у. Это уже следующий уровень оптимизации, который далеко не всегда и не везде нужен.Лично я бы просто не стал заморачиваться.

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

На мой взгляд, все эти премудрости излишняя растрата времени. Либо выбрать простой вариант с minify, либо один из вариантов посложнее:
1. «базовый комплект» скриптов + отдельно загружаемые частные скрипты страницы
2. все скрипты сразу

Правильный выбор зависит от ситуации.
Хм, только что дошло: получается пользователь регулярно будет грузить одни и теже файлы в разных их комбинациях? К примеру:
1. первая страница: main.js, jquery.js
2. вторая страница: main.js, jquery.js, some.js

Minify хитро всё учтёт и загрузит только some.js или всё заного? И что будет если в комбинации, наоборот, будет не хватать какого либо файла?
Это будут отдельные запросы, которые будут отдельно кэшироваться и отдельно загружаться. Именно поэтому правильнее гонять через Minify один и тот же набор файлов для каждой страницы.

Есть два варианта:
а) На всех страницах запрашивать через Minify jquery.js и main.js, а там где нужно отдельным файлом some.js
б) На всех страницах запрашивать через Minify все файлы.
Можно комбинировать оба варианта, загружая для конкретной страницы несколько файлов через minify (исключая общие для всех страниц, которые были загружены выше по коду).

С точки зрения быстродействия и удобства работы в абстрактной задаче второй вариант предпочтительнее — меньше головной боли разработчику, быстрее (в общем виде) работает, больше порядка в коде.
«один и тот же набор файлов для каждой страницы» = для всех страниц сайта. Пятница, однако.
Солидарен. Примерно тоже самое отписал комментом выше :)

Привет из 2021 года! :)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории