Действительно ли node.js работает медленнее в Windows? Как использование пряжи вместо npm влияет на ваш рабочий процесс? Влияет ли антивирус в реальном времени на время вашего строительства? Позвольте мне попытаться ответить на эти вопросы с помощью быстрого теста и реальных, экспериментально собранных чисел.
Я всегда считал себя далеким от религиозности в области операционных систем, платформ и браузеров. Очевидно, что у меня есть некоторые предпочтения, но я стараюсь не вовлекать их в обсуждение. Кто-то использует Linux? Круто, если им это хорошо. Windows? Отлично, может им просто нравится этот опыт. MacOS? Я не против. Fire Fox? Опера? Хром? Все нормально.
Говоря об операционных системах, предпочтение редко бывает связано с производительностью - обычно это вопрос удобства, деталей и эстетики. Очевидно, можно было бы сказать, что macOS невероятно быстра, но в основном это результат точно подобранного высокопроизводительного оборудования, используемого платформой Mac / MacBook.
Поскольку я работаю с различными проектами и инструментами для решения проблем моих коллег по команде, я часто меняю рабочую среду: часть моей работы выполняется с использованием MacBook с macOS, некоторые части выполняются в Windows, время от времени перескакиваю на линукс. И обычно существенной разницы не замечал.
Однако несколько месяцев назад я начал чувствовать легкий… зуд. У меня возникло ощущение, что производительность интерфейсных инструментов разработки на основе node.js ограничивается средой Windows. Работать было нормально, но я не мог избавиться от ощущения, что npm
, node
, yarn
и подобные инструменты работают… медленнее, чем в системах linux / macOS. Очевидно я был не один - было несколько сообщений о подобных переживаниях, но без надлежащих выводов.
Любопытство взяло верх, и мне удалось подсчитать некоторые цифры.
Результаты были однозначными. Просмотрите эту статью, чтобы узнать, что я обнаружил.
Метод
Основная цель заключалась в том, чтобы сравнить производительность Windows и Linux, протестировать их на наиболее распространенных сценариях:
- строительство нового веб-приложения
- установка зависимостей узлов
- создание пакета, то есть создание веб-приложения
Планировалось включить macOS в тесты, но у меня не было возможности запустить Windows и macOS на одном и том же оборудовании. В итоге мы сравнили производительность двух популярных систем:
- Windows 10 Pro (сборка 1809, обновление за октябрь 2018 г.)
- Ubuntu 18.04.2 LTS с ядром Linux 5.0.0–23
Выбирая технологии, которые будут служить наилучшим эталоном, я обратился к React с помощью TypeScript и Webpack (из пакета create-react-app). Кроме того, я решил протестировать и NPM, и yarn с точки зрения управления зависимостями. Время сборки проверялось не только на небольшом количестве файлов, но и на сотнях. Я закончил разработку схемы теста, состоящей из следующих шагов:
- Создайте шаблон приложения с помощью create-response-app с включенным TypeScript (тест №1)
- Сбросьте зависимости (удалите node_modules) и извлеките конфигурацию
- Установите зависимости:
- с помощью npm install с сохранением
package-lock.json
(контрольный показатель 2) - с помощью npm install при удалении
package-lock.json
при каждом запуске (тест № 3) - используя пряжу с сохранением
yarn.lock
(эталон №4) - использование yarn install при удалении yarn.lock при каждом запуске (тест № 5)
4. Создайте приложение с шаблоном:
- небольшое количество (3) исходных файлов (тест №6)
- наличие большого количества (300+) исходных файлов (тест №7)
Чтобы результаты теста были максимально достоверными и правдивыми, были применены следующие правила:
- Обе протестированные системы изначально работали на одной машине без виртуализации (Asus P25P20L с процессором i5–5200U и 16 ГБ ОЗУ).
- Обе системы были недавно установлены. Во время тестирования не было других запущенных приложений.
- Каждый тест проводился не менее 5 раз, чтобы свести к минимуму случайность. Окончательный результат - это средний результат тестовых прогонов.
- Машина была подключена к стабильному интернет-каналу на основе оптоволокна с пропускной способностью 300/300 Мбит / с. В обеих системах заранее был проведен тест на подключение к Интернету.
- Перед первым запуском каждого теста в серии выполнялся предварительный запуск, чтобы подготовить и прогреть кеш приложения.
Кроме того, одни и те же версии node.js и других инструментов использовались на двух платформах:
- узел 12.7.0
- npm 6.10.0
- create-react-app 3.0.1
- пряжа 1.17.3
Очевидно, что время было основным измеряемым показателем. Конечно, я не использовал для этого ручной секундомер - чтобы получить точный результат, я создал небольшое приложение node.js, которое выполняло за меня запуск теста и измерения. Вот как это выглядело в случае разработки приложений:
Как упоминалось ранее, каждый тест проводился не менее 5 раз, и рассчитанное среднее значение приводилось к окончательному результату.
В случае тестов Windows был еще один существенный фактор - в версии 10 по умолчанию установлен антивирус, который сканирует всю файловую активность в режиме реального времени. Поскольку я думал, что это может сильно повлиять (и мальчик, я был прав!) На производительность npm и yarn, тесты Windows проводились независимо с упомянутым антивирусом, как включенным, так и отключенным.
Результаты
Тест №1: создание экземпляра приложения с помощью приложения create response
Описание:
Во время каждого тестового запуска вызывалась команда create-response-app, чтобы вывести приложение React и TypeScript в новый каталог.
Результаты:
Комментарий:
Ubuntu - явный победитель с приростом более чем на 25% по сравнению с Windows! Кроме того, мы можем видеть, насколько сильно антивирус влияет на производительность - ему потребовалось почти вдвое больше времени для создания каркаса приложения, когда оно было включено.
Тест №2: установка зависимостей с помощью npm install с сохранением package-lock.json
Описание:
Во время каждого тестового запуска вызывалась команда npm install для восстановления зависимостей. Ранее каталог `node_modules` был удален, но файл package-lock.json остался на месте.
Результаты:
Комментарий:
Между Ubuntu и Windows огромная пропасть - разница почти в три раза. Кроме того, антивирус в Windows добавляет дополнительные 100% накладных расходов.
Тест №3: установка зависимостей с помощью npm install при удалении package-lock.json при каждом запуске
Описание:
Во время каждого тестового запуска вызывалась команда npm install для восстановления зависимостей. Предварительно были удалены и `node_modules`, и package-lock.json.
Результаты:
Комментарий:
Опять же, разрыв между Ubuntu и Windows довольно велик, однако соотношение уменьшилось. Обратите внимание, что удаление package-lock.json привело к увеличению объема необходимых вычислений по сравнению с изменением дисковых операций.
Тест №4: установка зависимостей с помощью yarn при сохранении yarn.lock
Описание:
Во время каждого тестового прогона вызывалась команда `yarn` для восстановления зависимостей. Ранее каталог `node_modules` был удален, но файл yarn.lock остался на месте.
Результаты:
Комментарий:
Использование Yarn продемонстрировало значительное улучшение по сравнению с npm в обеих системах, но все же выявило слабые места версии для Windows. Разница между включенным и отключенным антивирусом значительно меньше, что указывает на меньшее количество операций с диском по сравнению с npm.
Тест №5: установка зависимостей с помощью yarn install при удалении yarn.lock при каждом запуске
Описание:
Во время каждого тестового прогона вызывалась команда `yarn` для восстановления зависимостей. Предварительно были удалены и `node_modules`, и yarn.lock.
Результаты:
Комментарий:
Отсутствие использования файла блокировки при установке зависимостей с помощью yarn привело к значительному снижению производительности. Кроме того, умеренно уменьшились различия между двумя операционными системами.
Контрольный тест № 6. Создание приложения-шаблона с небольшим количеством (3) исходных файлов
Описание:
Во время каждого запуска теста Webpack и транспилятор машинописного текста вызывались с помощью команды npm run build. Исходный код состоит из трех файлов кода TypeScript среднего размера. Перед каждым тестом удалялась директория с выходом бандла.
Результаты:
Комментарий:
Наконец, узел, работающий в Windows, догоняет и показывает производительность, аналогичную той, что работает в Ubuntu. Это указывает на то, что, хотя мы имеем дело с большим количеством вычислений по сравнению с дисковыми / сетевыми операциями, Windows существенно не отстает - пока у нас не включен антивирус в реальном времени.
Контрольный тест № 7. Создайте приложение с шаблоном, содержащее большое количество (более 300) исходных файлов
Описание:
Во время каждого запуска теста Webpack и транспилятор Typescript вызывались с помощью команды npm run build. Исходный код состоит из более чем 300 файлов кода TypeScript среднего размера. Каждый из файлов кода включал 10 экспортируемых переменных и экспорт по умолчанию (см. Прикрепленный тестовый репозиторий). Они были объединены с использованием древовидной структуры с несколькими уровнями файлов. В итоге все постепенно было импортировано в основной файл index.ts. Как и раньше, перед каждым запуском теста каталог с бандлом удалялся.
Результаты:
Комментарий:
По сравнению с версией с меньшим количеством файлов, этот тест показывает более заметную разницу между узлом, работающим в Ubuntu, и узлом в Windows. Что интересно, в отличие от предыдущего - на этот раз антивирус не сильно повлиял на результат. Имея в виду, что мы не выводим много файлов (результат объединяется Wepack), это означает, что антивирус имеет значение только количество запускаемых исполняемых файлов.
Выводы и выводы
Пришло время подвести итоги! В среднем задачи, выполняемые в Ubuntu, имели примерно на 41% более высокую производительность, чем в Windows. Чем больше было задействовано дисковых операций, тем значительнее разница.
Говоря о Windows, оказывается, что включение антивируса приводит к снижению производительности на 44%, что указывает на то, что разработчик не должен забывать занести узел и npm в белый список - в противном случае это серьезно снизит время обработки.
Случайно оказывается, что эксперимент - чертовски хорошая реклама использования пряжи. Во всех тестах он работал значительно быстрее, чем npm - в среднем он работал примерно на 32% быстрее.
И, возвращаясь к основному вопросу, цифры довольно ясны - инструменты на основе node.js дают значительно худшую производительность при работе в Windows. В чем может быть причина? Проблема может заключаться не в Windows или самом node.js - в конце концов, в обоих сценариях это собственный исполняемый файл, который обрабатывается на ЦП.
Я считаю, что проблема в том, как они взаимодействуют на уровне ввода-вывода.
Обратите внимание, что наиболее существенные различия возникают в тестах на основе npm
- в этих сценариях тысячи небольших дисковых операций выполняются с небольшими файлами. И именно здесь файловая система NTFS может отставать от системы Ubuntu ext4 - просто она менее оптимизирована для множества небольших операций. Обратите внимание, что этот процесс также сильно использует сеть - когда кеш пуст, npm Mush-запрос для каждого пакета отдельно. Это может указывать на то, что сетевой уровень Windows недостаточно отзывчив, чтобы обеспечить максимальную потенциальную производительность, когда сотни HTTP-запросов необходимо обрабатывать и быстро переключать. Тема не нова - погуглив, можно найти статьи, описывающие прямое измерение производительности файловых систем.
Что это значит для нас, фронтенд-разработчиков? Конечно, в большинстве сценариев работа в Windows приводит к потере всего нескольких секунд в день по сравнению с Linux, что для многих не является платой за отказ от своей любимой среды. Использование NPM в Windows может быть медленнее, но, в конце концов, мы не переустанавливаем все зависимости несколько раз в день. Однако, если ваш проект тяжелый (сотни исходных файлов), включает в себя более сложный процесс транспиляции (например, несколько загрузчиков и TypeScript) и требует, чтобы вы собирали его очень часто (например, частые выпуски в разных средах), вы можете потерять значительную часть времени. и переход на Linux можно было бы рассмотреть в целях экономии времени. То же самое относится к интенсивно используемым конвейерам CI / CD - если вы используете конвейер на базе Windows (например, в Azure DevOps), помимо затрат на лицензирование, это может быть дороже только из-за затраченного времени на сборку.
Означает ли это, что вам следует отказаться от Windows? Неа. Но теперь вы знаете цену.
Если вы хотите поиграть с ним самостоятельно и получить свои собственные результаты (и выводы!), Не стесняйтесь использовать тестовый код, который я использовал:
https://github.com/hzub/node-perf -test
Репозиторий включает тестовый код и пример скаффолдинга приложения, которые использовались в этой статье. Не забудьте поделиться своими результатами!
Ваше здоровье!