Что посеешь, то и пожмешь
или как уменьшить ваш javascript bundle

Алексей Золотых, Wrike

2 вывода

  • Бекенд != Фронтенд
  • Нужно понимать как все устроено

2 вывода

  • Бекенд != Фронтенд
  • Нужно понимать как все устроено

left-pad

holy wars

Left-pad

Веб-разработчик Азер Кочулу (Azer Koçulu), автор более 250 модулей для Node.js, попал в неприятную ситуацию. В своём блоге он пишет, что несколько недель назад получил письмо от юриста компании Kik (мессенджер) с требованием отозвать модуль с аналогичным названием kik из пакетного менеджера NPM (Node Package Manager).

Программист отказался, тогда юрист обратился напрямую в NPM, и администрация проекта удовлетворила его требование, сменив владельца kik без разрешения автора.

Азер Кочулу был крайне недоволен этим. Настолько недоволен, что решил в ответ «освободить» (то есть отозвать) все свои модули — более 250 модулей NPM. К сожалению, среди них оказался и left-pad — маленький модуль из 11 строк кода на JavaScript. Он используется при установке зависимостей между пакетами через NPM, в том числе в Node.js, JavaScript-транскомпиляторе Babel и огромном количестве других билдов. Только за прошлый месяц left-pad скачали 2 486 696 с сервера NPM, по их статистике.

Код left-pad показан ниже. Он просто заполняет левую часть строки нулями или пробелами.

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

Чтобы в экстренном порядке исправить ситуацию, технический директор и сооснователь NPM Лори Восс (Laurie Voss) пошёл беспрецедентный шаг (так он назвал его в твиттере) и, «учитывая серьёзность и распространённость проблемы», отменил отзыв модуля. Была опубликована старая версия модуля, аналогичная последней.

Сам Азер Кочулу считает, что администрация NPM берёт на себя слишком много полномочий. Он верит в силу движения Open Source и призывает создать «по-настоящему свободную альтернативу NPM». Азер просит прощения у всех веб-разработчиков, кто пострадал в результате его действий. Модуль Kik и другие он выложил на Github.

Hello world!

Angular


Hello world!

Spring boot (Java)


    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }
          

Минутка тро-ло-ло

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
</body>
          

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
</body>
          

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
</body>
          

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

С чего все началось


<body>
  <script src="jquery.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

Меньше файлов → меньше изжержки на сеть


<body>
  <script src="bundle.js"></script>
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.js"></script>
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.min.js"></script>
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.min.js"></script>
  <!--Плагины и код-->
  <!--Еще больше плагинов и кода-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.min.js"></script>
  <!--Backbone классы-->
  <!--Еще больше классов-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.min.js"></script>
  <!--Angular классы-->
  <!--Еще больше г;вна и палок-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.min.js"></script>
  <!--React компоненты-->
  <!--Еще больше преферанса и поэтес-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

Браузер не оценить читаемость кода


<body>
  <script src="bundle.min.js"></script>
  <!--Vue js компоненты-->
  <!--Еще больше крафтового пива-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
  <!--больше больше больше-->
</body>
          

node

Дайте нам нормальные модули!

ES6+

Дайте нам нормальные модули!

ES6+

Дайте нам нормальные модули в браузере!

И теперь мы могём так

import _ from 'lodash';

if (_.has([1, 2, 3], 2)) {
  console.log("debug");
}
          

И получаем...

Сборщик Размер
Webpack 531k
Rollup 528k

import has from 'lodash/has';

if (has([1, 2, 3], 2)) {
  console.log("debug");
}
          

import has from 'lodash/has';

if (has([1, 2, 3], 2)) {
  console.log("debug");
}
          
Сборщик Размер
Webpack 42к
Rollup 33к

Вместо 42k можно написать примерно вот так


if([1,2,3].indexOf(2) != -1){
  console.log('debug');
}
          

const has = (arr,input) => arr.indexOf(input) != -1

if(has([1,2,3], 2)){
 console.log('debug');
}
          

const has = (arr,input) => arr.indexOf(input) != -1

if(has([1,2,3], 2)){
 console.log('debug');
}
          
