Оптимизация Javascript с помощью Google Closure Compiler

    image
    Google открыла исходные коды нескольких инструментов, которые использовались их сотрудниками при разработке таких проектов как Google Docs, Google Maps и GMail.

    В числе этих инструментов имеется достаточно интересная штука, называемая Google Closure Compiler. Данная утилита минимизирует и оптимизирует javascript-код, за счет чего он начинает работать и загружаться быстрее.

    «Компилятор» можно скачать по ссылке closure-compiler.googlecode.com/files/compiler-latest.zip (примерно 3Мб), но для того чтобы посмотреть его в действии достаточно пройти по адресу closure-compiler.appspot.com.
    Перед Вами откроется окно, которое разделено на 2 части: слева Вы вводите свой код, а справа получаете результат. По умолчанию там уже будет функция Hello World
    image

    Нажмите кнопку «Compile» для того чтобы увидеть результат
    image
    Как видно из рисунка, этот простой пример «сжался» на 40.22%.

    Но можно попробовать сжать что-нибудь побольше. Для этого нажимаем кнопку «reset», в поле «Add a URL» вводим «habrahabr.ru/js/1257170514/tm/validation.js?revision=29» и нажимаем кнопки «Add» и «Compile»image

    Данный код «сжался» на 68.40%. Для того чтобы оценить степень оптимизации можно в поле «Add a URL» выбрать из выпадающего списка какую-нибудь известную библиотеку и посмотреть как она будет сжиматься.
    image

    Сейчас уже существует достаточно много оптимизаторов javascript кодов, но, как утверждается на сайте проекта, в большинстве случаев Closure Compile оптимизирует javascript лучше.

    Также Google открыл исходные коды ещё двух интересных проектов:
    Closure Library и Closure Templates
    Поделиться публикацией
    Комментарии 67
      0
      Интересно, чем же отличается от обычного обфускатора?
        +5
        Сжатие и обфускация это разное, да.
          –7
          Так что же, что? Не вижу разницы.
          0
          если судить по скриншотам, то наверное тем, что оптимизируется только код, а имена функций остаются такими же. обфускатор, вроде бы, все функции тоже «оптимизирует» переименовывая в a(), b(), etc. делая код совершенно нечитаемым
            0
            нет, это просто разные степени «оптимизации», включаются дополнительным параметром командной строки
              +4
              Поверьте, это сжатие. достаточно отформатировать код (чтобы не шел в одну строку) и все будет очень даже читабетельно.

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



              дальше конечно только хуже, начиная char и base64, заканчивая RSA, с использованием динамических элементов шифрования:



              вот примерно так, сорс код пытается себя защищать :) такие дела.
                +9
                я знаю людей, которые примерно так программируют, только в коде ещё намешаны php, sql и css
                  0
                  Первокурсники то? :)
                  0
                  ТССССС!!!

                  НЕ ВЫДАВАЙТЕ НАС!!!
              0
              правильный вопрос))
              хотя отличия скорее есть, но не думаю что существенные и сильно выигрывает по сравнению с другим подобными онлайн-сервисами
              хотя это все-таки продакшен-сервис…
              но подается это новость как-будто гугл сделал что координальное
              –4
              Ну надеемся скоро Google откроет исходный код еще нескольких своих интереснейших проектов, например GFS ;)
                +3
                Минимизация кода — понятно. А где тут заявленая оптимизация?
                  0
                  ну так короче имена переменных, меньше памяти и так далее
                    +6
                    хехе, уменьшение потребления памяти путём сокращения имён переменных % )
                      +5
                      ну не совсем)

                      рассмотрим это:
                      function hello(name) {
                        var code = 19;
                        var srt = 'dss';
                        alert('Hello, ' + name);
                      }
                      hello('New user');
                      

                      в результате получаем:
                        function hello(a){alert("Hello, "+a)}hello("New user");
                      

                      то есть как минимум под лишние переменные память не выделяется. Уже приятно. packer такого не делает.
                        0
                        интересно он проверяет выполнение внутри eval? :)
                          0
                          в факе по компилятору написано, если я правильно понял, что «ограничено» умеет.
                    +1
                    «Оптимизация размера»

                    не дописали… =)
                      0
                      единственный пример оптимизации, который я у них видел — function inlining: вызовы некоторых очень простых функций заменяются на их код, типа

                      (function(){ alert(123) })() заменится на alert(123)

                      на мой взгляд эффект от этого сомнительный

                      ещё в доках предлагается описывать в спецкомментариях тип каждой переменной, что теоретически даст «компилятору» возможность лучше оптимизировать код, но подтверждения этому я не нашёл
                        0
                        Ну вот например @nosideeffects аннотация скорее всего даст какой-нибудь эффект. Да и там много полезных других вещей, например, эта тулза граф выходов рисовать может. Практической ценности на первый взгляд нет, конечно :)
                        +1
                        The ADVANCED_OPTIMIZATIONS level goes beyond simple shortening of variable names in several ways, including:

                        * more aggressive renaming:

                        Compilation with SIMPLE_OPTIMIZATIONS only renames the note parameters of the displayNoteTitle() and unusedFunction() functions, because these are the only variables in the script that are local to a function. ADVANCED_OPTIMIZATIONS also renames the global variable flowerNote.

                        *dead code removal:

                        Compilation with ADVANCED_OPTIMIZATIONS removes the function unusedFunction() entirely, because it is never called in the code.

                        * function inlining:

                        Compilation with ADVANCED_OPTIMIZATIONS replaces the call to displayNoteTitle() with the single alert() that composes the function's body. This replacement of a function call with the function's body is known as «inlining». If the function were longer or more complicated, inlining it might change the behavior of the code, but the Closure Compiler determines that in this case inlining is safe and saves space. Compilation with ADVANCED_OPTIMIZATIONS also inlines constants and some variables when it determines that it can do so safely.
                          0
                          ну да, как я и написал, фактически кроме inlining оптимизации по скорости нет, а этот способ даёт выигрыш только на очень большом числе вызовов
                            –2
                            Опять же не более, чем уменьшение размера.
                              +1
                              Ну так в этом и фишка. У них там в факе вопрос примерно такой: «Есть ли какой-нибуть tradeoff между скоростью и размером файлов в выхлопе компилятора?» и они честно отвечают, что основная задача — уменьшить код, т.к. это увеличивает скорость загрузки страницы и всякое такое прочее. Ну и побочным эффектом _может_ стать небольшое увеличение производительности, т.к. «usually less code means faster code» как-то так.
                          0
                          Я конечно, понимаю что использование win1251 нынче не кашерно, но вот именно с ним у данного оптимизатора (тот что доступен через веб), наблюдаются проблемы (
                            0
                            хм, как обнаружилось:
                            function x () {
                            alert('привет');
                            }

                            получается на 50% больше чем до оптимизации )
                              0
                              они сами все не-ascii символы указывают в виде \uXXXX, и это полезно делать всем, чей код внезапно может оказаться загруженным в неюникодной кодировке
                              0
                              я так поняла, что утилита делает минимизацию javascript'a. А как она оптимизирует код?
                                +1
                                извините. не видела верхний комментарий.
                                0
                                compiler.jar не запускается… по-моему compiler-latest.zip поврежден
                                  0
                                  Туда можно добавить несколько js файлов и толза вернет один собранный =)
                                    0
                                    только надо сильно пошаманить, чтобы внешние файлы можно было безболезненно подключать. тот же скриптакулус хрен просто так подключишь, несмотря на все extern-ы и прочие хитрости, которые они там советуют.

                                    имхо, для существующей js-инфраструктуры не очень подходит эта штукенция.
                                    0
                                    Проверял в вебе

                                    Размер без сжатия: 137.92 КБ

                                    yuicompressor 2.4.2
                                    97.5 КБ (32.7 КБ после gzip)

                                    Google Closure Compiler (simple):
                                    97.1 КБ (31.8 КБ после gzip)

                                    Google Closure Compiler (advanced):
                                    79,4 КБ

                                    Но в simple режиме что-то с кодировкой, судя по комментам сверху это можно преодолеть, а вот js прогнанный через advanced mode вообще не заработал. Возможно дело в том, что я изначально слил несколько js файлов в один.

                                    Попробую его наверное :)
                                      0
                                      Если есть строковые ссылки на функции — они не находятся, в итоге функции оптимизируются как не использованние. Размер уменьшается, код не работает. Чтобы advanced работал нормально, нужно сделать дополнительные телодвижения: code.google.com/closure/compiler/docs/api-tutorial3.html#dangers
                                        0
                                        да, я смотрел, но jquery и несколько сторонних скриптов так переделывать — вот уж нет :)
                                      +9
                                      Так вот как получается та нечитабельная хренотень в скриптах гугла!.. :)
                                        0
                                        Когда б вы знали, из какого source
                                        Растут стихи, не ведая стыда,
                                        Как желтый одуванчик у забора,
                                        Как лопухи и лебеда.
                                        +1
                                        да, прогонял на jQuery — выигрыш после gzip еще 5%
                                          0
                                          jquery-1.3.2.min.js сжался еще на 12.92%. Правда работоспособность не проверял…
                                            0
                                            я его и гонял. 5% — работоспособность проверена
                                            +1
                                            Можно ждать включение этого инструмента в Web Optimizer?
                                              +1
                                              да, там лицензия Apache — свободная перепродажа и распространение.
                                              Но будет только в Pro-версии, больно тяжелый инструмент (в 4 раза больше самого текущего Web Optimizer).
                                            0
                                            Что если при использовании подобных методов сжатия, уже в рабочем коде обнаруживается ошибка?
                                            тогда нужно исправить, потом занового сжать и только потомы выкладывать на сервер. Может кто-нибудь подскажет как можно оптимизировать этот процесс? может быть можно производить такое сжатие на лету?
                                              0
                                              тяжеловато такое будет на лету делать.
                                              У нас минимизация делается при nightly build'e и все ошибки сборки высылаются скриптом на емейл.
                                                +1
                                                В своём проекте я держу каждый JS для отдельного модуля в отдельном файле. И при изменении одного из них (Определяет скрипт с некоторой периодичностью) собираю все файлы в один, прогоняю через yuicompressor и копирую на live. Тжс и с CSS
                                                  0
                                                  в частности для django это решается очень просто через django-compress, думаю подобные инструменты есть и для других фреймворков
                                                    0
                                                    соберите соотв. систему для перехода от delevoping-версии к продукту
                                                    мы, например, начинали с подвешивания хука на свн
                                                      0
                                                      Пишите скрипты для размещения. Или юзайте готовые решения, например, Capistrano
                                                        0
                                                        Можно делать сжатие на лету с помощью их API: code.google.com/intl/ru/closure/compiler/docs/gettingstarted_api.html
                                                        +1
                                                        Хм, почему все while'ы заменяются на for'ы :)
                                                          +2
                                                          for — 3 буквы, while — целых 5 ; )
                                                            +3
                                                            но у for еще две точки с запятой
                                                              –2
                                                              Но for медленнее while
                                                            0
                                                            Спасибо за ссылку — либа сжала код на 4% лучше YUI compressor.
                                                              +2
                                                              Жаль с русским языком не дружит, если написать например:
                                                              if (document.getElementById('comment_content_'+idFeedback)) {
                                                              document.getElementById('comment_content_'+idFeedback).innerHTML='комментарий был удален';
                                                              }

                                                              результатом будет:
                                                                +1
                                                                хм… отправилось раньше чем дописал…
                                                                if(document.getElementById("comment_content_"+idFeedback))document.getElementById("comment_content_"+idFeedback).innerHTML='\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0435\u043d';
                                                                  +1
                                                                  за то теперь этот код будет работать на странице с любой кодировкой :)
                                                                0
                                                                а у меня при advanced optimization показывает пустую строку
                                                                Compiled Size: 0 bytes
                                                                  +1
                                                                  Это идеально оптимизированный код!
                                                                  0
                                                                  externs правильно определили?
                                                                    0
                                                                    Я слышал про архиватор, который всё в один байт архивирует.
                                                                    0
                                                                    Original Size: 2.87KB (1.11KB gzipped)
                                                                    Compiled Size: 0 bytes (20 bytes gzipped)
                                                                    Saved 100.00% off the original size (98.25% off the gzipped size)
                                                                      0
                                                                      Любителям ужимать код js хочу заметить, что для того, что бы код был максимально сжимаемым, нужно следовать рекомендациям ADsafe.
                                                                      +1
                                                                      github.com/troolee/jscc Вот начал набрасывать тулз. Описывается «проект» с помощью yaml. Что-то типа такого:

                                                                      api_version: 1
                                                                      source_dir: src
                                                                      output_dir: js                            
                                                                      default_compilation_level: simple
                                                                      
                                                                      targets:
                                                                        output_filename-1.js:
                                                                          compilation_level: advanced
                                                                          sources:                            
                                                                            - input-1.1.js
                                                                            - input-1.2.js
                                                                            - input-1.3.js
                                                                      
                                                                        output_filename-2.js:
                                                                          sources:                            
                                                                            - input-2.1.js
                                                                            - input-2.2.js
                                                                      


                                                                      На выходе сжатый кложуром яваскрипт. Есть режим --watch: тулза мониторит изменения исходников и автоматом пережимает. Она еще в «зачаточном» состоянии, сыроватая, но вроде как работает.

                                                                      Зависимости: closure, python, pyyaml. Пишется/проверяется под ubuntu.

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

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