mega.genn.org

Оптимизируя оптимизированного

Flash optimum

Воскресным утром я осуществил то, что давно собирался сделать: всерьез взялся за Action Script 3. Разобравшись в синтаксисе и принципах я решил сделать что-то простое и ненавязчивое, но в то же время дающее подергать за самые частые задачи, которые приходится делать, создавая флеш-сайты или флеш-приложения. Ничего сложного в AS3, кроме огромного количества файлов для любого хоть чуточку серьезного проекта, нет. Мало того, всплыли воспоминания о юности, в которой я стал магистром технических наук и software engineer — дорвавшись до нормального объектно-ориентированного программирования я забыл о еде, питье и вообще почти обо всем.

Теперь о поставленной себе задаче. Вчера за quattro formaggi Юра рассказал об интересном посте, который он сейчас пишет. Я предложил проиллюстрировать, что одну из описываемых задач оптимальнее всего делать на флеше. Этой задачей я и занялся, сделав флеш-ролик используя AS3. Если бы я писал на AS2, то все заняло бы не более 20 минут. С копанием в устройстве и работе Action Script 3 я справился за 40 минут. Итак, что же я делал.

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

How it works

Приводить весь первоначальный код не буду, он слишком велик для публикации просто так в посте. Кто хочет, может скачать и полюбоваться. Первоначальный же .fla не сохранился, но он не так уж необходим ;)

После компиляции флеша я получил аккуратный файл размером 4 Кбайта, отправил Юре и отправился читать Dark Blue Воррена Эллиса (Warren Ellis). После прочтения комикса мне захотелось решить какую-нибудь головоломку и я взялся за оптимизацию флеш-ролика. Достигнуть желаемых 1024 байтов мне не удалось, но результат получился удовлетворительный.

Оптимизация символов

Первым делом я, разумеется, убрал встраивание шрифта, которым показывались цифры. Для этого достаточно и _sans. Само текстовое поле сделал шириной в два символа и удалил единицу, которую написал в нем еще при создании. Половину размера как рукой сняло ;)

После этого, я избавился от всех групп: вместо размещения блика в группе над нижней плашкой, я поднял его в слой повыше, сэкономив несколько байтов. Везде, где это было возможно, я убрал прозрачность: Alpha: 100% и никаких возражений!

Оптимизация имен

Следующим шагом стала оптимизация имен. Текстовое поле из txt стало просто t, buttonBackgroundb и так далее. Это также сэкономило несколько десятков байтов. Функция arr(e:Event) в файле main.as стала называться просто a(e:Event). Поскольку она вызывается при изменении размеров окна listener’ом, это помогло уменьшить размер результирующего swf. Изменения же имен переменных никакого влияния на размер файла не оказали бы.

Оптимизация исходного кода

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

Все переменные типа Number я сделал int, после чего убрал ненужные округления. Например, если при подсчете переменной типа Number мне необходимо было указывать

  1. var colw:Number=Math.floor(stage.stageWidth/cols);

то после того, как она стала int, операция / взяла на себя функции целочисленного деления:

  1. var colw:int=stage.stageWidth/cols;

После этого, не задумываясь ни секунды, я вынес повторяющийся кусок с расстановкой блоков в отдельную функцию. Поскольку эта функция вызывается при изменении размеров окна, я записал ее прямо в функцию, вызываемую listener’ом, которую, как мы уже знаем, стали звать a:

  1. stage.addEventListener(Event.RESIZE, a);
  2. function a(e:Event):void {
  3. var cols:int=Math.ceil(stage.stageWidth/300);
  4. var colw:int=stage.stageWidth/cols;
  5. for (var i:int = 0; i < 30; i++) {
  6. var nB:Object=getChildAt(i);
  7. nB.b.width=colw;
  8. nB.x=i%cols*colw;
  9. nB.y=Math.floor(i/cols)*43;
  10. }
  11. }

Для вызова этой функции в конструкторе пришлось добавить следующее:

  1. var e:Event;
  2. a(e);

Эта конструкция добавила 2 байта к размеру swf, но до этого мы сэкономили гораздо больше.

В конце-концов я убрал проверки деления на ноль (флеш даже не поморщился) и скомпилировал проект снова. Юра предостерег меня, чтобы я не увлекся и не сделал оптимизацию настолько хорошей, что swf станет отрицательного размера. Мир в безопасности: БАК запущен, а файл с отрицательным размером у меня не получился. После всех манипуляций swf стал занимать 1149 байт. Больше в нем оптимизировать нечего. Для сравнения можно скачать получившийся проект (zip, 12,7 Кбайта). Мне кажется, что оптимизировать там уже нечего ;)

18.09.08 в 21:18 | iv:

Оптимизация символов
Назвать удаление embed шрифта из ролика оптимизацией нельзя. Это кастрация.

Оптимизация имен
За переименование в однобуквенные - отрывать руки.

18.09.08 в 21:29 | Genn:

iv, в определенных случаях достаточно и системных. Кроме того, это не единственный шаг.

Я еще раз повторю, что изменение имен переменных не оказало влияния на размер файлов, так что оно абсолютно бесполезно. Имея же одну функцию для работы по событию (очевидную, как ее не назови), можно назвать ее хоть q — смысл не изменится. Тем не менее, чем короче имя, тем меньше размер, что представляет и академический, и практический интерес.

18.09.08 в 21:31 | Genn:

Говоря «чем короче имя, тем меньше размер» я имел в виду «чем короче имя используемых в ролике объектов, а не в коде, тем меньше размер». Symbol names matter! ;)

21.09.08 в 10:19 | WoRld_fRom_TeaRs:

Класс! Очень понравилось :)

4.10.08 в 8:11 | Nadinka22:

Хоть и пока не в “теме”, но решила покапать поглубже - интересно.

10.10.08 в 14:19 | Zhengo:

скажи как можно с тобой связаться, плиз, а то не нашел страницу “контакты”

7.12.08 в 21:37 | Len:

Завтра разошлю ссылку всем сотрудникам, тут прикольно

Оставить комментарий

Copyright © 2007 Genn
Сайт работает под управлением WP-турбийона.
Steve still jobs… I mean… jokes!
House M.D. s05 e01