Использование функций на массивах, типа
1. Выделения и потом уничтожения промежуточных массивов
2. Cоздавания циклов в циклах ( сложность
Например, код 1. ниже выполняется в 2-3 раза дольше, чем код 2.
#js #optimization
filter
, map
и других, очень удобно и даёт красивый код, но может создавать проблемы в производительности из-за:1. Выделения и потом уничтожения промежуточных массивов
2. Cоздавания циклов в циклах ( сложность
O(N^2)
), хотя весь код можно разместить в одном цикле ( O(N)
)Например, код 1. ниже выполняется в 2-3 раза дольше, чем код 2.
// setup:
const numbers = Array.from({ length: 10000 }).map(() => Math.random())
// 1. functional
const result =
numbers
.map(n => Math.round(n * 10))
.filter(n => n % 2 === 0)
.reduce((a, n) => a + n, 0)
// 2. imperative
let result = 0
for (let i = 0; i < numbers.length; i++) {
let n = Math.round(numbers[i] * 10)
if (n % 2 !== 0) continue
result = result + n
}
#js #optimization
Во всех браузерах кроме Firefox реализован Fetch Priority API
Это атрибут
Это важно в первую очередь для метрик
Учитывая, что ресурсов на странице может быть много, а браузеры выделяют на сетевые соединения около 5 потоков на один домен, то может образоваться очередь, и ваша
Также можно указать
#tip #optimization #webvitals
Это атрибут
fetchpriority
на тэгах img
, script
, link
, который указывает, насколько приоритетен данный ресурс для загрузки.Это важно в первую очередь для метрик
Core Web Vitals
, а именно - LCP
. Если элемент LCP
- картинка, имеет смысл указать ей fetchpriority="high"
.Учитывая, что ресурсов на странице может быть много, а браузеры выделяют на сетевые соединения около 5 потоков на один домен, то может образоваться очередь, и ваша
LCP
картинка появится не сразу.Также можно указать
fetchpriority="low"
для картинок вне области видимости, - в том числе, в слайдере.#tip #optimization #webvitals
web.dev
Optimize resource loading with the Fetch Priority API | Articles | web.dev
The Fetch Priority API indicates the relative priority of resources to the browser. It can enable optimal loading and improve Core Web Vitals.
Если у вас есть большая строка в JavaScript, и вы с помощью
Также утверждение, что конкатенация строк - дорогая операция, уже не соответствует действительности. Например, на массиве строк
будет медленней конкатенации через reduce:
Опять же из-за особенностей V8. Более того, конкатенация будет даже быстрее шаблонов строк (`
В целях оптимизации работы со строками следует избегать мутирующих операций.
#tip #js #optimization
slice()
вытаскиваете из нее подстроку, то эта подстрока не даст Garbage Collector-у уничтожить большую строку, даже если вы на нее больше не ссылаетесь. Это верно в V8, где подстрока оформляется как С++ указатель на нужное место в большой строке. В результате при обработке большого числа строковых данных могут происходить утечки памяти. Чтобы избежать этого можно делать копирование подстроки.Также утверждение, что конкатенация строк - дорогая операция, уже не соответствует действительности. Например, на массиве строк
.join(' ')
будет медленней конкатенации через reduce:
.reduce((acc, c) => acc + ' ' + c, '')
Опять же из-за особенностей V8. Более того, конкатенация будет даже быстрее шаблонов строк (`
Hello ${name}
`), хотя обычно учат обратному.В целях оптимизации работы со строками следует избегать мутирующих операций.
#tip #js #optimization
Подбирайте для своих данных подходящую структуру, в зависимости от операций над ними.
Это сильно влияет на производительность
В примере ниже
#js #optimization
Это сильно влияет на производительность
В примере ниже
Array.includes()
примерно в три раза медленней, чем Set.has()
// setup:
const userIds = Array.from({ length: 1000 }).map((_, i) => i)
const adminIdsArray = userIds.slice(0, 10)
const adminIdsSet = new Set(adminIdsArray)
// 1. Array
let num = 0
for (let i = 0; i < userIds.length; i++) {
if (adminIdsArray.includes(userIds[i])) { num += 1 }
}
// 2. Set
let num = 0
for (let i = 0; i < userIds.length; i++) {
if (adminIdsSet.has(userIds[i])) { num += 1 }
}
#js #optimization
В подтверждение нашему недавнему совету по оптимизации js кода, твит Эвана:
Самое приятное в этом то, что вы можете писать хороший функциональный код, который выполняет итерации над коллекциями (аналогично map, filter и т.д.) с оптимизированной вручную производительностью.
Каждый раз, когда я использую map/filter в JS вместо обычных циклов for, мне кажется, что я добровольно отказываюсь от производительности.
#tip #optimization #evanyou
Самое приятное в этом то, что вы можете писать хороший функциональный код, который выполняет итерации над коллекциями (аналогично map, filter и т.д.) с оптимизированной вручную производительностью.
Каждый раз, когда я использую map/filter в JS вместо обычных циклов for, мне кажется, что я добровольно отказываюсь от производительности.
#tip #optimization #evanyou
Самое время узнать, за счет чего главная лендинговая статичная страница
На скриншоте бандлофобии разрезолвились не все пакеты
Первая тройка тяжеловесов:
1.
2.
3.
#gitlab #optimization #nuxt #i18n
GitLab
смогла набрать 13Мб в скриптахНа скриншоте бандлофобии разрезолвились не все пакеты
Первая тройка тяжеловесов:
1.
@nuxtjs/i18n
- 2.5Mb2.
slippers-ui
(GitLab's Marketing Design System) - 1.8Mb3.
vue-mermaid-string
(построение диаграмм) - 1.1Mb#gitlab #optimization #nuxt #i18n
Немного OSINT-a в ленту.
Давайте еще поизучаем результаты исследования бандла лендинга GitLab, потому что это интересно и познавательно.
Первая тройка тяжеловесов:
1.
2.
3.
На третьем месте хорошая библиотека для генерации налету диаграмм по тексту
На втором - slippers-ui, это гитлабовский относительно небольшой (20 компонент) UI kit. Без какого- либо тришейкинга и оптимизации, естественно. Очень много, с учетом того, что любая современная UI библиотека весит в несколько раз меньше.
Ну и победитель - то, за что так любят Nuxt. Это когда он берет что-то хорошее и делает его еще лучше. В этот раз он взял
Используя pkg-size.dev смотрим сперва на vue-i18n, отключив учет
Install size: 2.8MB / 6 packages
Bundle size: 73KB minified (23KB gzip) / 9 modules
Очень неплохо для
То же с @nuxtjs/i18n:
Install size: 61MB / 239 packages
Bundle size: Не собрался (ошибки)
Bundlephobia тоже дала ошибки при сборке
Самая простая реализация
#nuxt #optimization #i18n #gitlab
Давайте еще поизучаем результаты исследования бандла лендинга GitLab, потому что это интересно и познавательно.
Первая тройка тяжеловесов:
1.
@nuxtjs/i18n
- 2.5Mb2.
slippers-ui
(GitLab's Marketing Design System) - 1.8Mb3.
vue-mermaid-string
(построение диаграмм) - 1.1MbНа третьем месте хорошая библиотека для генерации налету диаграмм по тексту
mairmaid
. Я тоже хотел поставить её на Vue-FAQ, поставил, посмотрел насколько она просадила размер бандла и производительность в браузере, убрал и заменил генерацию налету на статичные заранее сгенеренные ею картинки ради UX.На втором - slippers-ui, это гитлабовский относительно небольшой (20 компонент) UI kit. Без какого- либо тришейкинга и оптимизации, естественно. Очень много, с учетом того, что любая современная UI библиотека весит в несколько раз меньше.
Ну и победитель - то, за что так любят Nuxt. Это когда он берет что-то хорошее и делает его еще лучше. В этот раз он взял
vue-i18n
, естественно, для интернационализации.Используя pkg-size.dev смотрим сперва на vue-i18n, отключив учет
peer dependencies
:Install size: 2.8MB / 6 packages
Bundle size: 73KB minified (23KB gzip) / 9 modules
Очень неплохо для
i18n
библиотекиТо же с @nuxtjs/i18n:
Install size: 61MB / 239 packages
Bundle size: Не собрался (ошибки)
Error: Process exited with code 1
✘ [ERROR] No matching export in "node_modules/unicorn-magic/default.js" for import "toPath"
Bundlephobia тоже дала ошибки при сборке
Самая простая реализация
i18n
пишется в один composable. Но на Nuxt
-e всё намного серьезней.#nuxt #optimization #i18n #gitlab
Два самых значимых улучшения в грядущем
- PR#9511 - улучшает работу с большими reactive массивами (которые сейчас обслуживаются как все объекты - через
- PR#10407 - в целом в два раза уменьшает использование памяти на реактивном коде
#vuejs #optimization
Vue 3.5
связаны с оптимизацией реактивности- PR#9511 - улучшает работу с большими reactive массивами (которые сейчас обслуживаются как все объекты - через
Proxy
), что должно дать многократное ускорение при работе с ним и оптимизацию по памяти- PR#10407 - в целом в два раза уменьшает использование памяти на реактивном коде
#vuejs #optimization
GitHub
optimize array tracking (fix #4318) by jods4 · Pull Request #9511 · vuejs/core
This PR implements the optimisations proposed in #4318. Shortly:
It adds a special tracking key: ARRAY_ITERATE_KEY, which represents a full dependency on an array (not including extra keys when ha...
It adds a special tracking key: ARRAY_ITERATE_KEY, which represents a full dependency on an array (not including extra keys when ha...
v-memo - директива для микро-оптимизации
При изменении актуального состояния компонента он ре-рендится весь. Может случиться, что какие-то куски его шаблона тяжелы для построения, и при определенных изменениях их не надо ре-рендерить, тогда можно определить эту логику через
#optimization
При изменении актуального состояния компонента он ре-рендится весь. Может случиться, что какие-то куски его шаблона тяжелы для построения, и при определенных изменениях их не надо ре-рендерить, тогда можно определить эту логику через
v-memo
. Особенно это может пригодиться при отображении большого массива нетривиальных элементов/компонентов.#optimization
ru.vuejs.org
Vue.js
Vue.js - The Progressive JavaScript Framework
Поставил
Бандл был 200Кб, стал 400Кб...
wtf%№?:;*"(;?;*!!!!!
Кто как делает?
#firebase #auth #optimization
Firebase Authentication
на сайт (логин через Google
, Apple
и т.д.)Бандл был 200Кб, стал 400Кб...
wtf%№?:;*"(;?;*!!!!!
AI бот
предлагает другие варианты, но уверяет, что они хуже.Кто как делает?
#firebase #auth #optimization
В очередной раз делая
Понятно, что для того, чтобы при смене языка он сразу менялся на странице без ее перезагрузки. А оно того стоит? Ценой этого - пронизывание практически всех компонентов сетью реактивной зависимости, что точно не благотворно сказывается на производительности и сложности кода.
Большинство сайтов направлены на определенную языковую аудиторию. Кроме того, можно определять по браузеру язык системы и автоматически в него переключаться в первый раз. То есть, процент тех, кто на сайте сменит язык какой - 1-2? И из-за одного их переключения должны тормозить все?
Напомню, что у монструозного лендинга
Какие мысли по этому поводу?
#i18n #optimization
i18n
на Vue
проекте, задумался - а зачем этому модулю (и функции t()
в частности) реактивность? Неважно, стандартный это i18n-next
или самописный.Понятно, что для того, чтобы при смене языка он сразу менялся на странице без ее перезагрузки. А оно того стоит? Ценой этого - пронизывание практически всех компонентов сетью реактивной зависимости, что точно не благотворно сказывается на производительности и сложности кода.
Большинство сайтов направлены на определенную языковую аудиторию. Кроме того, можно определять по браузеру язык системы и автоматически в него переключаться в первый раз. То есть, процент тех, кто на сайте сменит язык какой - 1-2? И из-за одного их переключения должны тормозить все?
Напомню, что у монструозного лендинга
GitLab
основная зависимость в 13Mb скриптов именно i18n
Какие мысли по этому поводу?
#i18n #optimization
Telegram
Vue-FAQ
Кастомная i18n
Распространенный пакет для интернационализации веб приложений i18next сильно раздут и содержит много редко используемого функционала.
В то же время перевод сайта на несколько языков без необходимости обработки чисел и родов можно провести…
Распространенный пакет для интернационализации веб приложений i18next сильно раздут и содержит много редко используемого функционала.
В то же время перевод сайта на несколько языков без необходимости обработки чисел и родов можно провести…
Сайт icones.js.org довольно удобен для подбора иконок (хотя выбор средний и поиска по параметрам нет, но хорошо сделано копирование найденного сразу в
К вопросу о том, качественный ли код пишет
#antfu #icons #optimization
svg
), но такое потребление памяти после поиска нескольких иконок выше понимания.К вопросу о том, качественный ли код пишет
Anthony Fu
, автор VueUse
, Nuxt
и многого другого#antfu #icons #optimization
VS Code
позволяет отключить аппаратное ускорение при отрисовке, что может заметно убыстрить IDE
при плохом GPU
или проблемах с драйверами1. Preferences > Configure Runtime Arguments
2. Добавить: "disable-hardware-acceleration": true
Или сразу в
.vscode/argv.json
#vscode #tip #optimization
Vite
позволяет использовать новый более производительный и функциональный компилятор SASS
через эту опцию:export default {
css: {
preprocessorOptions: {
scss: {
api: 'modern-compiler'
}
}
}
}
Дефолтным его не делали пока потому, что это breaking change, но в
Vite 6
он будет по умолчанию.В любом случае, чистый
CSS3
со своим современным функционалом уже вполне покрывает все основные потребности стилизации.Рекомендуется к использованию.
#vite #css #optimization
Заспорил тут в Твиттере с создателем
На аргумент о
В итоге получился вот такой бенчмарк на Stackblitz по замеру времени изменения разных массивов
С одной стороны, ужасно, как
С другой, еще раз стало очевидно, что писать программы на
#optimization #benchmark
FormKit
Justin Schroeder
, который с чего-то призвал отказаться от использования ref
в пользу reactive
На аргумент о
ShallowRef
он привел ShallowReactive
, и стало интересно, как сильно они отличаютсяВ итоге получился вот такой бенчмарк на Stackblitz по замеру времени изменения разных массивов
ShallowRef
не использует JavaScript Proxy
, отсюда такая эффективностьС одной стороны, ужасно, как
Proxy
уронил общую производительность в JS
С другой, еще раз стало очевидно, что писать программы на
Vue
надо с умом. Необходимо полностью контролировать модель и потоки данных. Именно поэтому доверять таким библиотекам, как VueUse
и Tanstack
, это, как минимум, торговать производительностью и архитектурой.#optimization #benchmark
Сперва они советуют всегда для роутов использовать динамичные роуты, потом учат делать префетчинг...
Этот совет из документации
#routing #optimization
Этот совет из документации
Vue Router
- самое глупое что есть в ближайшей Vue
экосистеме.#routing #optimization
// useUserService.ts
function isAuthenticated() {
return !!user.value;
}
// Component A
<script>
const { isAuthenticated } = useUserService();
</script>
<template>
<p v-if="isAuthenticated()">hello</p>
</template>
Функции во
Vue
ведут себя не совсем как функцииВ данном примере функция
isAuthenticated()
ведет себя как computed
и будет вызываться каждый раз, когда user
изменится или компонент А
будет перерисовываться.Происходит это из-за того, что
Vue
определяет все реактивные зависимости внутри тела функции и перерендивает компонент, когда кто-то из них меняется.Таким образом, большой разницы в использовании функции вместо
computed
нет. Но если внутри большая логика, то лучше использовать computed
, потому что он будет пересчитываться только когда его зависимости изменились, а функция - при любом рендеринге#reactivity #tip #optimization
Время от времени можно удалять локальный
#npm #pnpm #optimization
npm
/yarn
/ pnpm
кэш, чтобы освободить место на диске от устаревших версий пакетов.#npm #pnpm #optimization
Датацентры всего мира производят 3.7% мирового CO2 (carbon footprint, углекислый газ)
Каждый показ вашего сайта является причиной выделения CO2 - в среднем 0.8 грамм.
Замерьте карбоновый след вашего сайта
Еще одна причина писать эффективные
#pwa #optimization
Каждый показ вашего сайта является причиной выделения CO2 - в среднем 0.8 грамм.
Замерьте карбоновый след вашего сайта
Еще одна причина писать эффективные
PWA
#pwa #optimization
Website Carbon Calculator
Website Carbon Calculator v3 | What's your site's carbon footprint?
The original website carbon calculator tool, brought to you by Wholegrain Digital,London's original sustainable WordPress agency.