В сентябре 2005 года интернациональная творческая команда Orange Movie Project собралась в Амстердаме (режиссер — сириец из США, арт-директор из Германии, художники-постановщики из Австралии и Германии), и работа началась. А уже в марте нынешнего года состоялась премьера десятиминутного анимационного мультфильма, который в мае был выпущен на DVD и выложен в Сеть, вместе со всеми рабочими файлами. Таким образом, «Elephants Dream» в максимальной комплектации — это не только мультфильм, но еще и учебник по работе с Blender (благо львиная доля работы выполнялась именно в этом пакете).
   Правда, при подготовке фильма создателям пришлось слегка отступить от заявленных принципов. Строго говоря, при создании «Elephants Dream» применялось не только свободное ПО. Озвучивание проводила сторонняя компания, использующая привычный для себя проприетарный софт (Reaktor). Кроме того, часть текстур разрабатывалась вне рамок проекта, и какое ПО применялось для их создания — точно неизвестно. Проприетарное ПО использовалось также при кодировании окончательной версии фильма (что в любом случае было неизбежно, так как наиболее популярные видеокодеки никакого отношения к open source не имеют) и при подготовке DVD.
   Впрочем, все эти моменты непринципиальны, и, наверное, даже хорошо, что создатели мультфильма не стали упорствовать в своей приверженности свободным программным продуктам, а поручили часть работы профессионалам. Потому что даже в области анимации получилось у них, честно говоря, не все.
Фильм
   После всей этой предыстории о фильме хочется сказать что-то хорошее, но первый блин вышел слегка комом. Сконцентрировавшись на визуальной составляющей, авторы фильма совершенно забыли про сюжет. Для особо непонятливых зрителей (а таковых, если судить по форумам, набралось довольно много) даже было написано некое подобие балетной программки, где объясняется, что же все-таки происходит на экране.
   С точки зрения невинного, не читавшего Рембрандта зрителя происходит в мультфильме следующее: суровый старик по имени Пруг таскает за собой молодого, но уже чуть пришибленного жизнью Эмо (в одном из сообщений утверждалось, что это трубач, но при просмотре этот вывод решительно ниоткуда не следует) и рассказывает ему, как жизнь устроена. Жизнь устроена не очень уютно, а местами даже жутковато. В финале Эмо пытается вырваться из-под влияния Пруга, но не слишком удачно. Конец. Кто такие Пруг и Эмо, почему они ходят вместе и где они, собственно, ходят — не слишком понятно.
   Другими словами, о сюжете как таковом речь не идет. О диалогах, в общем-то, тоже, хотя, конечно, несколько раз повторенную конструкцию («Эмо, посмотри направо, а теперь посмотри налево». — «Угу») можно при большом желании считать диалогом. Анимация самих персонажей тоже оставляет желать лучшего. Десять лет назад это было бы здорово, но сегодня… В общем, не Pixar.
   Но и делал эту короткометражку не Pixar. И людей, которые над ней работали, намного меньше, чем в Pixar. И ресурсы, которыми эти люди располагали, несравнимы с ресурсами, доступными крупным студиям. И времени у них было меньше. И, самое главное, опыта создания полноценных анимационных фильмов у большинства участников проекта тоже не было. Никакого. Если учитывать все эти факторы и рассматривать «Elephants Dream» не как художественное произведение, а как впечатляющую демонстрацию возможностей Blender, то проект удался на сто пятьдесят процентов.
   И даже без всяких скидок — нарисован «Elephants Dream» прекрасно (а анимация даже в неудачных моментах всяко получше, чем в «Правдивой истории о Красной Шапке»). Для хорошего мультфильма этого, конечно, недостаточно, однако для первой попытки — вполне. Тем более что сами создатели мультфильма о недостатках своего проекта прекрасно осведомлены и наверняка какие-то выводы сделают.
