Pull to refresh
6
0
Владислав @ihost

Программист

Send message

Вечная проблема адептов TDD заключается в том, что все это работает только на примитивнейших приложениях такой же сложности, как примеры к самой книжке по TDD — уровня тестирования функции sum2and2


Если взять хотя бы разработку приложения, которое хотя бы минимально поддерживает highload, не говоря уже о настоящих HPC-решениях — то все это TDD абсолютнейшая фикция, которая никак не коррелирует с работоспособностью программы


Почему? Да потому, что выдернутая изолированно функция и написанная по TDD будет конечно работать, но в составе самого HPC/highload-приложения это никогда не зарабоает. Потому что не только приемлемая скорость работы, а вообще работоспособность зависит от выравнивания линеек кэша и его когерентности между numa-нодами, примитивов синхронизации и барьеров памяти, аспектов спекулятивного выполнения и еще тонны вещей, о которых адепты TDD на модных языках никогда и не слышали скорее всего

С исходной новостью все довольно понятно и очевидно, куда интереснее смежный вопрос.
Интересно, как закон учитывает фотографии в публичных местах? Чтобы сфотографироваться, к примеру на Piazza San Marco, надо спросить письменного разрешения у десятков тысяч человек? То есть живешь ты, допустим в Германии, поехал отдохнуть в Италию, пофотографировался от души, выложил сотню фоток — и к тебе потом могут предъявить иски на миллионы евро любые люди, кто засветился хоть краешком?
Если действительно так, то странно, что Instagram/Facebook не имеют функцию автоматического размывания лиц на заднем плане, причем включенную по умолчанию, чтобы уберечь себя от многомиллионных исков

Значительно меньшее потребление памяти и лучшее быстродействие. На бюджетном/стареньком ноутбуке под управлением Windows 10 пользоваться чем-то, кроме Edge на движке Charka, решительно невозможно из-за тормозов и отвалов по оперативке.
Как обстоят дела под остальными операционками — это другой вопрос.
Самое простое это провести эксперимент — берете ноут на 2-3 GB оперативки, выключаете файл подкачки (с ним из-за медленного HDD система просто умирает) — и в таком случае даже запустить что-то, кроме классического Edge на Chakra, вряд ли получится, не говоря уже о скорости серфинга.
Если у вас такая комбинация оборудования, крайне рекомендую поставить blocker kit https://docs.microsoft.com/en-us/deployedge/microsoft-edge-blocker-toolkit, чтобы не пришлось выкидывать старый ноут на помойку или ставить на него linux :)

Google Chrome с 63 версии уже поддерживает эту возможность

А Edge и Safari поддерживают эту фичу уже два года — https://habr.com/ru/company/tuturu/blog/326716/. Оперативно, может еще через десяток лет хром наконец-то оптимизирует потребление памяти до уровня Edge

В Edge и Safari эта фича уже давно поддерживается и работает — больше двух лет как — см. https://habr.com/ru/company/tuturu/blog/326716/ — как собственно и с множеством современных ES-фичей, которые в Edge поступают раньше, чем в хром

У docker-а скорее другая проблема: он не подходит для низкоуровневых highload приложений, вроде сетевого ввода/вывода на основе poll mode-драйвера IGB UIO на сервере с несколькими 40-гигабитными карточками. По очевидным причинам IGB UIO или KNI на docker-ах не запустить, а иначе сложно выжать соответствующую производительность


А не-highload приложения, не столь критичные к ресурсам, можно запускать и на виртуалках, или что еще лучше — в serverless-облаке.

Если вы пишете серверные приложения в среде Node.js, взгляните на wolkenkit. Этот фреймворк, среди того, что удалось обнаружить в данной сфере предоставляет разработчику один из самых простых интерфейсов для реализации шаблонов CQRS и Event Sourcing

Только при этом wolkenkit, к сожалению, требователен к инструментам — как минимум, придется docker устанавливать, что к примеру под windows — сомнительное занятие


Существуют более легковесные CQRS+ES фреймворки на Node.js, не требующие дополнительных инструментов, к примеру, Resolve.JS. Еще и поддержка React Native из коробки

EdgeHTML менее стабилен и быстр, чем Chromium

Можно спорить о разных аспектах, но это утверждение ложное.
Может быть оно и является истинным на рабочей станции с Core i9 и 256 ГБ оперативной памяти.
Но на ноутбуке 2012-ого года выпуска с Win10 и 4GB памяти использовать что-то кроме Edge решительно невозможно — это единственный браузер, который не отжирает все эти 4GB, даже если открыть 100500 вкладок.
Если выключить swap-раздел, то хваленый Хром каждую вторую вкладку аварийно завершает с нехваткой памяти, а Edge летает очень шустро.
Так что если новость правда — то это колоссальная потеря для стареньких маломощных ноутбуков и нетбуков — тогда их будет только на мусорку отнести.
Конечно, можно снести винду и поставить Lununtu или Xubuntu с облегченным рабочим столом, но это уже совсем другая история.

