• Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +3
    надо было мне сказать, что ты будешь этот конкретный пост переводить, я бы justboris сказал, что кто-то уже переводит. а так ты меня спросил, можно ли статьи переводить и репостить — я сказал можно; но у меня это как-то в голове не сложилось 1+1, что ты эту конкретную статью будешь переводить. извиняюсь.
  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +2
    JIT умеет инлайнить функции, но вызов функции должен быть мономорфным — те вы должны вызывать всегда одну и ту же функцию из данного места.
  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +1
    Да ну хотя бы эта картинка

    Эта картинка для объяснения "почему". Можно без объяснения "почему", просто сказать "делай как я! будет счастье" (и между прочим говорили начиная с 2010 года, я сам помнится говорил пару раз).


    Тут надо повторится, что SpiderMonkey от такого не страдает и V8-товцы обещают подумать и починить.


    Вот этот вывод например требует нехило так разбираться в предмете.

    С этим я в принципе согласен. Нужно иметь хоть какой-то опыт чтения профилей, с учетом низкоуровневых деталей. Однако у меня есть такой пример: когда было дело и я общался с нодовцами по поводу производительности, то они обычно достаточно быстро просекали, как читать профили.


    Я, кстати, об этом и в посте написал — что было бы очень хорошо если бы V8 умела все эти вещи объяснять понятным языком. Например, не KeyedLoadIC_Megamorphic, а что-нибудь более понятное человеку менее углубленному в детали реализации.

  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +6

    Ну это все фантазии, к сожалению, из разряда вечерних мечтаний за чаркой среди единоверов. "Ах вот бы было хорошо, если бы!"


    Я бы может быть тоже хотел проснутся одним морозным утром и обнаружить, что JS скукожился. Но одним Rustом тут дело не решить, к сожалению. Нужен глобальный выбор — на чем хочешь, на том и пиши, а для этого нужен вменяемый compilation target. (… и все равно в конце-то внезапно обнаружится, что писать на все том же ЖС будут порядочно.)

  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    0

    Я не пытаюсь Rust отодвинуть: у меня две причины, одна корыстная, одна не очень.


    Во-первых, причина простая: я не понимаю зачем писать такие вещи на Rust, если можно на JS (который я не особо-то и люблю). Ну пусть бы написали что-то осмысленное и большое, но такую мелкую штуку смысла на мой взгляд не имеет никакого. Только из любви к языку, ну пусть тогда так и пишут — а не наводят тень на плетень.


    Во-вторых, причина корыстная: в WASM компилировать по нормальному можно только языки типа C/C++/Rust, для всего остального надо за собой тащить собственный рантайм — GC, JIT, etc — скомпилированный в тот же WASM. Я считаю, что это неоправданные издержки. Поэтому получатся, что JS до сих пор единственный нормальный целевой язык для компиляции высокоуровневых языков (хотя он тоже не сахар, но хотя бы свой JIT/GC/exceptions, тащить не надо). А значит нужно поддерживать огонь под JS производительностью со всех возможных направлений.


    (Что инетерсно тот товарищ, который source-map делает он даже написал собственный аллокатор памяти для WASM — потому что встроенный в Rust был слишком большой… ну у меня даже слов нет.)

  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    0

    Да, и это работало. А вот попробуйте WASM в текстовом редакторе поправить. Еще та черная магия!

  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +2
  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +1
    Не говоря о том, каким образом получена эта информация — копание в ассемблерных листингах явно не моя сильная сторона, как думаю, и многих других разработчиков, особенно таких высокоуровневых языков вроде JS.

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


    и для меня некоторые улучшения просто черная магия.

    Какие именно? Вот допустим пишете вы бэкэнд на C# или Java — для вас мономорфный/полиморфный код имеет точно такое же значение с точки зрения перформанса! Это никакая не черная магия.


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

    Я потратил ~2 часа утром на диване перед работой, чтобы оптимизировать код. А затем я потратил гораздо больше времени, чтобы написать длинный пост с пошаговым объяснением.


    Глянул, там говорится, что для компиляции rust нужно поставить компилятор rust

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

  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +3
    Я на всякий случай напомню, что авторы библиотеки изначально так и делали.

    Нет, ничего они так не делали изначально. Максимум они сделали:


    • хак с кэшированием (без которого на самом-то деле быстрее)
    • сделали свою собственную быструю сортировку

    Все. Никаких других оптимизаций они не делали. Никаких особых проблем с поддержкой и гибкостью от двух этих изменений у них не было.


    Очень рекомендую прочитать статью-ответ, ссылку на которую уже дали выше.

    Я читал ответ, и я с ним не до конца согласен. (Если что, я это одна из двух сторон).

  • Возможно, вам не нужен Rust, чтобы ускорить ваш JS
    +2

    Все оптимизации достаточно примитивны — к тому же с течением времени необходимость в оптимизациях из группы №3 должна сойти на нет.


    Единственная действительно спорная оптимзация состоит в использовании typed arrays руками — потому что она делает код действительно сложно читаемым. Но опять же — эту проблему можно решить просто добавив правильные фичи в JavaScript — а не приглашать людей переписывать их код на Rust.


    Да и почему предполагется, что цена поддержки Rust и WASM нулевая? Это совершенно отдельный язык и экосистема! Автор Вы посмотрите на список вещей, которые нужно установить, чтобы обновить ту часть source-map, которая написана на Rust.

  • Анонс Dart 2.0: Оптимизированный для клиентской разработки
    +2
    Вот в том-то и дело, что Dart 1 никогда и не был задизайнен, как статически типизированный язык. Все странности языка перестают быть странностями, если это знать и воспринимать его именно таким образом.
  • Анонс Dart 2.0: Оптимизированный для клиентской разработки
    +2

    Решетка (lattice) — это такая алгебраическая структура.

  • Анонс Dart 2.0: Оптимизированный для клиентской разработки
    +2

    Решение становится гораздо менее странным, если воспринимать Dart 1, как динамически типизированный язык. Допустим приехал вам JSON [1, 2, 3], вообще-то он List<dynamic>, но вы допустим как-то знаете, что он на самом-то деле List<int>. В Dart 1 вы его спокойно можете передать куда-нибудь, где ожидают List<int>. В Dart 2 вам его сначала надо бы преобразовать, например через list.cast<int>()

  • Анонс Dart 2.0: Оптимизированный для клиентской разработки
    +2

    В Dart 1 ["1", "2"] имеет тип List<dynamic>, а List<dynamic> является подтипом List<int>. Это было сделано, чтобы можно было легко смешивать полностью динамический и типизированный код. dynamic был одновременно и top и bottom решетки типов, т.е. в коде внизу оба присваивания были валидны и в runtime и в compile time


    List<dynamic> a;
    List<int> b;
    
    a = <int>[]; 
    b = <dynamic>[];  
  • Анонс Dart 2.0: Оптимизированный для клиентской разработки
    +3

    В Dart 2 состоит из следующих компонентов:


    • серьезно переработанная система типов (strong mode, которая включает в себя generic methods, локальный вывод типов, изменения в семантике dynamic и void);
    • int больше не является целым числом произвольного размера (aka bigint), а ограничен 64-битами;
    • мелкие изменения в языке (optional new/const, async functions start synchronously);
    • большое число новых методов в core библиотеках (см CHANGELOG.md);
    • важное инфраструктурное изменение: введение Общего Фронтенда и Kernel, унифицированного формата представления и сериализации Dart AST — все тулы будут использовать один и тот же парсер Dart написанный на Dartе, даже VM.
  • Анонс Dart 2.0: Оптимизированный для клиентской разработки
    +2
    Когда запилят eval? Ведь существуют не только мобильные приложения и фротенды. Так, из-за этого отсутствует вменяемый repl в Dart SDK.

    eval можно через service протокол делать. Есть сторонние прототипы replов на основе этого.


    Добавят ли возможность ждать завершения выполнения async кода в sync функциях?

    По нормальному это добавлять тяжко (по разным техническим причинам), но в 2.0 добавили dart:cli с методом waitFor, который синхронно ждет завершения Future. Я думаю после 2.0 будем смотреть на "многопоточность" и асинхронность в целом более пристально, потому что людям хочется чего-то более вменяемого особенно за пределами браузера.


    В stagehand не хватает шаблона бекенд+фронтенд

    Можно в stagehand репе сделать баг на эту тему или там нарисовать PR :)

  • Чем полезен мономорфизм?
    +2
    Если посмотреть на код, который V8 делает для Typed и Monorphic бенчмарков, то оказывается, что он один и тот же. А производительность почему-то разная. А если переписать код

    // Pregenerate objects
    for (let i = 0; i < n; i++) {
      typed[i] = new Type(i);
    }
    
    for (let i = 0; i < n; i++) {
      poly[i] = {};
      poly[i]["k" + i] = null;
      poly[i].x = i;
    }
    
    for (let i = 0; i < n; i++) {
        mono[i] = {
            x: i,
            n: i, // Add n to balance memory usage
        };
    }
    


    то на моей машине внезапно все выравнивается, что намекает на какие-то мистические источники разницы.
  • Чем полезен мономорфизм?
    +2
    На самом деле ваш мегаморфный совсем отнюдь не мегаморфный, потому что в массиве poly встречаются объекты всего двух разных скрытых классов: с быстрыми элементами и с разреженными.

    // запускать с --allow-natives-syntax для доступа к %HaveSameMap
    let maps = [poly[0]];
    for (let i = 1; i < poly.length; i++) {
      let found = false;
      for (let o of maps) {
        if (%HaveSameMap(o, poly[i])) {
            found = true;
            break;
        }
      }
    
      if (!found) maps.push(poly[i]);
    }
    console.log(maps.length);  // напечает 2
    


    Происходит это потому, что V8 отделяет числовые свойства (т.е. свойствами с именами "0", "1", "2", ...) от других свойств. Сделано это для ускорения работы масивов.

    Вам нужно написать что-нибудь типа poly[i]["k" + i] = null; для создания полноценного мегаморфизма.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    0
    Если мы хотим оптимизировать

    function f(x) {
      return x.f() // (*)
    }
    
    f(a);
    f(b);
    


    то V8 спотыкается о то, что она при отслеживании метаструктуры рассматривает функции как нечто неделимое, т.е. она будет считать, что вызов в точке (*) полиморфный. А если бы она учитывала, что функция это тело+контекст, то было бы лучше.

    Чинится очень просто: отказом от использования замыканий таким образом на горячих путях.

    function Classic(x) {
      this.x = x;
    }
    
    Classic.prototype.f = function () { return this.x; }
    
    function make(x) {
      return new Classic(x);
    }
    var a = make(0), b = make(1);


    Но это только один пример…

    Можно рассмотреть полиморфизм другого толка:

    function A() { this.x = "a"; this.a = 0; }
    function B() { this.x = "b"; this.b = 0; }
    
    var a = new A(), b = new B();
    
    function use(o) {
      return o.x;
    }
    
    use(a);
    use(b);
    


    Как скомпилировать use(o) во что-то умнее чем (псевдокод):

    function use(o) {
      if (o.hiddenClass === ClassA) {
        return o.x  // load from some fixed offset
      } else if (o.hiddenClass === ClassB) {
        return o.x  // load from some fixed offset
      } else {
        return /* either generic load or deopt */
      }
    }
    


    вопрос открытый
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    0
    Полиморфный код можно, конечно, компилировать, но это отнюдь не так просто, как вам кажется — если хочется добиться, действительно быстрого вызова методов. Это только в С++ у вас есть простые явные vtable-s и все просто, уже в Java начинаются всякие интересности если хочется сделать быструю реализацию интерфейсных вызовов (поищите в интернете статьи о реализации invokeinterface).

    большинство объектных структур будут вполне статисческими


    Это действительно так (хотя и здесь есть свои тонкости). Однако интерес тут представляет не сами объекты, а то, что с ними происходит… Для оптимизации методов, которые работают с этими объектами надо видеть статичность статичность метаструктуры, если можно так выразится. Выше в тексте статьи я приводил уже пример с

    function make(x) {
      return { f: function () { return x } }
    }
    var a = make(0), b = make(1);
    


    здесь не всякая VM может увидеть, что a и b имеют одинаковую метаструктуру — V8, например, не может.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    0
    Когда я говорю «насколько Facebook/Inbox/etc выигрывает», я как раз и имею ввиду «выигрывает по производительности», т.е. становится быстрее.

    С кодом всяких разных web-приложений все очень не просто — много полиморфизма, сложно оптимизировать, классические оптимизации рассчитанные на мономорфный код часто не окупаются.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    0
    вопрос о том, насколько Facebook/Inbox/etc выигрывает от того, что его код оптимизировали, решается отнюдь не всегда в пользу оптимизаций :)

    Ну а скоро и WebAssembly подъедет.


    и люди сразу перепишут UI Facebook на С++ вместо JS :)
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    +3
    Он утверждал, что смысл const это просто заменить данный идентификатор значением константы.


    Разумеется в JavaScript семантика у const отнюдь не такая. Самый наглядный пример того, что это все-таки неизменяемая привязка переменной к значению:

    (function () {
      console.log(f()); // prints <?>
      const X = '<!>';
      console.log(f());  // prints <!>
    
      function f() {
        try {
          return X;
        } catch (e) {
          return '<?>'
        }
      }
    })();
    


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

    V8 не использует, к сожалению. А JSC, например, использует. Код

    const X = 10;
    function bar() { return X * X }
    


    компилируется в return 100 по сути дела
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    +1
    В JS скорость парсинга одинаково важна как и скорость исполнения.


    Да скорость парсинга важна. Только ведь скорость парсинга тут вообще сбоку припёка — наличие, отсутствие оптимизирующего компилятора не влияет на нее.

    Оптимизатор чаще всего сидит в отдельном потоке и оптимизирует только горячий код, как раз из соображения, что затраты на оптимизацию должны окупаться.

    Конечно, не все так просто. Оптимизации могут полагаться на разного рода информацию собранную во время неоптимизированного исполнения — поэтому нужно так реализовывать сбор этой информации, чтобы производительность не страдала. Можете быть уверены — разработчики JS VMs все это стараются учесть и найти баланс между пиковой производительностью и startup.

    Т.е. путь того же Python — простой bytecode interpreter + удобная возможность встраивания native (или тех же bytecodes близких к native) для функций которым нужен CPU на 100%.


    Python — это очень странный пример. Люди ведь совсем даже не поголовно довольны его производительностью — существует целый ряд различных компляторов/реализаций, которые стараются решить проблему производительности. Начиная от Cython и заканчивая PyPy. DropBox вот тоже свой собственный JIT пилит.

    А так… создавать чисто интерпретирумый язык по своей изначальной природе


    Так уж сложилось, что люди которые JavaScript создали, и люди, которые «героически преодолевают его интерпретируемость», это совершенно разные люди.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    +2
    В таких случая можно баги файлить на GitHub или посылать мне описания непонятных деоптимизаций. Я разьясню деоптимизацию — и куда-нибудь запишу ее как пример для будущих поколений.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    +1
    В WASM мне не нравится то, что они не поддерживают ничего, что сделало бы этот самый WASM для меня полезным. Меня не интересует возможность запускать C++ браузере. Меня интересует возможность запускать динамические языки в браузере отличные по семантике от JavaScript. Причем я хочу это делать с минимальными издержками. Например, я не хочу компилировать мой написанный на C++ GC в WASM — я хочу полагаться на GC, который уже в браузере есть… при этом, кстати, GC не так-то и просто скомпилировать, потому что я хочу ходить по стеку в поисках корней, а WASM такого не позволяет. Аналогично, я не хочу писать свой JIT — я хочу полагаться на JIT, который в браузере есть — со всеми его мощьными фичами типа адаптивной спекулятивной оптимизации.

    Поэтому от WASM я впервую очередь жду таких фич как интеграция с GC и JIT.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    +5
    Понятия не имею. Меня про asm.js вообще бесполезно спрашивать, я считаю, что это совершенно бесполезная (или даже вредная) «технология» и мир без нее будет лучше.

    rumkin внизу правильно замечает, что на замену asm.js пришел WASM… Я, впрочем, не большой фанат WASM в его текущей форме.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    +6
    Я не большой поклонник компиляции C++ в JS. Если WebAssembly получит распространение и поддержку во всех браузерах, то emscripten станет не нужен, потому что для clang есть уже экспериментальный backend, который умеет выдавать WebAssembly.

    Вопрос нужен ли нам WebAssembly я оставлю за рамками — пусть на него отвечают те, кто этим WebAssembly занимаются.
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    0
    Смысл в глубоких оптимизациях JS очень простой — люди пишут JS-код, надо чтобы он исполнялся эффективно.

    Если бы люди JS не писали, то его никто бы и не оптимизировал.

    А так выбора нет :)

  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    0
    Для разных машин существуют разные флаги — чтобы посмотреть на сгенерированный код. Тул IRHydra, который я написал, позволяет в более-менее удобоваримом виде изучать информацию, которую умеет дампить V8-овый Crankshaft. Что-то мне подсказывает, что и для других машин есть подобные способы, но разрабочики их не афишируют :)
  • Что браузеры делают с вашим JavaScript-кодом: об оптимизациях в JS-движках на примере V8
    +4
    На русском у меня есть, но мало

    Из более-менее свежего: http://mrale.ph/blog/2015/04/12/jsunderhood.html

    Из старинного есть:

    http://www.youtube.com/watch?v=tCG0aPNvkTs
    http://s3.mrale.ph/TechForum2012.pdf
  • Почему JavaScript работает быстрее, чем С++?
    +4
    Но ведь именно из-за поддержки этих фич, иначе устроен процессинг


    Отнюдь. Различия между re2 и irregexp действительно фундаментальные — но они отнюдь не из-за поддержки этих фич.

    Вот, например, lookbehind в irregexp сделали недавно и никакой особой заморочки с этим не было.

    Для простых регекспов из этого бенчмарка основное преимущество V8 состоит в том, что irregexp транслирует регулярные выражения в машинный код, а не исполняет их на «интерпретаторе», как многие другие regexp движки.

    Ну тут должно быть просто


    На самом деле нет. Вот что на это отвечает Russ Cox (автор re2)

    The lack of generalized assertions, like the lack of backreferences,
    is not a statement on our part about regular expression style. It is
    a consequence of not knowing how to implement them efficiently. If
    you can implement them while preserving the guarantees made by the
    current package regexp, namely that it makes a single scan over the
    input and runs in O(n) time, then I would be happy to review and
    approve that CL. However, I have pondered how to do this for five
    years, off and on, and gotten nowhere.


    https://groups.google.com/d/msg/golang-nuts/7qgSDWPIh_E/OHTAm4wRZL0J

    Иными словами в re2 выбраны и реализованы только те фичи, которые можно эффективно исполнять гарантируя линейную сложность, без катастрофического отката

    А вот что вы имеете в виду под zero-width positive lookahead? Ведь любые lookahead и lookbehind это zero-width match?


    Они так просто часто называются.

    Кстати, lookbehind (?<=re) re2 тоже не поддерживает, если верить документации :)
  • Почему JavaScript работает быстрее, чем С++?
    +3
    lookbehind, atomic groups, possessive quantifiers


    Ни одна из этих фич в regex dna не используется.

    в V8 это встроенная имплементация с довольно урезаным функционалом


    Имплементация V8 — это полноценная имплементация JS RegExp. JavaScriptовые регулярные выражения действительно не поддерживают разные фичи, которые поддерживает re2, но обратное тоже верно — например: JS поддерживает zero-width positive lookahead (?=...) и backreferences \n, а re2 — нет.
  • Тонкости Javascript/Node.js. Увеличиваем производительность в десятки раз
    +4
    Нельзя делать выводы на основе простых измерений, надо хотя бы профилировать и пытаться понять, что же на самом-то деле происходит внутри. Иначе получаются неправильные выводы.

    Дело здесь в следующем — создание функций, которые содержат в себе литералы (например, array literal или там object literal), это более тяжелая операция по сравнению с созданием функций, которые в себе литералов не содержат.

    Если взять и просто сравнить два профиля, то все тайное становится явным

    function find(val){
        function index (value) {
            return [1, 2, 3].indexOf(value);
        }
    
        return index(val);
    }

        8.29%  67  | LazyCompile:*InnerArrayIndexOf native array.js:1020
    *   7.67%  62  | v8::internal::JSFunction::set_literals
    *   7.05%  57  | v8::internal::Factory::NewFunctionFromSharedFunctionInfo
    *   5.81%  47  | v8::internal::Factory::NewFunction
    *   4.58%  37  | v8::internal::Factory::New<v8::internal::JSFunction
    *   4.33%  35  | v8::internal::Runtime_NewClosure
        4.21%  34  | Stub:FastCloneShallowArrayStub
        4.08%  33  | v8::internal::Heap::AllocateRaw
        3.34%  27  | LazyCompile:~index test.js:2
    *   3.34%  27  | v8::internal::Factory::NewFunctionFromSharedFunctionInfo
        3.34%  27  | Builtin:ArgumentsAdaptorTrampoline
        3.09%  25  | v8::internal::Heap::Allocate
    *   3.09%  25  | v8::internal::SharedFunctionInfo::SearchOptimizedCodeMap    
    

    function foo() {
      return [1, 2, 3];
    }
    
    function find(val){
        function index (value) {
            return foo().indexOf(value);
        }
    
        return index(val);
    }

       13.58%  58  | LazyCompile:*InnerArrayIndexOf native array.js:1020
        9.82%  42  | Builtin:ArgumentsAdaptorTrampoline
        7.49%  32  | LazyCompile:~index test1.js:6
        7.01%  30  | LoadIC:A load IC from the snapshot
    *   6.08%  26  | Stub:FastNewClosureStub
        5.62%  24  | Builtin:CallFunction_ReceiverIsNullOrUndefined
        3.74%  16  | LazyCompile:*foo test1.js:1
        3.51%  15  | Builtin:Call_ReceiverIsNullOrUndefined
        3.51%  15  | LazyCompile:*indexOf native array.js:1065        
    

    В первом случае мы ходим много в среду исполнения и там занимаемся всякой тяжелой и малополезной работой (например, клонированием массива литералов привязанного к замыканию), а во втором случае мы быстренько создаем замыкание с помощью FastNewClosureStub. Вот отсюда и основная разница.
  • Dart для всего веба
    0
    Достаточно странный вопрос, я где-то сказал, что «для этого»? Вменяемые библиотеки (включая работу с DOM) — это просто одно из его достоинств, а отнюдь не причина существования.

    В таком ключе и я мог бы спросить: а что для этого нужно полифиллить Array.from и вообще компилировать мой код каким-нибудь babel.js? Оказывается да, нужно таки. Потому что ES6 в настоящий момент тоже язык отдельный от того, что поддерживается браузерами.
  • Dart для всего веба
    +1
    Скорее «почти так», чем «именно так»: Array.from(document.querySelectorAll(".xyz"), el => el.value), потому что NodeList не является Array и как следствие не «умеет» map.
  • Dart для всего веба
    +3
    Часть этих вещей выполняется во время исполнения, компилятор dart2js выкидывает, что может. Если их не исполнять, то другой язык получается.

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

    Голому Hello World особо «рантайма» не нужно, там только прибавляется кусочек который (лениво) инстанцирует классы.

    Основная часть того, что воспринимается как runtime на самом деле в реальных проектах приходит из dart:html. Это библиотека, которая оборачивает DOM и реализует всякие полезные методы, чтобы вы могли писать

    document.querySelectorAll(".xyz").map((el) => el.value) или el.onClick.listen((e) { /* ... */ })

    вместо голого JSовго [].slice.call(document.querySelectorAll(".xyz")).map(function (el) { return el.value }) и el.addEventListener("click", function () {}), т.е. в некотором смысле dart:html это такая специально заточеная для Dart jQuery.

    Компилятор старается выкинуть все что можно, но он же не знает, что там querySelector вернет — поэтому остается всякий потенциально неиспользуемый код. Сравнивать этот «рантайм» нужно, конечно же, не с голым JS, а с размером всех тех либ которые вы будете использовать в своем коде (jQuery там или lodash).
  • Dart для всего веба
    0
    В виде плагина его не добавишь, потому что PPAPI не дает сделать легковесную тесную интеграцию с DOM.
  • Dart для всего веба
    +9
    Если вы посмотрите на Dart, то обнаружите, что он не только добавляет, но и убирает.

    Семантически Dart достаточно отличается от JavaScript объектной моделью. Вместо концепции «любой объект это словарь с прототипом», в Dart обычные классы с фиксированной структурой. В JavaScript вы читаете свойство, которого нет, и получаете undefined, в Dart вы получаете исключение. В JS вы складываете null + 1 получаете 1 (или undefined + 1 получаете NaN), в Dart вы получаете опять же исключение (и нет никакого undefined). Иными словами то «что не хватает в TS, а есть в dart также» — это в некотром смысле отрицательная величина, потому что Dart упрощает семантику и убирает те части JS, которые скажем так мешают вам поймать ошибку в коде как можно раньше.

    Конечно же, Dart не только убирает, но и довавляет. Например, в Dart можно переопределить операторы + или допустим [], или каждый класс может иметь метод noSuchMethod, который позволяет динамически регировать на вызов несуществующих методов и менять поведение объекта (можно, например, легко написать proxy объект на основе этого метода).

    Плюс Dart это не только язык, это еще и платформа с библиотеками спроектированными так, чтобы хорошо работать с его семантикой. В TypeScript библиотек вообще нет, люди просто .d.ts декларациями к тому, что есть в JavaScript.
  • Dart для всего веба
    +1
    Никак не связанна. Oilpan вообще особо никак не связан был с Dart (хотя и существовали некоторые теоретические предположения о том, что он может облегчить интеграцию Dart и Blink в вопросах GC).

    Dart не будут интегрировать в стандартной сборке, но другие варианты какие-нибудь останутся (за исключением Dartium)?


    Не совсем понятен вопрос. Существует всего один Chrome, поэтому не ясно о каких вариантах идет речь.

    Dartium останется, потому что пока это единственный способ гарантировать быстрый edit-refresh цикл разработки.