Кому выгодно?
   Разумный вопрос, даже когда речь идет о хорошем деле. Если люди сначала отчаянно ищут деньги на проект, потом несколько месяцев вкалывают чуть ли не круглые сутки, а в итоге просто-напросто раздают результаты своего труда всем желающим — что-то здесь не то.
   Главная цель проекта Orange Movie Project — популяризация даже не столько свободного программного обеспечения, сколько самого пакета Blender. С одной стороны, уникальная история Blender обеспечила ему упоминание в девяти из десяти статьях, посвященных бесплатному софту. С другой — многие профессионалы знают о Blender немногим больше журналистов, и общепринятым в индустрии считается мнение, что функциональные возможности этого пакета ограничены (это правда, но у какого пакета они не ограничены?), а активная разработка остановилась несколько лет назад (не совсем правда — возможно, оставайся Blender проприетарным, он развивался бы быстрее, но мертвым этот проект вовсе не назовешь).
   Таким образом, создатели Open Movie Project ставили перед собой три задачи:
   показать возможности Blender и доказать, что это полноценная программа для создания 3D-анимации;
   на примере реального и сложного проекта выявить слабые места Blender и форсировать разработку недостающей функциональности;
   дать людям возможность «поиграться» с Blender на по-настоящему богатом контенте.
   Первые два пункта тесно связаны. Не секрет, что разработка Blender ведется в основном добровольцами, и проект не развивается так быстро, как хотелось бы его создателям. Но если программой заинтересуется некая студия по производству визуальных эффектов, которой не хватит в Blender определенной функциональности, она вполне может спонсировать ее добавление или разработать нужные модули самостоятельно, сделав их затем общедоступными (не исключено, что оба подхода обеспечат студии солидную экономию, если сравнивать возможные затраты с затратами на покупку лицензий платного 3D-софта).
   Пока ни одна студия не заинтересовалась пакетом настолько, чтобы тратить на него деньги, Blender дорабатывался по запросам креативной команды. Собственно говоря, простой пользователь Blender не смог бы сваять «Elephants Dream», потому что на момент начала проекта в нем действительно было реализовано не все, что нужно (и даже сегодня значительная часть функциональности только обещана в будущей версии 2.42).
   Про последний же пункт стоит рассказать чуть подробнее. Благодаря тому, что практически все составляющие фильма (включая исходники для Blender) выпущены по лицензии Creative Commons и доступны, каждый желающий может использовать эти ресурсы для своих собственных проектов (включая коммерческие). Можно посмотреть, как делаются те или иные вещи (Blender — как почти любой свободно распространяемый софт — не может похвастать хорошей документацией) и использовать это знание при создании своих фильмов. А можно взять уже готовых персонажей, нарисовать другие бэкграунды и сделать совершенно новый фильм. Или еще проще — перемонтировать и переозвучить то, что уже есть, еще сильнее сократив время на подготовку «своей» картины.
   Если пример Orange Movie Project окажется заразительным, то уже через несколько лет из искры может разгореться пламя, и на смену музыкальным ремиксам придут полноценные видеоремиксы, собранные из общедоступных кирпичиков (сцен, персонажей, бэкграундов и т. д.). Сдерживающих факторов всего два. Во-первых, не очень понятно, кто будет создавать эти кирпичики, — заинтересованность Orange Movie Project очевидна, но только их усилий для этого явно не хватит. Во-вторых — неподъемные для обычного пользователя требования к вычислительным ресурсам.
   Впрочем, высокие требования к ресурсам — фактор временный. Десять лет назад многое из того, что сегодня считается обыденным, — например, редактирование видео на домашнем компьютере, — казалось фантастикой. Так что не исключено, что «Elephants Dream» — это первая ласточка, знаменующая наступление новой эпохи в 3D-анимации, когда создание мультфильма будет доступно даже любителям (пусть не совсем самостоятельного, а по следам чужих разработок).
   Что же до художественной ценности — так знаменитое «Прибытие поезда» с кинематографической точки зрения тоже, если честно, не шедевр. Ну какой там сюжет? Поезд из Воркуты прибывает на второй путь. Вот, собственно, и все.
   А люди помнят.