Интересное решение, хотя при использовании C extensions (gcc), можно обойтись без функторов вообще — за счет Label Values. Эта функциональность применяется в низкоуровневых модулях высоконагруженных приложений для организации переходов без ветвления, хотя в зависимости от ситуации может быть оптимальнее использовать if в сочетании с builtin_expect для мануальной настройки branch prediction. Вместо отрицания, возможно, применить более подходящий оптимальный intrinsic


int main() {
  int n = 100500;
  void* refs [] = { &&work, &&done };
  work:
    printf("%d ", n);
    n--;
    goto *refs[!n];
  done:
  return 0;
}

Безусловно, у всех решений свои плюсы и минусы. В принципе, в современном web-е код модифицируется и так немало раз — babel для async/await и генераторов, bundle-ирование в webpack-е, polyfills и так далее — так что в принципе в еще одном преобразовании особо ничего страшного нет.
Сам hammerhead выглядит довольно надежным — мне удалось найти, как выйти из песочницы, но маловероятно, что в обычном web-приложении такое бывает. Зато пользователи SmartTV и прочих необычных браузеров счастливы :)

Конечно, Nightwatch в целом неплох, но имеет свои недостатки: устаревший синтаксис с callback-цепочками вместо Promises и async/await, и требования наличия webdriver-а к браузеру — как тестировать на смартфоне или смарт-ТВ? Если Вы занимаетесь функциональным тестированием web-сфере и следите за развитием технологий, рекоммендую ознакомиться с этой статьей, и в частности, присмотреться к решениям от TestCafe — тоже на Node.js, но поудобнее и решающий вопрос с любыми девайсами. Можно вообще SauseLabs прикрутить, чтобы тестировать на всевозможных устройствах скопом.

react-scripts, или уж тем более с resolve-scripts
Что здесь сложного?

Тем что надо отдельно настраивать конфигурируемую head-секцию с внешнием сценарием через React Helmet ?


Тем что из-за синхронной загрузки скриптов увеличивается время загрузки страницы? А если CDN этого внешнего сервиса отвалится, то и web-приложение тоже? А также тем, что начинаются проблемы с offline-режимом, и к примеру, невозможно зарегистрировать service worken для удаленного СDN: https://filipbech.github.io/2017/02/service-worker-and-caching-from-other-origins ?


Тем что это может уже не сработать, если браузер поддержал ES modules-подобную загрузку, которая уже асинхронная, и если предполагался polyfill уровня ES8+, то он мог не успеть загрузиться?


Тем что нельзя установить жесткую CSP-политику для безопасности web-приложения, к примеру, отключающую eval для внешних сценариев или аналогичную?


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

о динамической генерации полифиллов полезно знать

Безусловно. А еще лучше иметь заранее подготовленные bundle-ы для версия браузеров. Более того, есть решения, которые позволяет также включать сразу ES Modules для современных клинетских агентов, не выполняя дифференциации генерируемой HTML-страницы, а делая это исходя из feature discovery: статьи как настроить раз и два.


Promise и fetch не завезли в IE11

Разумеется. Для fetch-а в исходном коде вообще скорее всего не будет прямого вызова, а изоморфный импорт import fetch from 'isomorphic-fetch'.


Это все довольно очевидные вещи. Весь тред собственно о том, если не использовать ES8+, то выбрасывание многострадального и довольно бесполезного includes позволяет сэкономить тонну работы по deployment-у.


Если вдруг ваше приложение использует ES8+, то и говорить не о чем. Собственно, как Вы сами частично и признаете:


includes сам по себе не очень хороший пример

А весь тред только об includes и есть.

сервис polyfill.io

Сторонний сервис, который судя по обзору документации и единственному стороннему устаревшему пакету для bundle-ирования, не стыкуется с концепцией упаковки и доставки кода на клиент, не говоря уже о chunk splitting, feature detecting-based bundles, HMR и тому подобное.


Как это использовать с react-scripts, или уж тем более с resolve-scripts, с изоморфным кодом data layer-а, и чтобы при этом оставалась поддержка требуемых клиентских агентов без избычного кода — совершенно неясно, и вероятно, вообще невозможно.


Если Вы где-то используете и для Ваших задач подходит — на здоровье, никто не против. В серьезных же проектах лучше отказаться от одной малополезной функции, ради упрощения и стабилицаии продукта.
Посмотрите на тот же React (includes vs indexOf) — на клиентской стороне ни одного includes, та парочка что есть — это серверный task runner.


Разумеется, на node.js в НЕ-изоморфном окружении можно использовать что угодно, хоть stage-0 со всякими флагами. На клиенте или изоморфном коде следует подходить аккуратнее.

Подключили скрипт на страницу

Какой скрипт, на какую страницу. о чем Вы вообще? Как у Вас организован deployment, bundle-ирование и доставка кода на клиент?


