предисловие
Когда дело доходит до оптимизации производительности, вы определенно можете думать о многих вещах. Например, как изменить конфигурацию Webpack для удовлетворения потребностей более быстрого создания и оптимизации продуктов, например, как оптимизировать производительность страницы и т. д.
На самом деле, в оптимизации производительности есть еще много мест, где можно поиграть, и сегодня я расскажу о некоторых местах, на которые вы не часто обращаете внимание, от разработки до этапа построения CI и финального развертывания и запуска.
этап сборки
Этап сборки делится на две части:
- местное развитие
- CI-сборка
Две части сосредоточены на разных моментах. Первый больше внимания уделяет скорости построения и не предъявляет требований к продукту, ведь построение — очень частое явление при локальной разработке, а медленная скорость означает меньшую эффективность разработки, второй больше внимания уделяет продукту, например файлу размер, количество и другие показатели.Конечно, скорость строительства нельзя назвать полностью беззаботной, но в основном это улучшение скорости строительства на предпосылке обеспечения продукта.
Далее я расскажу об оптимизации производительности, которую мы можем выполнить в этих двух частях.
местное развитие
Если взять в качестве примера Webpack, то эта часть локальной разработки и строительства является наиболее распространенной частью нашей повседневной работы, и если она может принести определенное ускорение, то восприятие все еще достаточно сильное.
Эта часть в основном делится на два этапа:
- начать проект, скажем
yarn start - Измените код сохранения, чтобы активировать горячее обновление.
На первом этапе частота относительно низкая, и медленная скорость в большинстве случаев допустима.
Но второй этап заключается в том, что наша фронтенд-разработка будет ежедневно выполнять десятки, а то и сотни громких операций, а для некоторых средних и крупных проектов время, затраченное на эту часть, может занимать более 10 секунд за один раз. . Если предположить, что Pharaoh изменяет код 100 раз в день, то эта часть должна ждать 15 минут и более каждый день.
Так есть ли способ улучшить эту часть контента? Ответ положительный, и многие читатели уже должны знать об этом типе продукта:Vite.
Vite относится к схеме NoBundle, которую также можно назвать UnBundle и Bundleless, что в любом случае одно и то же. Подобные конкуренты такжеsnowpack,wmrПодождите, конечно, не так знаменит, как бывший.
Если вы использовали Vite, у вас должен быть образ для запуска за считанные секунды и горячее обновление, что является огромным улучшением по сравнению с чистым Webpack.
На фото выше изстатья, проект имеет 150 000 строк кода, что является очень большим проектом.Вы можете обнаружить, что в десятки раз улучшен запуск и горячее обновление, что действительно гладко для опыта разработки. Кроме того, автор ранее также участвовал в исследованиях и разработках внутренней программы NoBundle компании, и полученные данные также весьма впечатляют.
Так почему же Vite приносит такой опыт и как он достигает такого эффекта? Автор кратко расскажет об этом здесь.
Сначала поговорим о построении Webpack на основе Webpack4 и средних и крупных проектов. когда мы выполняемyarn startВ дальнейшем Webpack начнёт упаковывать полностью, а после построения графа зависимостей весь контент будет набираться в несколько файлов, этот процесс построения графа зависимостей и упаковки займёт у нас несколько минут.
Когда запускается горячее обновление, Webpack также должен найти эту ссылку зависимости и снова упаковать ссылку, поэтому этот процесс занимает много времени. Конечно, если вы используете Webpack5, он должен значительно ускориться благодаря постоянному кэшированию.
Но для Vite в этом нет необходимости.
Первый Vite используетсяESBuildДля предварительной сборки зависимостей это особенно мощный компоновщик, написанный на Go, и его эффективность в десятки, а то и в сотни раз выше, чем у JS.Vite необходимо использовать его для обработки модулей и построения сред ESM.
Кроме того, благодаря функции загрузки по требованию ESM, нам не нужно строить графы зависимостей и файлы пакетов при запуске проекта, а компилировать те файлы, которые запрашиваются браузером (например, компилировать TS, вставлять коды горячего обновления, д.), полагаясь на Из-за этой функции мы можем запустить проект очень быстро.
Наконец, когда пользователь инициирует горячее обновление, Vite не нужно поступать так же, как Webpack, но он находит наименьший путь зависимости (как правило, измененный файл), а затем изменяет хэш файла и отправляет его в браузер до истечения срока его действия. Просто кешируйте это.
Основываясь на некоторых из вышеперечисленных функций и ESBuild, Vite в основном не будет замедлять скорость из-за большого количества кода, но для Webpack размер проекта явно замедлит скорость сборки.
Когда читатели увидят это, они могут подумать, что это действительно круто, и готовятся к этому. Впрочем, вот облить вас холодной водой. По результатам нашего внутреннего использования Nobundle и результатам общения автора со многими друзьями, которые делали это решение на крупных заводах, стоимость услуг доступа огромна.Хотя повышение эффективности хорошее, но может быть вводом и выводом по стоимости доступа соотношение не столь впечатляющее. В настоящее время нет хорошего плана доступа, и очень вероятно, что разные проекты попадут в разные ямы.Самая большая причина - среда ESM.
Но автор считает, что Nobundle станет мейнстримом местной разработки и строительства в будущем, потому что опыт разработки слишком гладкий.
Также вероятно, что читатели спросят, запретит ли Vite Webpack или нет. Автор считает, что эти две вещи не являются конкурирующими продуктами. Webpack можно применять к сложным и индивидуальным сценариям, чего Vite не может (и, возможно, не будет делать в будущем). Vite в основном предназначен для улучшения стадии разработки. В лучшем случае Vite может заменить работу Webpack на стадии разработки.
Ниже автор перечислил некоторую информацию, если вам интересно, вы можете узнать о ней:
Наконец, если вы заинтересованы в миграции в своем бизнесе, вы должны прочитать больше статей о миграции на рынке, которые могут помочь вам быстро решить проблемы, когда вы наступаете на яму.
CI
Построение в CI условно разделено на три этапа:
- Установить зависимости
- Обеспечение качества кода
- Построить
Контента, задействованного в первых двух ссылках, немного, и автор быстро перенесет его сюда.
Установить зависимости
Установка зависимостей по-прежнему занимает много времени. Мы можем ускорить эту ссылку, выполнив следующие действия:
- Источник должен быть переключен на источник Taobao или ваш собственный частный источник.
- Кэш node_modules должен быть заполнен
- Если есть возможность, попробуйте пряжу2
Давайте немного поговорим о пряже2 здесь. После обновления до yarn2 будет два варианта, один — решение node_modules, а другой — отказаться от node_modules и вместо этого использовать PnP.
Первая из этих двух схем в принципе не требует перемещения кода в процессе миграции, но может повысить скорость зависимой установки; вторая требует довольно много изменений, и некоторое сопротивление внутреннему продвижению все же есть , но эта схема может сильно уменьшить объем зависимостей и повысить скорость установки.Соотношение ввода-вывода вы можете оценить сами.
Обеспечение качества кода
Обеспечение качества кода обычно делится на две части:
- ESLint
- одиночный тест
Конечно, существуют и другие схемы обеспечения качества, которые здесь не перечислены.
На самом деле у ESLint нет решений по оптимизации, но большинство проектов должны быть оптимизированы при отправке кода локально, но многие люди могут это игнорировать. Предположительно в каждом проекте должен быть husky + Lint-stage, эти два инструмента действительно могут помочь нам при отправке кодаТолько для документов, которые необходимо предоставитькорп. ЭтоИнкрементныйИдея того, что во многих случаях нам нужна эта идея, чтобы помочь нам оптимизировать производительность.
Для одиночного теста многие читатели, возможно, вообще не писали эту вещь. Но если вы сделали несколько пакетов npm или сервисов Node, вы обнаружите, что модульное тестирование совершенно необходимо.
Для крупных проектов существует довольно много тестовых случаев. Возьмем, к примеру, нашу внутреннюю библиотеку компонентов.1000+Тестовый пример выполняется только один раз локальноyarn testдостаточно, чтобы потратитьдве-три минуты, не говоря уже о скорости работы в облаке. Но на самом деле код, который мы отправляем каждый раз, влияет на гораздо меньшее количество тестовых случаев, и каждый раз на полное выполнение одного теста уходит слишком много времени.
К этому моменту читатели должны помнить об инкрементах, о которых я упоминал выше. Правильно, здесь мы можем полностью использовать инкременты для ускорения выполнения одиночных тестов. Если вы используете фреймворк Jest, вы можете узнать о нем и—onlyChangedСвязанные параметры для реализации добавочного модульного тестирования.
Построить
Когда дело доходит до оптимизации сборки, многие читатели, вероятно, скажут, что это сделаю я. В конце концов, оптимизация конфигурации Webpack — это уже плохой вопрос для интервью, а статей на рынке бесконечное множество.
Поэтому автор не будет рассказывать о том, как нам следует настраивать Webpack таким образом, если читатели в этом нуждаются, они могут просматривать информацию самостоятельно.
На самом деле, в дополнение к изменению Webpack для достижения цели оптимизации производительности, обновленная версия также будет иметь большие сюрпризы.
Например, после обновления с 4 до 5 мы можем добиться повышения эффективности с помощью следующих новых функций:
- Постоянный кеш, о котором упоминалось выше, может помочь нам улучшить скорость вторичного запуска и HMR.
- Лучшее использование возможности встряхивания деревьев, что может лучше очищать неиспользованный экспорт и еще больше уменьшать размер продуктов сборки.
- Возможность предварительной упаковки для уменьшения объема кода за счет статических вычислений.
- Объединенные модули, которые могут загружать удаленные модули или зависимости во время выполнения, сокращая время, затрачиваемое на создание
Автор перечислил некоторые преимущества, которые может принести обновление Webpack.Если вас интересует какая-либо функция, вы можете самостоятельно найти статью.
Кроме того, на самом деле оптимизация скорости построения, о которой мы часто говорим, есть один момент, на который мало кто обращает внимание, но он также оказывает большое влияние на скорость построения, то есть сжатие кода.
если вы использовалиSpeed Measure PluginС помощью этого плагина вы можете убедиться, что то, что сказал автор, правда. Для больших приложений, даже если вы используете многопоточность для сжатия, это может занять от 20 до 30 секунд.
Конечно, мы можем оптимизировать этот этап, и используемые инструменты были упомянуты выше, то есть ESBuild. Основное внимание в ESBuild уделяется быстрой сборке.Из официальной таблицы сравнения производительности видно, что это уменьшение размерности для борьбы с другими сборщиками.
Сотни раз ужас (конечно, автор не может получить такие данные), но даже если это действительно быстро в строительстве, все еще есть некоторые проблемы (самая большая проблема - это обработка CSS), что делает его нереалистичным Перейти к производству. Но на самом деле Esbuild также поддерживает использование сжатого кода, и риск может быть в основном игнорироваться. Автор фактически оценил 30% до 40% улучшения скорости в бизнес-проектах, что довольно впечатляет.
В дополнение к этому в дополнение к вышеуказанному сказано, фактически, в этой части здания мы можем повысить эффективность инкрементных идей.
Для многостраничных приложений в большинстве случаев код, который мы изменяем каждый раз при публикации, не влияет на все записи. Следовательно, запись, которая не была затронута, на самом деле не нужно создавать заново, и можно напрямую использовать предыдущий кэш. Затем, в соответствии с этой идеей, нам нужно выяснить все измененные файлы от последнего выпуска до настоящего и записи, затронутые этими файлами, перед сборкой каждый раз, и, наконец, динамически изменить конфигурацию записи Webpack для достижения этого.инкрементная сборка.
Просто делайте то, что вы говорите, это общая идея пошагового строительства.
Первый — найти файлы, изменившиеся с момента последнего релиза, это очень просто, и сделать это можно одной строкой команды:
git diff --name-only {git tag / commit sha}
Не забудьте пометить или записать идентификатор коммита после развертывания и передать его при следующем выполнении команды.
Когда мы получим имя файла после изменения, нужно найти вход в влияние этих документов, необходимо приступить к построению дерева зависимостей. Хотя Webpack поможет нам это построить, но нам не нужно использовать тяжелые вещи, чтобы найти выделенное дерево зависимостей библиотеки на линии, вы можете выбратьmadgeили другие подобные продукты.
Далее нам нужно только сопоставить файлы, чтобы найти затронутые записи, а затем динамически изменить конфигурацию Webpack.entryсвойства могут быть построены.
В конце концов, нам просто нужно заменить старый входной продукт на содержимое сборки, и об этом можно не беспокоиться.
На самом деле инкрементное построение этого многостраничного приложения очень похоже на развертывание в монорепозитории. Если нам нужно только развернуть пакет с изменённым кодом в монорепозитории, то логика развёртывания кода очень похожа, и это тоже найти пострадавший пакет (запись в многостраничном приложении), а потом собрать и опубликовать.
Если в вашем бизнесе также есть проекты многостраничных приложений, вы можете попробовать это решение, и преимущества должны быть значительными.
резюме
Сказав так много, автор резюмирует рассмотренные выше методы оптимизации:
- На этапе разработки я пытался использовать NoBundle для замены Webpack, который работал хорошо, но необходимо учитывать стоимость миграции.
- ESBuild хорош как для сборки, так и для сжатия кода. Первое рискованно, и есть сценарии с плохой обработкой, в то время как второе имеет небольшой риск и может повысить эффективность.
- Для ускорения установки зависимостей можно начать с исходников, кешировать и апгрейдить yarn2
- Фаза обеспечения качества кода крупномасштабных проектов занимает слишком много времени. Рассмотрите возможность использования дополнительных решений для ускорения процесса. Конечно, если вы чувствуете себя более комфортно, повторяя все заново, в этом нет ничего плохого.
- На уровне построения CI настройка Webpack плоха.Кто не знает, тот и сам разберется.Кроме того,обновление Webpack также даст неожиданные преимущества.Конечно, еще есть некоторые затраты на миграцию.
- Многостраничные приложения не должны создавать все записи каждый раз, можно создавать только те записи, на которые влияет код.
- Инкрементальное мышление довольно распространено в оптимизации производительности.
После выхода в интернет
Про общую оптимизацию производительности после выхода в интернет тоже говорят плохо, она начинается только с сетевых протоколов, CSS и настройки Webpack, но я еще хочу поговорить о другом.
Поскольку мы хотим говорить об оптимизации производительности, то мы должны знать, где есть проблема с производительностью, иначе это пустая оптимизация. Как выявить оптимизацию производительности и какие существуют показатели эффективности — также часто задаваемые автором вопросы на интервью (конечно, интервьюируемый написал этот аспект в резюме), но чаще всего полученные ответы, по мнению автора, неверны, и не может быть Определить, действительно ли другая сторона выполнила эту оптимизацию.
Например, когда дело доходит до показателей производительности, если вы спросите десять человек и девять человек, они скажут время белого экрана, но на самом деле время белого экрана в настоящее время не является квалифицированным показателем. Загрузочные или каркасные экраны будут существовать в большинстве приложений, когда они откроют экран. Пройдет некоторое время, прежде чем этот контент перейдет к контенту, который интересует пользователей на странице. Однако, если мы будем полагаться только на сбор времени белого экрана, чтобы судить о том, что пользователь видит DOM, это неправильный подход.Недостаточно оптимизировать открытие экрана только по этому показателю.Мы должны собирать время, когда пользователь видит DOM. пользователь видит настоящий DOM.
На этом этапе мы можем собрать индикатор LCP (Largest Contentful Paint), который поможет нам записать временную метку самого большого отрисовки контента на странице.
Благодаря этому индикатору плюс время белого экрана мы можем правильно оптимизировать время открытия экрана. Кроме того, здесь также можно не использовать индикатор LCP, мы можем сами управлять ключевым DOM для достижения персонализированного сбора.
Помимо индикатора LCP появилось много новых индикаторов, если вам интересно, вы можете ознакомиться с предыдущими работами автора.статья, в статье описано несколько новых индикаторов и способы оптимизации этих индикаторов.
наконец
Это все для этой статьи. Оптимизация производительности — это большая тема, и в дополнение к этим привычным методам на самом деле есть много решений, которые можно сделать.
Если у вас есть какие-либо вопросы, пожалуйста, поделитесь в разделе комментариев.