ОПЫТЫ: Видео ремонт

   Автор: Филипп Казаков
   Когда домашние кинотеатры маячили где-то на горизонте, а бытовые DVD-плейеры только-только появились и стоили по 500—700 долларов, я очень удивлялся, зачем люди их покупают. Ведь за те же деньги можно собрать компьютер, который воспроизводит музыку, DVD, кривые пиратские «дивиксы» да еще и делает в тысячу раз больше, чем умели и сейчас умеют бытовые проигрыватели. Ответ на этот вопрос печален в своей банальности: бытовыми плейерами гораздо проще пользоваться. Единственное, что требуется от счастливого покупателя ширпотреба, — подключить его к телевизору двумя-тремя проводками, вставить диск и нажать кнопку на пульте. А вот чтобы сделать видеоплейер из своего домашнего компьютера, придется потрудиться: снизить шум системного блока, поставить операционную систему, плейеры, кодеки, купить специальные кабели и соединить выходы звуковой и видеокарты с телевизором, докупить пульт ДУ и наконец настроить все это хозяйство. Дело, прямо скажем, гораздо более мозгоемкое. Кроме того, компьютер, в отличие от узкоспециализированного устройства, штука капризная, и настроение его может меняться. Хоть беспричинных глюков не бывает, порой трудно понять, с чего вдруг перестали играться видеофайлы. Давайте попробуем проанализировать главные причины возникновения проблем при воспроизведении видео на компьютере под управлением Windows. Даже если эта статья не поможет вам локализовать неисправность, вы, по крайней мере, будете знать, в каком направлении «рыть землю».
   Разумеется, прежде чем начинать диагностику, следует выбрать заведомо «не битый» видеофайл, то есть полученный из надежных источников либо нормально воспроизводящийся на других компьютерах. Также следует заранее удостовериться, что проблемы не связаны с нехваткой системных ресурсов. С этой задачей, уверен, читатели «Компьютерры» справятся самостоятельно.
   Первая по распространенности причина неполадок с воспроизведением видео кроется в неправильном режиме работы CD/DVD-ROM-драйва. Вместо DMA, то есть режима прямого обращения к памяти, оптический привод почему-то переключается в режим PIO, при котором вся считываемая информация прогоняется через процессор, что катастрофически сказывается на его загрузке. Диагностировать это очень просто: из Диспетчера устройств зайдите в свойства вашего IDE-контроллера, где в закладке «Дополнительные параметры» указан режим работы каждого из каналов устройства. Если на канале с приводом активен PIO-режим, поменяйте его на DMA. Не поможет — обновите драйвер или удалите контроллер из системы: после перезагрузки ОС все может встать на свои места. Если эти очевидные меры не помогают, придется лезть в Сеть с поисковым запросом «DMA PIO». Эта проблема имеет с десяток причин и методов решений. Если с режимом работы у вашей «читалки» все о’кей, для дальнейшей диагностики лучше все равно скопировать проблемный файл на винчестер.
   Выполнив предварительную диагностику, переходим к детальным исследованиям. Абсолютное большинство видеопроигрывателей для Windows используют разработанную Microsoft технологию DirectShow. Ее особенность заключается в том, что видеоплейер не заботится о декодировании входного файла: при воспроизведении медиафайлов поток данных последовательно проходит через цепочку специальных системных библиотек обработки — DirectShow-фильтров, — каждый из которых производит с ним одну узкоспециализированную операцию. Таким образом, теоретически процесс декодирования видеофайла не должен быть привязан к конкретному ПО, инициализировавшему его запуск. Однако это только в теории, а на практике популярных видеоплейеров очень много, и далеко не все они корректно общаются с DirectShow-интерфейсом, а многие и вовсе игнорируют его, используя свои собственные декодеры. Чтобы во время диагностики исключить возможность влияния плейера, воспользуемся бесплатной утилитой GraphEdit[Скачать ее можно с www.videohelp.com/download/graphedit041201.zip.] от Microsoft, предназначенной, в частности, для «низкоуровнего» доступа к DirectShow-фильтрам. Перетягиваем файл-пациент в рабочее поле GraphEdit. Далее возможны четыре варианта развития событий.
   1. Файл открывается в GraphEdit, в результате чего на экране строится цепочка прямоугольников-фильтров, а после нажатия треугольной стрелочки в панели инструментов (старт рендеринга) видео проигрывается без всяких проблем. Не обязательно быть Шерлоком Холмсом, чтобы понять: виновник всех прошлых глюков — ваш программный плейер. Меняйте плейер или попытайте счастья на сайте его разработчика: возможно, уже вышла более стабильная версия.
   2. GraphEdit выдает сообщение, начинающееся со слов «Could not construct a graph from this file». Несмотря на грозный вид сообщения и пугающий код ошибки, ничего страшного в нем нет. Оно всего лишь означает, что в системе установлены не все декодеры и сплиттеры, требующиеся для воспроизведения файла. Достаточно скачать из Сети нужные кодеки, и файл заиграет (по крайней мере, должен заиграть). Если вы не знаете, каким кодеком закодирован ваш файл, придется отправиться на разведку. Главное, удержаться от соблазна скачать и установить какой-нибудь многомегабайтный Megamax Codec Pack Plus (если, конечно, вы этого еще не сделали) — подобные «паки», неизвестно кем и как собранные, не столько решают проблемы, сколько создают новые. Чтобы определить формат медиапотоков вашего файла, сначала обратите внимание на его расширение (в большинстве случаев оно однозначно указывает на используемый контейнер). Если это .avi, в нем легко разберутся специальные утилиты: AVIcodec[avicodec.duby.info] или GSpot[www.headbands.com/gspot]. Если это .mkv, .ogm, или .mpg — поможет VirtualDubMod[sourceforge.net/projects/virtualdubmod]. Более редкие контейнеры (.mp4, .ts, .264, .rm, .vob и др.) обычно определяют и кодеки, которыми внутри сжато аудио и видео, так что софт, необходимый для воспроизведения файлов такого типа, легко находится через Яндекс с Гуглом.
   3. Файл открылся, цепочка построена, но при попытке рендеринга происходит ошибка или падает GraphEdit. Эта малоприятная ситуация означает, что либо цепочка фильтров построена неверно, либо глючит одно из ее звеньев. Чтобы решить эту проблему, нужно построить правильную цепочку фильтров, запуск которой приведет к корректному воспроизведению файла. Добавлять фильтры можно из меню Graph > Insert Filters > DirectShow Filters, а связывать их в цепочки — курсором мыши. Ориентируйтесь по скриншотам: на них приведены иллюстрации правильных цепочек для основных типов контейнеров[Для редких видеокарт (например, Matrox G400) приведенные цепочки несправедливы]. Если нужных декодеров и сплиттеров в системе не обнаружится, их придется скачать и установить, но в любом случае, какой бы файл вы ни декодировали, принцип построения цепочек один и тот же. После того как вы найдете правильную цепочку, результат нужно будет как-то зафиксировать, чтобы любой открываемый файл подобного типа по умолчанию декодировался по правильной цепочке. К сожалению, в Windows нет встроенных средств для управления приоритетами DirectShow-фильтров, так что для этого нужна отдельная утилита, например DirectShow Filter Manager[www.softella.com/dsfm/index.ru.htm]. Будьте очень аккуратны при ее использовании — она затрагивает глубинные настройки операционной системы. Слишком резкое изменение приоритетов может привести к неприятным сюрпризам.
   4. Файл в GraphEdit открылся, цепочка фильтров построена и работает, однако исходная проблема упорно не исчезает. Что ж, продолжим эксперименты. Следующий шаг — проверка видео других типов. Постарайтесь найти побольше самых разных видеофайлов и проверить их в GraphEdit. Если все остальные типы файлов играются нормально, а глючит только один кодек или контейнер, возвращайтесь к предыдущему пункту. Ежели выяснится, что глюки никак не связаны с форматом видео, — дела плохи, причина лежит на более низком, чем DirectShow, уровне. Вероятнее всего, она связана с воспроизведением декодированной информации видеокартой (или аудио в крайне редких случаях). Попробуйте обновить DirectX, переставьте драйверы видеокарты. Проверьте, работает ли overlay-режим воспроизведения видео, поиграйте с другими настройками драйвера или поищите его более древнюю версию. Как ни странно, в исключительных случаях последняя мера может помочь — как-то мне довелось ставить современную AGP4x-видеокарту на устаревшую материнскую плату на легендарном чипсете i440BX. Система стабильно работала в 3D, а при воспроизведении overlay-видео зависала. Проблема решилась установкой драйвера позапрошлого поколения.
   Как показывает практика, четвертый вариант развития событий встречается редко, обычно неприятности случаются из-за конфликтов DirectShow-фильтров. И это легко объяснимо: политика Windows позволяет любому приложению устанавливать в систему свои DirectShow-фильтры, никак не иллюстрируя этот процесс и не спрашивая согласия пользователя. К примеру, установив Nero Burning ROM — известную утилиту для записи CD/DVD-дисков, — можно обнаружить, что парк DirectShow-фильтров неожиданно пополнился декодерами от Nero, казалось бы, не имеющими никакого отношения к нарезке болванок. И этот случай далеко не единственный — многие известнейшие продукты, напрямую не относящиеся к воспроизведению видео и звука, ведут себя аналогично. Таким образом, на перегруженном программными продуктами компьютере скапливается немало фильтров от разных производителей, далеко не всегда корректно взаимодействующих друг с другом.
   Окончательно запутывают ситуацию уже упоминавшиеся Codec Pack’и, якобы содержащие в одном инсталляционном файле декодеры для всех возможных форматов видео и аудио. Да, действительно, на момент сборки они, возможно, поддерживают большую часть актуальных форматов. Однако последствия одновременной установки большого количества фильтров совершенно непредсказуемы, ведь заранее узнать, «подружатся» ли они с текущим набором декодеров конкретной системы, невозможно. Хорошо еще, если на случай «не подружатся» сборщик Codec Pack’a позаботится о правильной процедуре деинсталляции своего детища, а если нет?..
   Так что залог видеоздоровья компьютера — установка по отдельности минимума необходимых декодеров. Тогда, возможно, и эта статья вам не пригодится.

