Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CodeFest 2019. Алексей Золотых (Infobip) — Сжимаем Javascript по-взрослому

CodeFest
April 07, 2019

CodeFest 2019. Алексей Золотых (Infobip) — Сжимаем Javascript по-взрослому

— Как влияет размер javascript бандла на общую производильность в 2019
— Как размер javascript бандла влияет на время старта вашего приложения
— Как правильно подключить javascript на страницу в 2019
— Как сжимают Javascript основные утилиты для сжатия
— Какие оптимизации и где применяются
— Какие реальные проблемы вызывают те или иные оптимизации SSA-формы
— Зачем нам типы для сжатия javascript

CodeFest

April 07, 2019
Tweet

More Decks by CodeFest

Other Decks in Technology

Transcript

  1. 2

  2. 3

  3. 8

  4. 17

  5. Сжатие в потоке gzip1— 50–90% gzip9 — 15–45% от gzip1

    zopfli — 4–7% от gzip9 brotli11 — 8–65% от zopfli 24
  6. 30% БЫСТРЕЕ 30% БЫСТРЕЕ ЗАГРУЗКА СТРАНИЦЫ ЗАГРУЗКА СТРАНИЦЫ * *

    * для медленных сетей и быстрых устройств 26
  7. 27

  8. 28

  9. ... gzip on; gzip_static on; gzip_vary on; gzip_types ... brotli

    on; brotli_comp_level 4; brotli_static on; brotli types 29
  10. 35

  11. Протянули константы (function() { const a = 1; const b

    = 2; console.log(a + b); }()); console.log(3); 42
  12. arrows, booleans, collapse_vars, comparisons, computed_props, conditionals, dead_code, drop_console, drop_debugger, ecma,

    evaluate, expression, global_defs, hoist_funs, hoist_props, hoist_vars, ie8, if_return, inline, join_vars, keep_classnames, keep_fargs, keep_fnames, keep_infinity, loops, negate_iife, passes, properties, pure_getters, pure_funcs, reduce_funcs, reduce_vars, sequences, side_effects, switches, top_retain,
  13. от 23к до 576к import * as _ from 'lodash'

    if (_.has([1, 2, 3], 2)) { console.log("debug"); } 50
  14. от 3к до 10к import * as _ from 'lodash/has'

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

  16. Как это скомпилит UglifyJS? import * as _ from 'lodash/has'

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

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

    export function cube(x) { return x * x * x; } 61
  19. Реальность !function(e){var r={};function t(n){if(r[n])return r[n].exports;var o=r[n]= {i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=r,t.d=function(e,r,n) {t.o(e,r)||Object.defineProperty(e,r, {configurable:!1,enumerable:!0,get:n})},t.r=function(e)

    {Object.defineProperty(e,"__esModule",{value:!0})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},t.p="",t(t.s=0)}([function(e,r,t){"use strict";t.r(r);var n;console.log((n=3)*n*n)}]); 64
  20. module.js export function square(x) { return x * x; }

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

    export function cube(x) { return square(x) * x } 67
  22. ... /* unused harmony export square */ /* harmony export

    (immutable) */ __webpa function square(x) { return x * x; } function cube(x) { t * * 70
  23. ... /* unused harmony export square */ /* harmony export

    (immutable) */ __webpa function square(x) { return x * x; } function cube(x) { t * * 71
  24. /* unused harmony export MyClass */ var MyClass = function

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

    () { function MyClass() { babelHelpers.classCallCheck(this, My } MyClass.prototype.turn = function prin console.log('find me'); }; 74
  26. Код на Dart void main() { print(cube(3)); } int cube(int

    x) => x * x * x; int square(int x) => x * x; 79
  27. class Rudder { void turn(){ print('turn'); } } class Wheel

    { void pump(){ print('pump'); } } 82
  28. void main(){ final car = new Car(); car.wheelList = [

    new Wheel() new Wheel(), new Wheel(), new Wheel(), ]; car.rudder = new Rudder(); car.rudder.turn(); } 83
  29. SSA (англ. Static single assignment form) — промежуточное представление, используемое

    компиляторами, в котором каждой переменной значение присваивается лишь единожды 88
  30. const car = { wheelList: [ new Wheel(), new Wheel(),

    new Wheel(), new Wheel(), ], rudder: new Rudder(), }; 91
  31. ОПТИМИЗАЦИИ ОПТИМИЗАЦИИ normalize optimizeArgumentsArray aggressiveInlineAliases collapseProperties earlyInlineVariables earlyPeepholeOptimizations removeUnusedCode disambiguateProperties

    codeRemovingLoop devirtualizePrototypeMethods flowSensitiveInlineVariables mainOptimizationLoop flowSensitiveInlineVariables removeUnusedCode collapseAnonymousFunctions extractPrototypeMemberDeclarations ambiguateProperties renameProperties convertToDottedProperties coalesceVariableNames peepholeOptimizations exploitAssign collapseVariableDeclarations denormalize renameVars renameLabels latePeepholeOptimizations 93
  32. 94

  33. 95

  34. 527k ⟹ 140k java -jar compiler.jar \ --compilation_level ADVANCED \

    --language_in=ES6 \ --js lodash.js > out.js 97
  35. /** * This annotation spans multiple lines * @type {{

    * id:number, * val:string, * }} */ 99
  36. const car = {}; car.idNumber = '1234'; function displayId(car) {

    alert(car['idNumber']); } alert(car.idNumber); displayId(car); 103
  37. (function () { function fibonacci(x) { return x <= 1

    ? x : fibonacci(x - 1 } global.x = fibonacci(15); })(); 106