Javascript.RU

Директива @define, удаление веток компилятором

Директива @define позволяет переопределить глобальную переменную (как правило, константу) в процессе компиляции. Компилятор заменит значение javascript-переменной на новое непосредственно в коде javascript.

А так как это константа, то сжатие продвинутым режимом позволяет тут же заинлайнить ее и оптимизировать соответствующие ветки if.

Например:

/** @define {number} */
var DEBUG_LEVEL = 5;

document.onclick = function() {
	if (DEBUG_LEVEL > 3) console.log("clicked")	
	alert("click")
}

Станет при переопределении DEBUG_LEVEL=2 и сжатии обычным режимом:

var DEBUG_LEVEL = 2;  // (замена!)

document.onclick = function() {
	if (DEBUG_LEVEL > 3) console.log("clicked")	
	alert("click")
}

А при сжатии продвинутым режимом:

document.onclick = function() {
	alert("click")
}

Как видно, переопределенная константа инлайнится, и лишние ветки кода удаляются. Это, разумеется, положительно влияет и на размер скрипта и на производительность.

Чтобы включить возможность переопределения, необходимо сделать аннотацию переменной вида:

/** @define {boolean} */
var myvar = 5

Для успешного определения @define должны соблюдаться следующие правила:

  1. Переменная должна быть глобальной и определена через var
  2. Тип переменной должен быть простейшим литеральным (строка, число, булево значение)

Кстати, имя переменной может быть любым, не обязательно БОЛЬШИМИ_БУКВАМИ.

Итак, в скрипте задана переопределяемая глобальная переменная . Следующий шаг - указание компилятору, на что ее заменять.

В документации описан флаг --define. Но на момент написания статьи он не работает, и вообще - его нет в исходных кодах.

Поэтому мы добавим свой флаг, как описано в статье про собственные флаги.

Флаг будет целочисленный.

Добавим его к описаниям флагов в (My)CompilerRunner:

@FlagSpec(help = "Debug level.")
public static final Flag<Integer> FLAG_debug_level = Flag.value(5);

Как видите, значение по умолчанию - 5. Это будет максимальный уровень отладки. Целочисленное значение выбрано из соображений удобства, можно было взять классический DEBUG/INFO/WARNING/...

Флаг добавлен. Теперь нужно из флага сделать установку компилятора на замену переменной.

Для этого дописываем соответствующую опцию в конец метода CompilerRunner#createOptions.
Добавление define производится одним из методов вида setDefineTo*, которые находятся в классе CompilerOptions.

Для целочисленного флага это будет setDefineToNumberLiteral :

options.setDefineToNumberLiteral("DEBUG_LEVEL", FLAG_debug_level.get());

Теперь после сборки ant'ом компилятор умеет распознавать новый флаг.
Код:

/** @define {number} */
var DEBUG_LEVEL = 5;

document.onclick = function() {
	if (DEBUG_LEVEL > 3) console.log("clicked")	
	alert("click")
}

Запуск компилятора:

java -jar compiler.jar --js debug.js --debug_level 3

Даст нам следующий код:

var DEBUG_LEVEL = 3;
document.onclick = function() {
  DEBUG_LEVEL > 3 && console.log("clicked");
  alert("click")
};

Как видите, переопределение произошло успешно. Однако, лишняя ветка кода не была убрана.

Это произошло из-за того, что в обычном режиме компилятор не имеет права заинлайнить глобальную переменную DEBUG_LEVEL.

Для этого его необходимо запустить в продвинутом режиме:

java -jar compiler.jar --js debug.js --compilation_level ADVANCED_OPTIMIZATIONS --debug_level 3

Результат компиляции:

document.onclick = function() {
	alert("click")
}

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

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

Например, в библиотеке Google Closure Library, в файле dom/dom.js есть настройки:

/**
 * @define {boolean} Whether we know at compile time that the browser is in
 * quirks mode.
 */
goog.dom.ASSUME_QUIRKS_MODE = false;


/**
 * @define {boolean} Whether we know at compile time that the browser is in
 * standards compliance mode.
 */
goog.dom.ASSUME_STANDARDS_MODE = false;

То есть, если мы знаем, что наш сайт работает в STANDARDS MODE (есть правильный DOCTYPE), то мы можем указать это компилятору, и он уберет из библиотеке лишние ветки кода, которые относятся к поддержке QUIRKS MODE.

Мы рассмотрели переопределение переменных при помощи аннотации @define и соответствующую недокументированую опцию компилятора.

Самое полезное применение, на мой взгляд - это существующая переменная COMPILED, значение которой при компиляции становится true и свой собственный LOG_LEVEL, который позволит автоматически вырезать ненужное логирование из production-кода.

Уже только это делает директиву @define весьма и весьма юзабельной.

Кстати, вот класс MyCompilerRunner с флагом и опцией:

package com.google.javascript.jscomp;

import com.google.common.flags.Flag;
import com.google.common.flags.FlagSpec;

import java.io.PrintStream;

public class MyCompilerRunner extends CompilerRunner {

    @FlagSpec(help = "Debug level.")
    public static final Flag<Integer> FLAG_debug_level = Flag.value(5);

    /* всевозможные конструкторы */
    public MyCompilerRunner(String[] args) {
        super(args);
    }

    public MyCompilerRunner(String[] args, PrintStream out, PrintStream err) {
        super(args, out, err);
    }

