- Как масштабировать и оптимизировать веб-приложения
- Оптимизация веб-приложений
- Минификация кода
- Кеширование
- Оптимизация изображений
- Масштабирование веб-приложений
- Вертикальное масштабирование
- Горизонтальное масштабирование
- Заключение
- Как повысить производительность фронтенда веб-приложения: пять советов
- Предисловие
- 1. Поиск: вместо обычных массивов — объекты и ассоциативные массивы
- 2. Вместо исключений — условный оператор «if»
- 3. Чем меньше циклов, тем лучше
- 4. Используйте обычные циклы «for»
- 5. Для работы с DOM используйте встроенные функции
- Дополнительные материалы
Как масштабировать и оптимизировать веб-приложения
Веб-приложения играют важную роль в современном мире интернет-технологий. Множество сервисов и платформ зависят от производительности и надежности веб-приложений. В этой статье мы рассмотрим ключевые аспекты масштабирования и оптимизации веб-приложений.
Оптимизация веб-приложений
Оптимизация веб-приложений состоит из нескольких этапов. Ниже мы рассмотрим наиболее важные из них.
Минификация кода
Минификация – это процесс удаления ненужных символов (пробелы, табуляции, комментарии) из исходного кода вашего приложения. Это делает файлы меньше и быстрее загружаемыми.
До минификации:
После минификации:
Кеширование
Кеширование данных позволяет сократить количество запросов к серверу и уменьшает время загрузки страницы. Используйте кеширование статического контента, такого как изображения, стили и скрипты.
Оптимизация изображений
Оптимизация изображений включает в себя сжатие и изменение размеров изображений. Это позволяет уменьшить время загрузки страницы и сэкономить трафик пользователя.
🚫 Большое изображение (500x500px, 100KB)
✅ Оптимизированное изображение (100x100px, 10KB)
Масштабирование веб-приложений
Масштабирование веб-приложений позволяет справляться с увеличением нагрузки на сервер и обеспечивать стабильность работы. Существует два основных подхода к масштабированию: вертикальное и горизонтальное.
Вертикальное масштабирование
Вертикальное масштабирование заключается в увеличении мощности сервера (процессор, память, дисковое пространство). Это подходит для небольших проектов с низкой нагрузкой.
Горизонтальное масштабирование
Горизонтальное масштабирование включает в себя добавление дополнительных серверов, которые работают параллельно и распределяют нагрузку между собой. Это решение подходит для крупных проектов с высокой нагрузкой.
Заключение
Оптимизация и масштабирование веб-приложений являются важными аспектами разработки. Применение этих подходов поможет вам создать быстрые и надежные веб-приложения, которые смогут справиться с возрастающей нагрузкой и удовлетворить потребности пользователей.
Если вы хотите углубиться в изучение веб-разработки и научиться создавать оптимизированные и масштабируемые веб-приложения, рекомендую обратиться к курсам знакомой школы по веб-разработке.
Как повысить производительность фронтенда веб-приложения: пять советов
Во многих своих фронтендовых проектах я в какой-то момент сталкивался со снижением производительности — обычно такое случается, когда возрастает сложность приложения, и это нормально. Тем не менее, разработчики всё же ответственны за производительность, поэтому в своей статье я дам пять советов по оптимизации приложений, которые применяю сам: какие-то могут показаться очевидными, какие-то затрагивают основные принципы программирования — но, думаю, освежить память лишним не будет. Каждый совет подкреплен тестами: можно запустить их самостоятельно и проверить производительность.
Предисловие
Запомните: если коду оптимизация не нужна, не лезьте в него. Безусловно, код, который вы пишете, должен работать быстро, и всегда можно придумать более быстрый алгоритм — но написанное должно оставаться понятным для других разработчиков. В лекции «Программирование как искусство» Дональд Кнут высказал очень важную мысль об оптимизации кода:
Настоящая проблема заключалась в том, что программисты тратили слишком много времени в заботах об эффективности в неподходящих местах и в неуместное время. Преждевременная оптимизация — это корень всех ошибок в программировании (или, по крайней мере, большинства).
1. Поиск: вместо обычных массивов — объекты и ассоциативные массивы
При работе с данными часто возникают ситуации, когда нужно, например, найти объект, сделать что-то с ним, затем найти другой объект, и так далее. Наиболее распространенной структурой данных в JS является массив, поэтому хранение данных в них — нормальная практика. Однако всякий раз, когда в массиве нужно что-то найти, приходится использовать такие методы, как «find», «indexOf», «filter», или выполнять итерации с циклами — то есть, нужно перебирать элементы от начала до конца. Таким образом мы выполняем линейный поиск, сложность которого — 0(n) (в худшем случае нам понадобится выполнить столько сравнений, сколько есть элементов в массиве). Если делать такую операцию пару раз на небольших массивах, влияние на производительность будет невелико. Однако если элементов у нас немало, и операция выполняется много раз, производительность обязательно просядет.
В таком случае хорошим решением будет преобразовать обычный массив в объект или ассоциативный массив и выполнять поиск по ключам: в этих структурах доступ к элементам можно получать со сложностью O(1) — у нас будет один вызов памяти, независимо от размера. Повышение скорости работы достигается за счет использования структуры данных, называемой хэш-таблицей.
Протестировать производительность можно здесь: https://jsperf.com/finding-element-object-vs-map-vs-array/1. Ниже приведены мои результаты:
Разница весьма значительна: для ассоциативного массива и объекта у меня получились миллионы операций в секунду, тогда как для массива лучший результат — чуть более сотни операций. Безусловно, здесь не учитывается преобразование данных, но даже с учетом его операция будет выполняться намного быстрее.
2. Вместо исключений — условный оператор «if»
Иногда кажется, что легче пропустить проверку на «null» и просто перехватывать соответствующие исключения. Это, понятно, плохая привычка — так делать не надо, и если у вас в коде такое есть, просто перепишите соответствующие участки. Но чтобы вас окончательно убедить, я подкреплю эту рекомендацию тестами. Я решил проверить три способа выполнения проверок: выражение «try-catch», условие «if» и вычисление «короткого замыкания».
Думаю, отсюда очевидно, что выполнять проверку на «null» нужно обязательно. Кроме того, как можно видеть, между условием «if» и вычислением «короткого замыкания» разницы почти нет — к чему душа лежит, то и применяйте.
3. Чем меньше циклов, тем лучше
Еще одно очевидное, но, возможно, небесспорное соображение. Для массивов есть много удобных функций: «map», «filter», «reduce», — поэтому их использование выглядит заманчиво, да и код с ними выглядит аккуратнее и читается проще. Но когда встает вопрос повышения производительности, можно попытаться сократить число вызываемых функций. Я решил разобрать два случая: 1) «filter», затем «map», и 2) «filter», затем «reduce», — и сравнить их с функциональной цепочкой, «forEach» и традиционным циклом «for». Почему именно эти два случая? Из тестов будет видно, что получаемые преимущества могут быть не очень значительными. Кроме того, во втором случае я попробовал также использовать «filter» при вызове «reduce».
Видно, что один цикл быстрее, но разница невелика. Причина такого небольшого отрыва — операция «push», которая при использовании «map» не требуется. Поэтому в этом случае можно задуматься, действительно ли так уж необходимо переходить к одному циклу.
Здесь разница уже значительнее: объединение двух функций в одну ускорило выполнение почти вдвое. Тем не менее, переход на традиционный цикл «for» дает намного более существенный прирост скорости.
4. Используйте обычные циклы «for»
Этот совет тоже может показаться спорным, ведь разработчики любят функциональные циклы: они хорошо читаются и могут упрощать работу. Однако они менее эффективны, чем традиционные циклы. Думаю, вы уже могли заметить разницу в использовании циклов «for», но давайте взглянем на нее в отдельном тесте: https://jsperf.com/for-loops-in-few-different-ways/. Как можно видеть, кроме встроенных механизмов я также проверил «forEach» из библиотеки «Lodash» и «each» из «jQuery». Результаты:
И мы снова видим, что самый простой цикл «for» работает гораздо быстрее остальных. Правда, эти циклы хороши только для массивов — в случае других итерируемых объектов следует использовать «forEach», «for…of» или непосредственно итератор. А вот «for…in» нужно применять, только если других способов нет вообще. Кроме того, помните, что «for…in» принимает все свойства объекта (а в массиве свойства — это индексы), что может привести к непредсказуемым результатам. Удивительно, но методы из Lodash и jQuery оказались не так уж плохи с точки зрения производительности, поэтому в некоторых случаях ими можно спокойно пользоваться вместо встроенного «forEach» (интересно, что в тесте цикл из Lodash сработал быстрее встроенного).
5. Для работы с DOM используйте встроенные функции
Иногда смотришь на чужой код и видишь, что разработчик импортировал jQuery только для манипуляций с DOM — уверен, вам тоже такое встречалось, ведь это одна из популярнейших библиотек JavaScript. Понятно, что в использовании библиотек для управления DOM нет ничего плохого: сегодня мы применяем React и Angular, а они делают то же самое. Однако некоторым иногда кажется, что jQuery нужно использовать даже для простых операций по извлечению элемента из DOM и внесению в него незначительных изменений.
Вот сравнение встроенных функций для DOM и аналогичных операций JQuery в трех различных случаях: https://jsperf.com/native-dom-functions-vs-jquery/1. Мои результаты:
И снова самые базовые функции — «getElementById» и «getElementsByClassName» — при просмотре DOM оказались самыми быстрыми. В случае идентификаторов и расширенных селекторов «querySelector» тоже быстрее, чем jQuery. И только в одном случае «querySelectorAll» медленнее, чем jQuery (получение элементов по имени класса). Подробнее о том, чем и как можно заменить jQuery, смотрите здесь: http://youmightnotneedjquery.com.
Понятно, что если вы уже используете библиотеку для управления DOM, настоятельно рекомендуется придерживаться ее — однако для простых случаев достаточно и встроенных инструментов.
Дополнительные материалы
Приведенные пять советов помогут писать более «быстрый» код на JavaScript. Но если вам интересно почитать об оптимизации производительности подробнее, вот несколько рекомендаций:
1. Оптимизация бандлов JavaScript с помощью Webpack: это очень обширная тема, но если всё сделать правильно, загрузка приложений может значительно ускориться.
2. Структуры данных, основные алгоритмы и их сложность: многие считают, что это «просто теория», однако мы в первом же пункте увидели, как эта теория работает на практике.
3. Тесты на странице jsPerf: здесь можно ознакомиться со сравнением различных способов выполнения одной и той же задачи в JavaScript и при этом увидеть важный на практике показатель — разницу в скорости.
Перевод статьи выполнен в Alconost.
Alconost занимается локализацией игр, приложений и сайтов на 70 языков. Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов.
Мы также делаем рекламные и обучающие видеоролики — для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.
- alconost
- javascript
- front-end разработка
- front-end development
- app
- performance optimization
- performance tests
- performance
- development tools
- алконост
- джаваскрипт
- приложения
- оптимизация производительности
- тесты производительности
- производительность