Если Вы делаете transpile-инг на серверной стороне, то и все необходимые polyfills надо интегрировать сразу, чтобы сборщик зависимостей исключил дубликаты. Если не делаете — то код просто сломается на старых клиентских агентах из-за синтаксических ошибок, тогда и polyfills вообще не понадобится уже — и так страница не откроется.


Получается, что Вы предлагаете разрабатывать на синтаксисе ES5, но с функциями из ES7? Смысла мало, но если в Вашем проекте Вам там удобно — кто ж запретит, юзайте на здоровье


Вы точно разбираетесь, чем полифилл отличается от библиотеки?

Ничем не отличаются, что одно package, что другое package. Правда обычно polyfill package не является прямой prod-зависимостью других пакетов, а добавляется явно во входной точке конфигурации того же webpack-а или другого bundler-а, если Вам угодно.


Однако в таком случае встречный вопрос — regenerator-runtime это в Вашей терминологии polyfill или абстрактный library?


Его надо явно import-ить (Как видимо "библиотека" в Вашей терминологии), но при этом он модифицирует глобальное пространство процесса (Как видимо "полифилл" в вашей терминологии)


Впрочем, позволю резюмировать. Каждый deploy-ит как хочет, выбирает клиентские агенты, какие поддерживать, а какие нет, решает, оптимизировать производительность или сделать попроще, забив на это. Для каждого случая это можно решать отдельно. Однако если вспомнить, что все это ради одной функции, то лучше на нее забить.

Сервер читает userAgent

Производить проверку браузера, исходя из строки агента, не рекоммендуется — современным методом является feature discovery — к примеру, вариант для ES6, но это даже не столь существенно


Самое главное — такое решение плохо сочетается с самой идеей bundle-ирование клиентского кода. Конечно, можно загрузить предложенную библиотеку как статику и добавить в externals, но тогда bundle все равно или будет целиком содержать излишний исходный код, или требовать условной сборки, зависимой от клиентского агента.

Или babel-polyfill, если зависимости собираются webpack-ом и поставляются на клиент в виде bundle-а? Окей, но скорее всего нет, поскольку есть один важный аспект — вопросы оптимизации, включая объем трафика для bundle-а и вычислительные ресурсы для выполнения на клиенте.


Применение единого bundle-а со всеми polyfills и transpile-кодом на современных браузерах приводит к существенному оверхэду, поэтому рекоммендуется разворачивать отдельный bundle для современных клиентских агентов (раз, два).


Условно все относительно-современные браузеры поддеривают ES6, и для них может приозводиться доставка непосредственно ES6-кода. Для старых браузеров можно применять polyfills, transpile-ить код, или вообще просить пользователя обновиться для просмотра ресурса — это вопрос отдельный.


Теперь если взять все браузеры с ES6, то часть из них, включая IE11, Smart TV, Tizen, не поддерживают ES7, но отлично понимают ES6. Если вспомнить соответствующую спецификацию комитета TC39, то 6-ая версия включает всего два изменения — оператор возведения в степень и includes. ВСЁ.


Исходя из этого вопрос — имеет ли смысл заморачиваться с отдельным bundle-ом с polyfills и transpile-ингом с уровня ES7 до ES6 (*), по сути ради одной единственной функции, которая чуть менее, чем на 100% — всего лишь синтаксический сахар для arr.indexOf(value) > 0? Настраивать развертывание, кеширование отдельного bundle-а, отдельные функциональные тесты на каком-нибудь SauseLabs, ради одной малополезной функции?


(*) При условии, что такое легко реализовать; babel по умолчанию, вроде бы, так не умеет, так что задача приобретает еще один виток сложности

Если говорить об ES6 то почему бы не использовать Array.prototype.includes вместо вот этого

Безотносительно ко всей статье, но именно includes в некоторым смысле вредная штука — способ выкинуть поддержку как минимум IE11 и Samsung TV browser на пустом месте
Если синтаксические конструкции ES7+ легко раз-babel-иваются, а для ES6-функционала polyfills во всех современных браузерах не нужны и по умолчанию их давно уже никто не включает в bundle-ы, то includes — фактически единственное исключение и способ нажить неудобства при deployment-е

Забавно, что приведенный Вами код с точностью до синтаксиса вообще не создает объект, а декларирует прототип функции в лексическом scope (См. https://en.wikipedia.org/wiki/Most_vexing_parse#Example_with_classes или вживую тут https://ideone.com/J3Y0oN )


Но в целом понятно, что Вы имели в вид

А теперь тоже самое для статичных (выделяемых в стеке) фукнций.

Имеются в виду функции, использующие переменные из activation object, то бишь замыкания? Они такие же объекты с похожим жизненным циклом, так что отлавливать и подсчитывать ссылки на объекты из activation object проблем нет.


Еще раз — потенцаильная сложность это функции из host object, типа DOM-модели, но это тоже обходится в transpile-фазе


но компилятор… все еще ждем

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

Information

Rating
Does not participate
Location
Тула, Тульская обл., Россия
Date of birth
Registered
Activity