Детали: Ускоряем JavaScript

   Автор: Хендерсон, Кэл
   Кажется, всего несколько дней назад мы рассказывали вам об истории Flickr, и вот — статья, написанная главным разработчиком этой компании Кэлом Хендерсоном. Статья довольно специфичная — это вполне конкретные советы по решению вполне конкретных проблем, с которыми может столкнуться практически любой веб-разработчик. Как правило, мы стараемся не публиковать материалы такого плана, однако и Веб 2.0 — штука довольно новая, и проблемы, которые поднимает Хендерсон, далеко не для всех очевидны (что уж говорить о способах их преодоления), и литературы, освещающей эти вопросы, тоже не очень много, — к сожалению, большинство авторов компьютерных книжек делает упор на подробное описание синтаксиса, избегая рассуждать о тонкостях применения тех или иных техник. Хендерсон на синтаксис не отвлекается. Не рассказывает он и о том, как делать приложения, активно использующие JavaScript и CSS. Его интересует другое — «как сделать эти приложения по-настоящему интерактивными и быстрыми». — В.Г.
   Так называемые приложения Веб 2.0 предполагают более интенсивное использование CSS и JavaScript, чем раньше. Но для быстрой и качественной работы приложения мы должны оптимизировать размер и выдачу контента, который требуется для рендеринга страницы. На практике это означает, что мы должны сделать статический контент настолько маленьким и быстрым для загрузки, насколько это возможно, избегая немотивированной раздачи файлов, которые не претерпели изменений.
   Эта задача несколько усложняется самой природой файлов CSS и JavaScript. В отличие от изображений, исходный код CSS и JavaScript скорее всего с течением времени будет меняться неоднократно. И нам нужно, чтобы после каждого изменения клиенты могли загрузить обновленные версии файлов, не пытаясь использовать старые версии, сохраненные в их локальном кэше (а также во всех кэшах, которые встретятся по пути). В этой статье мы обсудим, как облегчить жизнь пользователю — при первой и последующих загрузках страницы, а также по мере того, как приложение развивается и обновляется.
   Кроме того, мы должны максимально упростить жизнь разработчиков, так что обсудим заодно и способы автоматизации процессов оптимизации. Немного предварительной возни позволит нам совместить легкость разработки с удобством использования — и все без изменения привычных практик.