Ничего не напоминает?

holy wars

Left-pad

Веб-разработчик Азер Кочулу (Azer Koçulu), автор более 250 модулей для Node.js, попал в неприятную ситуацию. В своём блоге он пишет, что несколько недель назад получил письмо от юриста компании Kik (мессенджер) с требованием отозвать модуль с аналогичным названием kik из пакетного менеджера NPM (Node Package Manager).

Программист отказался, тогда юрист обратился напрямую в NPM, и администрация проекта удовлетворила его требование, сменив владельца kik без разрешения автора.

Азер Кочулу был крайне недоволен этим. Настолько недоволен, что решил в ответ «освободить» (то есть отозвать) все свои модули — более 250 модулей NPM. К сожалению, среди них оказался и left-pad — маленький модуль из 11 строк кода на JavaScript. Он используется при установке зависимостей между пакетами через NPM, в том числе в Node.js, JavaScript-транскомпиляторе Babel и огромном количестве других билдов. Только за прошлый месяц left-pad скачали 2 486 696 с сервера NPM, по их статистике.

Код left-pad показан ниже. Он просто заполняет левую часть строки нулями или пробелами.

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

Чтобы в экстренном порядке исправить ситуацию, технический директор и сооснователь NPM Лори Восс (Laurie Voss) пошёл беспрецедентный шаг (так он назвал его в твиттере) и, «учитывая серьёзность и распространённость проблемы», отменил отзыв модуля. Была опубликована старая версия модуля, аналогичная последней.

Сам Азер Кочулу считает, что администрация NPM берёт на себя слишком много полномочий. Он верит в силу движения Open Source и призывает создать «по-настоящему свободную альтернативу NPM». Азер просит прощения у всех веб-разработчиков, кто пострадал в результате его действий. Модуль Kik и другие он выложил на Github.


_.padStart('abc', 6);
// => '   abc'
          

2 вывода

  • Бекенд != Фронтенд
  • Нужно понимать как все устроено

2 вывода

  • Бекенд != Фронтенд — ✓
  • Нужно понимать как все устроено

2 вывода

  • Бекенд != Фронтенд — ✓
  • Нужно понимать как все устроено

Уменьшение объема кода

  • gzip
  • уменьшение самого файла

Уменьшение объема кода

  • gzip
  • уменьшение самого файла

Чем ещё плох этот код?


import has from 'lodash/has';

if (has([1, 2, 3], 2)) {
  console.log("debug");
}
          

Чем ещё плох этот код?


import has from 'lodash/has';

if (has([1, 2, 3], 2)) {
  console.log("debug");
}
          

Dart


void main(){
  if([1,2,3].contains(2)){
    print('debug');
  }
}
          
Dart - 24K

Dart


void main(){
  if([1,2,3].contains(2)){
    print('debug');
  }
  [1,2,3].forEach((item){
    print(item);
  });

}
          
Dart - 52K

Angular

  • Typescript - 284kb 💩
  • Dart - 220kb
  • Dart + uglify - 192kb
Копаем глубже

src/math.js


export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}
          

src/index.js


import { cube } from './math.js';

console.log(cube(10));
          

var cube = function(a) {
  return a * a;
}
console.log(cube(10));
          

Dart


// Стандартная библиотека
...
    main: function() {
      H.printString("100");
    },
...
// Стандартная библиотека
          

class Wheel {
  pump(){
    console.log('puuuuf');
  }
}

class Rudder {
  turn(){
    console.log('turn');
  }
}

export {Wheel, Rudder}
          

import { Wheel } from './module.js';

class Car {
  constructor(){
    this.wheel = new Wheel();
  }
}

const car = new Car();
car.wheel.pump();
          

Uglify vs Google Closure Compiler

Сравнение - https://goo.gl/suo6gq

2 вывода

  • Бекенд != Фронтенд — ✓
  • Нужно понимать как все устроено

2 вывода

  • Бекенд != Фронтенд — ✓
  • Нужно понимать как все устроено — ✓
Спасибо за внимание!

twitter: @zolotyh

Слайды: https://goo.gl/vrrpfW