Kyiv Go Meetup May 2018:
![](https://habrastorage.org/webt/bf/du/ti/bfdutifuyvrv1fruqtixblqvrvm.jpeg)
Ведущий: – Всем привет! Спасибо, что вы здесь собрались! Сегодня у нас два официальных спикера – Лёша и Ваня. Будет ещё два, если у нас хватит времени. Первый спикер – Алексей Грачёв, он расскажет нам о GopherJS.
Алексей Грачёв (далее – АГ): – Я – Go-девелопер, и я пишу веб-сервисы на Go. Порой приходится сталкиваться с фронтендом, иногда приходится залазить туда ручками. Хочу рассказать о своём опыте и исследованиях Go на фронтенде.
Легенда такая: сначала поговорим, почему мы хотим запускать Go на фронтенде, потом поговорим, как это можно сделать. Есть два пути – Web Assembly и GopherJS. Посмотрим, в каком состоянии эти решения и что можно делать.
Все согласны, что всё хорошо с фронтендом?
![](https://habrastorage.org/webt/of/f_/ix/off_ixibj9wbieegnt2ybp2sc3w.jpeg)
Тестов мало? Медленная сборка? Экосистема? Хорошо.
По поводу фронтенда мне нравится цитата, которую сказал один из фронтенд-разработчиков в своей книге:
![](https://habrastorage.org/webt/fa/et/a7/faeta7quyo5vwl7d-y6gqr1dkd4.jpeg)
В Javascript нет системы типов. Сейчас я буду называть проблемы, с которыми сталкивался по ходу своей работы и объяснять, как их решают.
Систему типов вообще трудно назвать системой типов в Javasript – там есть строки, которые обозначают тип объекта, но на самом деле к типам это не имеет никакого отношения. Эта проблема решена в TypeScript (надстройка над Javasript) и Flow (static-checker типов в Javascript). Собственно, фронтенд уже дошёл до решения проблемы плохой системы типов в Javascript.
![](https://habrastorage.org/webt/qb/to/lb/qbtolb9mypeirisl5naj7gal1bs.jpeg)
Стандартной библиотеки в браузере как таковой нет – есть какие-то встроенные объекты и «магические» функции в браузерах. Но я в Javascript как таковом стандартная библиотека отсутствует. Эта проблема уже была когда-то решена jQuery (все использовали jQuery со всеми прототипами, хелперами, функциями, которые нужны для работы). Сейчас же все используют Lodash:
![](https://habrastorage.org/webt/bo/7u/xv/bo7uxvik2sop3ojvnikuik3xprm.jpeg)
Callback hell. Думаю, все видели код на Javascript где-то 5 лет назад, и он был похож на «лапшу» из невероятного хитросплетения коллбэков. Сейчас эта проблема решена (с выходом ES-15 или ES-16), добавили в Javascript промисы (promises) и всем стало дышать полегче на какое-то время.
![](https://habrastorage.org/webt/pz/dx/q1/pzdxq1ctpbb5sihwtjnsu5etni8.jpeg)
Пока не пришёл Promice hell… Не знаю, как фронтенд-индустрия умудряется, но они всё время загоняют себя в какие-то странные дебри. Умудрились и на «промисах» сделать hell. Потом решили эту проблему, добавив новый примитив – async/await:
![](https://habrastorage.org/webt/oa/zz/8w/oazz8wf1yzvd3yei5ru3ek74cyw.jpeg)
С асинхронностью проблема решена. Async/await – достаточно популярный примитив в разных языках. В «Питоне» и в других есть такой подход – он достаточно хорош. Проблема решена.
Какая проблема не решена? Возрастающая в геометрической прогрессии сложность фреймворков, сложность экосистемы и собственно программ.
![](https://habrastorage.org/webt/wi/w0/ii/wiw0ii1soqn4o_epxke-dtvc6ws.jpeg)
Бравые ребята из Mozilla Foundation и ряда других компаний придумали такую вещь, как Web Assembly. Что это?
![](https://habrastorage.org/webt/kh/gg/84/khgg84kto__qwejpi46crviqy0o.jpeg)
Пока у нас нет поддержки Web Assembly, есть такой транспайлер, как GopherJS.
![](https://habrastorage.org/webt/gh/zr/nd/ghzrndmrxnalkq9rrgepog8oogw.jpeg)
Получить GopherJS очень легко – это обычный Go-пакет. Делаем go get, и у нас есть команда GopherJS, чтобы билдить приложение:
![](https://habrastorage.org/webt/xr/jp/xd/xrjpxdpdfvfzwalewvzpvw57f_g.jpeg)
Вот такой маленький hello world…
![](https://habrastorage.org/webt/92/rv/qr/92rvqrogzoij19cu-gvw-7j6k_o.jpeg)
…Обычная Go-программа, обычный пакет fmt стандартной библиотеки и Binding Js, чтобы достучаться до API браузера. Println в итоге будет преобразован в console log и браузер напишет “Hello gophers”! Вот так просто: делаем GopherJS build – запускаем в браузере – всё работает!
![](https://habrastorage.org/webt/on/-3/s2/on-3s2zu83wlf8t3pokfhcxgyk4.jpeg)
Есть биндинги ко всем популярным js-фреймворкам:
Продемонстрирую пару примеров, как это выглядит и что уже сейчас можно написать на Go:
![](https://habrastorage.org/webt/r9/ql/nt/r9qlnt_xvq8qu8jstzasafy5fjk.jpeg)
Или такой вариант (3D-шутер не нашёл, но, может, он есть):
![](https://habrastorage.org/webt/r9/ql/nt/r9qlnt_xvq8qu8jstzasafy5fjk.jpeg)
Сейчас индустрия фронтенда находится в таком состоянии, что туда сейчас ринутся все языки, которые до этого плакали от Javascript. Теперь все будут компилироваться в «Веб Ассембли». Что нам нужно, чтобы занять там достойное место как «гоферам»?
![](https://habrastorage.org/webt/mb/ah/ny/mbahnylpmbnirgog49uf1ip1hlg.jpeg)
В Go традиционно пошло, что это – System programming language, и практически нет никаких библиотек для работы с UI. Что-то есть, но оно наполовину заброшенное, наполовину нефункциональное.
И вот – хороший шанс сделать UI-библиотеки на Go, которые будут запускаться на GopherJS! Можно, наконец, написать свой фреймворк! Наступило то время, когда можно написать фреймворк, и он будет одним из первых и получит раннюю адаптацию, и вы будете звездой (если это будет хороший фреймворк).
Адаптировать можно уйму разных пакетов, которые уже есть в экосистеме Go, к специфике браузера (например, Template engine). Они итак уже заработают, можно сделать удобные обвязки, чтобы можно было легко рендерить контент прямо в браузере. Плюс, можно сделать, например, сервис, умеющий рендерить то же самое на сервере и на фронтенде, используя один и тот же код – всё как любят фронтенд-девелоперы (только теперь на Go).
Можно написать игру! Just for fun…
У меня всё.
![](https://habrastorage.org/webt/4e/jl/hr/4ejlhr2zxkvwba3vzeigyh7gz-a.jpeg)
Вопрос (далее – В): – Я пишу на Go или на Js?
АГ: – Ты пишешь на Go рутины, каналы, структуры, embedding – всё… Ты подписываешься на event, передаёшь туда функцию.
В: – То есть я пишу на «голом» Js?
АГ: – Нет, ты пишешь как бы на Go и подключаешься к API браузера (API при этом не изменился). Можешь написать свои обвязки, чтобы в канал приходили сообщения – это ж несложно.
В: – Что насчёт мобайла?
АГ: – Я точно видел: есть биндинги для патча Cordova, которые Js запускает. В React Native – не знаю; может, есть, а может, нет (не особо интересовался). Игровой движок N-go поддерживает и мобильные приложения – и iOs, и Android.
В: – Вопрос по Web Assembly. Места занимается всё больше, несмотря на сжатость, «зазипованность»… Не убьём ли таким образом мир фронтенда ещё больше?
АГ: – Web Assembly – это бинарный формат, и бинарный по умолчанию не может быть в итоговом релизе больше, чем текст… Вас тянет runtime, но это то же самое, что стандартную библиотеку Javascript затянуть, когда её нет, поэтому мы используем какой-нибудь Lodash. Я не знаю, сколько Lodash занимает.
В: – Явно меньше, чем runtime…
АГ: – На «чистом» Javascript?
В: – Да. Мы же его сжимаем перед тем, как отправлять…
АГ: – Но это же текст… В общем, мегабайт – это вроде много, но это – всё (у тебя весь runtime есть). Далее ты пишешь свою бизнес-логику, которая увеличит на 1 % твой binary. Пока я не вижу, чтобы это убивало фронтенд. Тем более Web Assembly будет работать быстрее, чем Javascript по очевидной причине – его не надо парсить.
В: – Пока спорный момент… Ещё нет какой-то эталонной реализации «Васма» (Web Assembly), чтобы можно было однозначно судить. Концептуально – да: мы все понимает, что binary должен быть быстрей, но текущая реализация того же V8 очень эффективна.
АГ: – Да.
В: – Компиляция там работает реально очень круто и не факт, что будет большое преимущество.
АГ: – Web Assembly тоже большие дядьки делают.
В: – Пока, мне кажется, ещё трудно судить о Web Assembly. Уже сколько лет идут разговоры, а реальных достижений, которые можно пощупать, немного.
АГ: – Возможно. Будем посмотреть.
В: – У нас нет проблем на бэкенде… Может, оставить эти проблемы во фронтенде? Зачем туда лезть?
АГ: – Приходится держать штат фронтейнеров.
Спасибо, что остаётесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас, оформив заказ или порекомендовав знакомым, облачные VPS для разработчиков от $4.99, уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер? (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).
Dell R730xd в 2 раза дешевле в дата-центре Equinix Tier IV в Амстердаме? Только у нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199 в Нидерландах! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — от $99! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?
![](https://habrastorage.org/webt/bf/du/ti/bfdutifuyvrv1fruqtixblqvrvm.jpeg)
Ведущий: – Всем привет! Спасибо, что вы здесь собрались! Сегодня у нас два официальных спикера – Лёша и Ваня. Будет ещё два, если у нас хватит времени. Первый спикер – Алексей Грачёв, он расскажет нам о GopherJS.
Алексей Грачёв (далее – АГ): – Я – Go-девелопер, и я пишу веб-сервисы на Go. Порой приходится сталкиваться с фронтендом, иногда приходится залазить туда ручками. Хочу рассказать о своём опыте и исследованиях Go на фронтенде.
Легенда такая: сначала поговорим, почему мы хотим запускать Go на фронтенде, потом поговорим, как это можно сделать. Есть два пути – Web Assembly и GopherJS. Посмотрим, в каком состоянии эти решения и что можно делать.
Что не так с frontend-ом?
Все согласны, что всё хорошо с фронтендом?
![](https://habrastorage.org/webt/of/f_/ix/off_ixibj9wbieegnt2ybp2sc3w.jpeg)
Тестов мало? Медленная сборка? Экосистема? Хорошо.
По поводу фронтенда мне нравится цитата, которую сказал один из фронтенд-разработчиков в своей книге:
![](https://habrastorage.org/webt/fa/et/a7/faeta7quyo5vwl7d-y6gqr1dkd4.jpeg)
В Javascript нет системы типов. Сейчас я буду называть проблемы, с которыми сталкивался по ходу своей работы и объяснять, как их решают.
Систему типов вообще трудно назвать системой типов в Javasript – там есть строки, которые обозначают тип объекта, но на самом деле к типам это не имеет никакого отношения. Эта проблема решена в TypeScript (надстройка над Javasript) и Flow (static-checker типов в Javascript). Собственно, фронтенд уже дошёл до решения проблемы плохой системы типов в Javascript.
![](https://habrastorage.org/webt/qb/to/lb/qbtolb9mypeirisl5naj7gal1bs.jpeg)
Стандартной библиотеки в браузере как таковой нет – есть какие-то встроенные объекты и «магические» функции в браузерах. Но я в Javascript как таковом стандартная библиотека отсутствует. Эта проблема уже была когда-то решена jQuery (все использовали jQuery со всеми прототипами, хелперами, функциями, которые нужны для работы). Сейчас же все используют Lodash:
![](https://habrastorage.org/webt/bo/7u/xv/bo7uxvik2sop3ojvnikuik3xprm.jpeg)
Callback hell. Думаю, все видели код на Javascript где-то 5 лет назад, и он был похож на «лапшу» из невероятного хитросплетения коллбэков. Сейчас эта проблема решена (с выходом ES-15 или ES-16), добавили в Javascript промисы (promises) и всем стало дышать полегче на какое-то время.
![](https://habrastorage.org/webt/pz/dx/q1/pzdxq1ctpbb5sihwtjnsu5etni8.jpeg)
Пока не пришёл Promice hell… Не знаю, как фронтенд-индустрия умудряется, но они всё время загоняют себя в какие-то странные дебри. Умудрились и на «промисах» сделать hell. Потом решили эту проблему, добавив новый примитив – async/await:
![](https://habrastorage.org/webt/oa/zz/8w/oazz8wf1yzvd3yei5ru3ek74cyw.jpeg)
С асинхронностью проблема решена. Async/await – достаточно популярный примитив в разных языках. В «Питоне» и в других есть такой подход – он достаточно хорош. Проблема решена.
Какая проблема не решена? Возрастающая в геометрической прогрессии сложность фреймворков, сложность экосистемы и собственно программ.
![](https://habrastorage.org/webt/wi/w0/ii/wiw0ii1soqn4o_epxke-dtvc6ws.jpeg)
- Синтаксис Javasript немного странноватый. Все мы знаем проблемы со сложением массива и объекта и другие приколы.
- Javascript – мультипарадигменный. Сейчас это особенно насущная система, когда экосистема очень большая:
- все пишут в разных стилях – кто-то пишет структурно, кто-то пишет функционально, разные девелоперы пишут по-разному;
- из разных пэкэджей (packages) разные парадигмы, когда вы используете разные пакеты;
- очень много «веселья» с функциональным программированием в Javasript – появилась библиотека rambda и теперь читать программы, написанные в этой библиотеке, не может никто.
- Это всё вносит большой impact в экосистему, и она разрослась невероятно. Пакеты друг с другом несовместимы: кто-то – на промисах, кто-то – на async/await, кто-то – на коллбэках. Ещё и в разных парадигмах пишут!
- Это приводит к тому, что проект сложно поддерживать. Сложно найти баг, если ты не можешь прочитать код.
Что такое Web Assemly?
Бравые ребята из Mozilla Foundation и ряда других компаний придумали такую вещь, как Web Assembly. Что это?
![](https://habrastorage.org/webt/kh/gg/84/khgg84kto__qwejpi46crviqy0o.jpeg)
- Это встроенная в браузер виртуальная машина, которая поддерживает бинарный формат.
- Бинарные программы туда попадают, выполняются практически нативно, то есть браузеру не нужно каждый раз парсить всю «лапшу» javascript-кода.
- Все браузеры заявили о поддержке.
- Поскольку это байт-код, можно написать компилятоор под любой язык.
- Четыре основных браузера уже поставляются с поддержкой Web Assembly.
- Скоро мы ждём нативной поддержки в Go. Такая новая архитектура уже добавилась: GOARCH=wasm GOOS=js (soon). Пока, как я понимаю, она не функциональна, однако есть заявление о том, что это точно будет в Go.
Что делать сейчас? GopherJS
Пока у нас нет поддержки Web Assembly, есть такой транспайлер, как GopherJS.
![](https://habrastorage.org/webt/gh/zr/nd/ghzrndmrxnalkq9rrgepog8oogw.jpeg)
- Код на Go транспайлится в «чистый» Javascript.
- Запускается во всех браузерах – там нет новых фич, которые поддерживаются только современными браузерами (это Vanilla JS, который запускается на всём чём угодно).
- Есть поддержка почти всего, что есть в Go, в том числе горутины и каналы… – всё, что мы так любим и знаем.
- Почти вся стандартная библиотека поддерживается, за исключением тех пакетов, которые не имеет смысла поддерживать в браузере: syscall, net-взаимодействия (есть net/http-клиент, но нет сервера, а клиент эмулируется через XMLHttpRequest). В целом вся стандартная библиотека доступна – вот она в браузере, вот stdlib Go, которую мы любим.
- Вся экосистема пакета в Go, все сторонние решения (темплейтинг и проч.) можно скомпилировать с помощью GopherJS и запустить это в браузере.
Получить GopherJS очень легко – это обычный Go-пакет. Делаем go get, и у нас есть команда GopherJS, чтобы билдить приложение:
![](https://habrastorage.org/webt/xr/jp/xd/xrjpxdpdfvfzwalewvzpvw57f_g.jpeg)
Вот такой маленький hello world…
![](https://habrastorage.org/webt/92/rv/qr/92rvqrogzoij19cu-gvw-7j6k_o.jpeg)
…Обычная Go-программа, обычный пакет fmt стандартной библиотеки и Binding Js, чтобы достучаться до API браузера. Println в итоге будет преобразован в console log и браузер напишет “Hello gophers”! Вот так просто: делаем GopherJS build – запускаем в браузере – всё работает!
Что есть на данный момент? Bindings
![](https://habrastorage.org/webt/on/-3/s2/on-3s2zu83wlf8t3pokfhcxgyk4.jpeg)
Есть биндинги ко всем популярным js-фреймворкам:
- JQuery;
- Angular.js;
- D3.js для построения графиков и работы с большими данными;
- React.js;
- VueJS;
- даже есть поддержка Electron (то есть уже сейчас можем писать десктопные приложения на «Электроне»);
- и самое забавное – это WebGL (можем делать полнографические приложения, в том числе игры с 3D-графикой, музыкой и всеми плюшками);
- и очень много других биндингов ко всем популярным javascript-фреймворкам и библиотекам.
Framework
- Есть уже разработанный специально для GopherJS веб-фреймворк – Vecty. Это полноценный аналог React.js, но только разработанный на Go, со спецификой GopherJS.
- Есть игровые мешки (внезапно!). Я нашёл два самых популярных:
- Engo;
- Ebiten.
Продемонстрирую пару примеров, как это выглядит и что уже сейчас можно написать на Go:
![](https://habrastorage.org/webt/r9/ql/nt/r9qlnt_xvq8qu8jstzasafy5fjk.jpeg)
Или такой вариант (3D-шутер не нашёл, но, может, он есть):
![](https://habrastorage.org/webt/r9/ql/nt/r9qlnt_xvq8qu8jstzasafy5fjk.jpeg)
Что я предлагаю?
Сейчас индустрия фронтенда находится в таком состоянии, что туда сейчас ринутся все языки, которые до этого плакали от Javascript. Теперь все будут компилироваться в «Веб Ассембли». Что нам нужно, чтобы занять там достойное место как «гоферам»?
![](https://habrastorage.org/webt/mb/ah/ny/mbahnylpmbnirgog49uf1ip1hlg.jpeg)
В Go традиционно пошло, что это – System programming language, и практически нет никаких библиотек для работы с UI. Что-то есть, но оно наполовину заброшенное, наполовину нефункциональное.
И вот – хороший шанс сделать UI-библиотеки на Go, которые будут запускаться на GopherJS! Можно, наконец, написать свой фреймворк! Наступило то время, когда можно написать фреймворк, и он будет одним из первых и получит раннюю адаптацию, и вы будете звездой (если это будет хороший фреймворк).
Адаптировать можно уйму разных пакетов, которые уже есть в экосистеме Go, к специфике браузера (например, Template engine). Они итак уже заработают, можно сделать удобные обвязки, чтобы можно было легко рендерить контент прямо в браузере. Плюс, можно сделать, например, сервис, умеющий рендерить то же самое на сервере и на фронтенде, используя один и тот же код – всё как любят фронтенд-девелоперы (только теперь на Go).
Можно написать игру! Just for fun…
У меня всё.
![](https://habrastorage.org/webt/4e/jl/hr/4ejlhr2zxkvwba3vzeigyh7gz-a.jpeg)
Вопросы
Вопрос (далее – В): – Я пишу на Go или на Js?
АГ: – Ты пишешь на Go рутины, каналы, структуры, embedding – всё… Ты подписываешься на event, передаёшь туда функцию.
В: – То есть я пишу на «голом» Js?
АГ: – Нет, ты пишешь как бы на Go и подключаешься к API браузера (API при этом не изменился). Можешь написать свои обвязки, чтобы в канал приходили сообщения – это ж несложно.
В: – Что насчёт мобайла?
АГ: – Я точно видел: есть биндинги для патча Cordova, которые Js запускает. В React Native – не знаю; может, есть, а может, нет (не особо интересовался). Игровой движок N-go поддерживает и мобильные приложения – и iOs, и Android.
В: – Вопрос по Web Assembly. Места занимается всё больше, несмотря на сжатость, «зазипованность»… Не убьём ли таким образом мир фронтенда ещё больше?
АГ: – Web Assembly – это бинарный формат, и бинарный по умолчанию не может быть в итоговом релизе больше, чем текст… Вас тянет runtime, но это то же самое, что стандартную библиотеку Javascript затянуть, когда её нет, поэтому мы используем какой-нибудь Lodash. Я не знаю, сколько Lodash занимает.
В: – Явно меньше, чем runtime…
АГ: – На «чистом» Javascript?
В: – Да. Мы же его сжимаем перед тем, как отправлять…
АГ: – Но это же текст… В общем, мегабайт – это вроде много, но это – всё (у тебя весь runtime есть). Далее ты пишешь свою бизнес-логику, которая увеличит на 1 % твой binary. Пока я не вижу, чтобы это убивало фронтенд. Тем более Web Assembly будет работать быстрее, чем Javascript по очевидной причине – его не надо парсить.
В: – Пока спорный момент… Ещё нет какой-то эталонной реализации «Васма» (Web Assembly), чтобы можно было однозначно судить. Концептуально – да: мы все понимает, что binary должен быть быстрей, но текущая реализация того же V8 очень эффективна.
АГ: – Да.
В: – Компиляция там работает реально очень круто и не факт, что будет большое преимущество.
АГ: – Web Assembly тоже большие дядьки делают.
В: – Пока, мне кажется, ещё трудно судить о Web Assembly. Уже сколько лет идут разговоры, а реальных достижений, которые можно пощупать, немного.
АГ: – Возможно. Будем посмотреть.
В: – У нас нет проблем на бэкенде… Может, оставить эти проблемы во фронтенде? Зачем туда лезть?
АГ: – Приходится держать штат фронтейнеров.
Немного рекламы :)
Спасибо, что остаётесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас, оформив заказ или порекомендовав знакомым, облачные VPS для разработчиков от $4.99, уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер? (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).
Dell R730xd в 2 раза дешевле в дата-центре Equinix Tier IV в Амстердаме? Только у нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199 в Нидерландах! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — от $99! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?
youROCK
В плане WebAssembly и Go мне лично намного больше нравится tinygo — для того, чтобы сделать онлайн-демо PHP-линтера noverify просто после компиляции того же кода (за исключением некоторых мелочей) у меня получился ~1 Мб wasm-файл вместо ~5 Мб на обычном go 1.13.
Поскольку tinygo это компилятор на основе LLVM и пока что tinygo поддерживает не совсем 100% функциональности Go (хотя очень близко) и старается в первую очередь поддерживать то, что хорошо транслируется в обычный Си-код, у него получается оптимизировать размер получаемых файлов намного лучше, чем у стандартного компилятора, который в первую очередь оптимизирует производительность, но не размер.