Монолит
   Раньше считалось, что максимальной производительности можно добиться, объединив многочисленные CSS— и JavaScript-файлы в более крупные блоки. Вместо десятка JavaScript-файлов по 5 Кбайт каждый мы делали один файл размером 50 Кбайт. Хотя общий размер кода при этом не менялся, мы сокращали накладные расходы на обработку HTTP-запросов.
   Также важен аспект распараллеливания. По умолчанию и IE и Mozilla/Firefox при использовании стабильного соединения загружают только два файла с одного домена (см. спецификацию HTTP 1.1, секция 8.1.4). Это означает, что пока не загрузятся все скрипты, мы не загружаем картинки. Все это время пользователи видят страницу без изображений.
   Однако у этого подхода есть и недостатки. Совмещая все наши ресурсы, мы заставляем пользователя загружать всё и сразу. Разделив содержимое между разными файлами, мы могли бы распределить тяжесть загрузки поверх нескольких страниц (или вообще избежать загрузки отдельных блоков — зависит от поведения пользователя). Если же мы замедлим загрузку первой страницы, чтобы ускорить загрузку всех остальных, то можем столкнуться с тем, что второй страницы многие пользователи просто не дождутся.
   Исторически этот крупный недостаток такого подхода нечасто брался в расчет. Но для системы, в которой постоянные изменения содержимого статических файлов — обычное дело, это важно, поскольку любое изменение в большом едином блоке требует, чтобы клиент перегрузил себе полный рабочий набор CSS или JavaScript. Если приложение представляет собой монолитный исходник на JavaScript размером 100 Кбайт, значит, каждая мелочь приводит к принудительной загрузке лишних 100 Кбайт.