    /* изменить опции, в соответствие с новым флагом */
    @Override
    protected CompilerOptions createOptions() {

        CompilerOptions options = super.createOptions();
        options.setDefineToNumberLiteral("DEBUG_LEVEL", FLAG_debug_level.get());

        return options;
    }

    /* точка входа в компилятор */
    public static void main(String[] args) {
        (new MyCompilerRunner(args)).run();
    }

}

Автор: justicehwrknz807 (не зарегистрирован), дата: 10 января, 2022 - 10:37
#permalink

I am happy to find this post Very useful for me, as it contains lot of information. I Always prefer to read The Quality and glad I found this thing in you post. Thanks! https://www.tileinstallationtampafl.com/


Автор: Гость (не зарегистрирован), дата: 15 апреля, 2022 - 23:51
#permalink

Автор: Гость (не зарегистрирован), дата: 16 апреля, 2022 - 13:44
#permalink

Автор: Leonel Stanly (не зарегистрирован), дата: 19 сентября, 2022 - 01:37
#permalink

While you're scrolling through your feed, have you ever noticed that some posts have different fonts than others? Well, there's actually a tool for that! It's called Instagram Schrift, and it allows you to change the font of your Instagram posts.


Автор: MyrnaPaul (не зарегистрирован), дата: 3 октября, 2022 - 12:46
#permalink

The problems of life will be solved with the stickman fighter game, which is one of the popular new action games today.


Автор: Sun Flower (не зарегистрирован), дата: 14 декабря, 2022 - 11:45
#permalink

Please play the game at any of your free time. I was also recommended this game by my friends slope io


Автор: FLAGLE (не зарегистрирован), дата: 15 декабря, 2022 - 05:49
#permalink

There are a lot of fun, free games available on the internet these days, I usually play flagle because it's great for a lot of people, it feels so much fun when I guess the crossword correctly and get the highest score, are you ready to play?


Автор: Гость (не зарегистрирован), дата: 26 декабря, 2022 - 06:09
#permalink

For Retro Bowl success, it's important to have a well-rounded roster of players from all generations and positions. retro bowl


Автор: Natalie321 (не зарегистрирован), дата: 23 февраля, 2023 - 09:07
#permalink

I think it is well worth taking a few growdle minutes to read the insightful information you offer. Thank you for that.


Автор: Гость (не зарегистрирован), дата: 23 февраля, 2023 - 12:04
#permalink

Life is a fun and easy-to-play board game that can be enjoyed by two to six players. Collect the most money and life tile value to win this game! life the game


Автор: Гость (не зарегистрирован), дата: 3 апреля, 2023 - 07:46
#permalink

You can try to play redactle unlimited all you want, but the information that has been supplied is current and helpful. Very captivating!


Автор: Schriftarten.io (не зарегистрирован), дата: 24 мая, 2023 - 06:32
#permalink

Welcome to https://schriftarten.io/ - the ultimate font generator for anyone looking to add a unique, professional flair to their projects. Our wide selection of fonts allows you to pick out something special, and our user-friendly platform helps make the process effortless. Whether you’re searching for intricate calligraphy lettering, or something more contemporary with bold lines and modern symbols, Schriftarten.io has you covered.


Автор: joerieth (не зарегистрирован), дата: 14 июня, 2023 - 07:52
#permalink

A US judge refuses to permit Microsoft to acquire Activision. The development of shell shockers 2 might be hampered by this initiative.


Автор: Zoey Harris (не зарегистрирован), дата: 14 июня, 2023 - 12:14
#permalink

I feel great playing world of mario game so that's why i want to share it with you.


Автор: zelhdau (не зарегистрирован), дата: 20 июня, 2023 - 06:22
#permalink

Remember to always gamble rankdle responsibly and within your means. Good luck in your search for the perfect bookmaker!


Автор: deweysimon (не зарегистрирован), дата: 9 августа, 2023 - 06:52
#permalink

When the weather outside is hot, staying indoors and playing a fun game is the best option. As a firm recommendation, wordle today


Автор: JellyMin (не зарегистрирован), дата: 15 августа, 2023 - 18:16
#permalink

Как видите, переопределение произошло успешно. Однако, лишняя ветка кода не была убрана. drywall installation River Oaks


Автор: Гость (не зарегистрирован), дата: 22 сентября, 2023 - 06:02
#permalink

Challenge yourself with fnf game and see if you can conquer every round! The adrenaline rush you get from nailing those arrow keys in FNF is unbeatable!


Автор: antiguans2000, дата: 8 декабря, 2023 - 16:15
#permalink

Superfluous code branches are removed, and the overridden constant is inlined. fencing contractors christchurch


Автор: orianna (не зарегистрирован), дата: 10 января, 2024 - 07:14
#permalink

Amazing! The use of internal options and custom Buckshot Roulette flags in the Closure Inspector source code is so clean and organized.


Автор: Losudia (не зарегистрирован), дата: 18 января, 2024 - 11:25
#permalink

You will have to fight other eggs on diverse and interesting maps in shell shockers.


Автор: sarahly (не зарегистрирован), дата: 15 февраля, 2024 - 11:40
#permalink

This command is extremely effective. Bring benefits and save time for bob the robber


Автор: Гость (не зарегистрирован), дата: 18 марта, 2024 - 12:16
#permalink

The attention to detail in this post is commendable. Well-researched!


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

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
5 + 15 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum