Оптимизация Фронтенда. Часть 1. Почему Мне Не Нравится Слово Treeshaking Или Где Вебпак Вас Обманывает



Оптимизация фронтенда.
</p><p>
 Часть 1. Почему мне не нравится слово Treeshaking или где вебпак вас обманывает

Мы относимся к технологиям, которые используем как делать покупки на яндекс маркете.

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

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



Фон

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

Автор показывает, что Tree Shaking имеет гораздо больше возможностей для сжатия кода.

И в доказательство он высказывает несколько мыслей о рецептах пирогов и разбитых яйцах.

Ох уж эти метафоры! Эта идея (о тряске деревьев, а не о пироге и яйцах) была подхвачена командой разработчиков вебпака и стала официально поддерживаться с версии 2.0.

Проблема

Я бы не писал, если бы технология приносила хоть какой-то результат на реальных проектах.

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

Некоторые, конечно, догадываются и даже пишут статьи на Хабре .

Но людей, рассуждающих о преимуществах Tree-Shaking перед подсветкой мертвого кода в вебпаке, не меньше, по крайней мере, среди посетителей конференции и среди моих коллег.



Как это должно было работать?

Идея так же проста, как бак .

  1. Конструктор просматривает дерево модулей и помечает неиспользуемые импорты специальными комментариями.

    Так:

      
      
      
      
      
      
       

    .

    /* unused harmony export square */ function square(x) { return x * x;} .



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

  3. ВЫГОДА!


Когда это не работает?

Допустим, все как в документации.

Два файла index.js и Module.js

// index.js import {cube} from '.

/module' console.log(cube(x))



// module.js export function square(x) { return x * x; } export function cube(x) { return x * x * x; }

Если теперь запустить вебпак в режиме оптимизации и минификации, то все будет работать как положено.

( код )

webpack --optimize-minimize index.js out.js

А вот если в файл с модулями при наличии бабель-загрузчика добавить какой-нибудь, даже самый маленький класс с экспортом, то начинается ад. Класс попадет в окончательную сборку как функция, созданная Babel. ( код )

//module.js export function square(x) { return x * x; } export function cube(x) { return x * x * x; } export class MyClass { print(){ console.log('find me'); } }



Как это произошло?

Все дело в том, что UglifyJS боится выкинуть что-то ненужное.

Оно и понятно: лучше на пару сотен байт больше, просто чтобы не сломалось.

Итак, представьте, что UglifyJS получает на вход следующий код:

/* unused harmony export MyClass */ var MyClass = function () { function MyClass() { babelHelpers.classCallCheck(this, MyClass); } MyClass.prototype.turn = function print() { console.log('find me'); }; return MyClass; }();

MyClass после компиляции Babel каким-то образом сумел распознать себя как класс.

В целом, UglifyJS мало что знает о том, как команда Babel видит реализацию классов в ES5. Поэтому он сдается, оставляя этот неизвестный, неиспользованный позор в вашей финальной сборке.

В репозитории даже есть ошибка по этому поводу.

веб-пакет , и ребята обещают всё исправить в 4-я версия .

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

( сломанный пример , рабочий пример ).



Мораль

Так вот, купив вебпак, в том числе и для трэкшейка, я получил околонулевую выгоду в этом направлении.

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



Так что же нам теперь делать?

Во-первых, откажитесь от веб-пакета и используйте мой.

принципиально новый коллекционер , который лишен как этих недостатков, так и многих других.

Помимо классических сборок, он варит крафтовое пиво и готовит чиабатта-бургеры.

Извините, я не удержался.

А если серьезно, то есть очень простой способ исправить ситуацию: веб-пакету необходимо добавить специальную директиву

/*#__PURE__*/

, который бы сказал UglifyJS, что этого неизвестного монстра можно вырезать в виде функции.

Ох уж эти костыли.

И выглядит это примерно так:

/* unused harmony export MyClass */ var MyClass = /*#__PURE__*/ function () { function MyClass() { babelHelpers.classCallCheck(this, MyClass); } MyClass.prototype.turn = function print() { console.log('find me'); }; return MyClass; }();

Еще пара итераций и мы изобретем статическую типизацию ;) Рабочий пример Кстати, новая версия Babel 7 уже это делает. К сожалению, он все еще находится в стадии бета-тестирования, что, похоже, намекает на невозможность его использования прямо сейчас.

Но если вы смелы и решительны, вы можете попробовать обновиться.

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

О них я расскажу в следующей статье.

Возможно, они сэкономят чьи-то нервы и время.

И нам пора переходить к выводам.



выводы

  1. Сомневайтесь во всем.

    Проверьте информацию.

    Даже эта статья.

    Эта практика сэкономит вам много нервов и времени.

  2. Экосистема JavaScript иногда страдает от сбоев на стыке технологий.

    Здесь тоже из-за того, что Babel ничего не сообщил UglifyJS через вебпак о своем формате классов для ES5, произошло недоразумение.

    При этом в Babel это уже почти исправлено, о чем, конечно же, ребята из webpack не знают и хотят исправить в следующем релизе.

P.S. Напишите в комментариях, если вы тоже попались на удочку маркетологов и выбрали модные технологии вместо решения проблем.

Оптимизация фронтенда.

Часть 2 Теги: #webpack #JavaScript #treeshaking #Разработка сайтов #JavaScript #Оптимизация клиента

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.