Один в поле не воин
   В качестве альтернативного подхода постараемся придерживаться золотой середины. Разобъем наши CSS— и JavaScript-ресурсы на множество подфайлов, сохраняя в то же время количество этих файлов функционально невысоким. С одной стороны, нам удобно разрабатывать приложения, разбивая код на логические блоки. С другой стороны, для работы приложения важно, чтобы этих блоков было не слишком много (так что нам приходится объединять эти файлы). Компромисса можно добиться, сделав определенные добавления к системе сборки билдов (набор инструментов, превращающий «грязный» код разработки в рабочий, готовый для развертывания код).
   Для прикладного окружения, в котором среда разработки и среда исполнения четко разделены, подойдут простые техники управления кодом. Пусть в среде разработки код для пущей ясности разбит на множество логических блоков. Создадим в Smarty (язык шаблонов для PHP) простую функцию загрузки JavaScript:
 
   {insert_js files="foo.js,bar.js,baz.js"}
   function smarty_insert_js($args){
   foreach (explode(‘,’, $args[‘files’]) as $file){
   echo «<script type=\»text/javascript\" src=\"/javascript/$file\"></script>n";
   <script type="text/javascript" src="/javascript/foo.js"></script>
   <script type="text/javascript" src="/javascript/bar.js"></script>
   <script type="text/javascript" src="/javascript/baz.js"></script>
   Пока все просто. Но затем мы во время сборки билда объединяем нужные файлы. Представьте, что в нашем примере мы должны объединить foo.js и bar.js в foobar.js, раз уж они почти всегда подгружаются вместе. Учтем этот факт при настройке нашего приложения и модифицируем код с учетом этой информации:
 
   {insert_js files="foo.js,bar.js,baz.js"}
   # map of where we can find .js source files after the build process
   # has merged as necessary
   $GLOBALS[‘config’][‘js_source_map’] = array(
   ‘foo.js’ => ‘foobar.js’,
   ‘bar.js’ => ‘foobar.js’,
   ‘baz.js’ => ‘baz.js’,
   function smarty_insert_js($args){
   if ($GLOBALS[‘config’][‘is_dev_site’]){
   $files = explode(‘,’, $args[‘files’]);
   $files = array();
   foreach (explode(‘,’, $args[‘files’]) as $file){
   $files[$GLOBALS[‘config’][‘js_source_map’][$file]]++;
   $files = array_keys($files);
   foreach ($files as $file){
   echo «<script type=\»text/javascript\" src=\"/javascript/$file\"></script>n";
   <script type="text/javascript" src="/javascript/foobar.js"></script>
   <script type="text/javascript" src="/javascript/baz.js"></script>
   Исходный код шаблонов не меняется, что позволяет нам сохранять эти файлы разделенными во время разработки. Кроме того, мы можем написать собственный процесс объединения на PHP и использовать тот же самый конфигурационный блок при самом объединении (а использование одного и того же конфигурационного файла избавляет нас от необходимости синхронизации). А если брать по максимуму, то можно проанализировать использование скриптов и стилей на страницах сайта, чтобы определить, какие именно файлы лучше объединять (хорошие кандидаты для такого объединения — это файлы, которые почти всегда подгружаются вместе).
   В случае с CSS можно начать с полезной модели, состоящей из двух стилей: основного стиля и стиля подраздела. Единый основной стиль используется во всем приложении, а разные стили подразделов контролируют разные функциональные области. В этом случае подавляющее большинство страниц подгружают только два стиля (один из которых кэшируется при первой загрузке — это, конечно, основной).