16 июн. 2025 г.

Debug CLS: List DOM elements, their coordinates, and area changes for every layout shift

(new PerformanceObserver((list) => {

    const entries = list.getEntriesByType('layout-shift');

    entries.forEach((/*LayoutShift*/entry) => {

        console.log(entry);

        const /*Array<LayoutShiftAttribution>*/sources = entry.sources || [];

        const changes = [];

        for (const source of sources) {

            const { currentRect: cr, previousRect: pr, node } = source;

            const dx = cr.x - pr.x;

            const dy = cr.y - pr.y;

            const ds = cr.width * cr.height - pr.width * pr.height;

            changes.push({dx, dy, ds, node});

        }

        if (changes.length) {

            console.table(changes);

        }

    });

})).observe({ type: 'layout-shift', buffered: true });


23 авг. 2024 г.

State of React memoization in 2023

 https://2023.stateofreact.com/en-US/features/


  • 86% used useMemo()
  • 85% used useCallback()
  • 73% used memo()
About 12% of auditory know something about stable links in component props (via useMemo and useCallback) but need to know how to memoize functional components to use those stable links.

3 нояб. 2023 г.

Benchmarking bun startup time

Single-line file:

console.log('Hello World')

Benchmark:

hyperfine --warmup 3 'bun test.js' 'node test.js'
Benchmark 1: bun test.js
  Time (mean ± σ): 8.9 ms ± 0.6 ms [User: 5.2 ms, System: 3.6 ms]
  Range (min … max): 7.5 ms … 11.8 ms 258 runs

Benchmark 2: node test.js
  Time (mean ± σ): 24.9 ms ± 1.1 ms [User: 19.7 ms, System: 3.6 ms]
  Range (min … max): 23.6 ms … 30.0 ms 111 runs

The difference is only about 20 ms.

ESLint'ing the project with 30000 files:

find . \( -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" \) | wc -l
   30623

hyperfine --warmup 3 --ignore-failure 'npx eslint --ext .js,.jsx,.ts,.tsx .' 'bunx eslint --ext .js,.jsx,.ts,.tsx .'
Benchmark 1: npx eslint --ext .js,.jsx,.ts,.tsx .
  Time (mean ± σ): 6.896 s ± 0.047 s [User: 15.452 s, System: 0.621 s]
  Range (min … max): 6.831 s … 6.980 s 10 runs

Benchmark 2: bunx eslint --ext .js,.jsx,.ts,.tsx .
  Time (mean ± σ): 6.776 s ± 0.046 s [User: 15.423 s, System: 0.578 s]
  Range (min … max): 6.715 s … 6.849 s 10 runs

The difference is about 100 ms.

25 окт. 2023 г.

How to use ESLint + Prettier + VS Code together without conflicts

  1. Install eslint, prettier, eslint-plugin-prettier, eslint-config-prettier
  2. Update eslintrc file to look like this:

extends: [
  'eslint:recommended',
  'plugin:react/recommended', // if react is used
  'plugin:react-hooks/recommended', // if react is used
  'plugin:@typescript-eslint/recommended', // if ts
  'plugin:prettier/recommended'
],
plugins: ['prettier', 'react', 'react-hooks', '@typescript-eslint'],

With this setup ESLint starts to use Prettier and its rules for code style checks and autofixes.

Moreover, now you don't need two separate commands to run ESLint and Prettier, they both will run with a single command eslint --fix.

Additional steps for VS Code:

  1. Install the "Prettier - Code formatter" extension
  2. Go to Settings and set the "Editor: Default formatter" to "Prettier - Code formatter"
  3. Enable "Editor: Format On Save"

29 мар. 2022 г.

React.StrictMode calls your render() and reducer() twice

In a strict mode development build of React renders your components twice. It calls your render() method, functional components, all the hooks two times. The reducer() function from the useReducer() hook is also called twice.

Before the second call, React disables all console output methods. In case your code works in non-strict mode but shows strange results in strict mode, you may want to see console output from the second call. In order to do that you can store the original console.log method at the very beginning of your code:

import { useReducer } from "react";
// other imports...

const log = console.log;

function MyComponent() {
  const [state, dispatch] = useReducer(reducer, undefined, init);
  log("MyComponent", state); // note: log instead of console.log
  return <div>markup...</div>;
}


26 мая 2021 г.

Network Filter expressions in Chrome DevTools


KeywordExample
cookie-domain:cookie-domain:.google.com
cookie-name:
cookie-path:cookie-path:/images
cookie-value:
domain:domain:*.com domain:example.com
has-response-header:has-response-header:Access-Control-Allow-Origin
is:is:from-cache is:service-worker-intercepted
larger-than:larger-than:10k
method:method:POST
mime-type:mime-type:application/json
mixed-content:
priority:priority:Highest
resource-type:resource-type:image resource-type:other
scheme:scheme:https
set-cookie-domain:set-cookie-domain:.google.com
set-cookie-name:set-cookie-name:__utma
set-cookie-value:set-cookie-value:abc123
status-code:status-code:204
url:url:data:

To invert the rule, i.e. leave URLs that do not match, prepend it with minus sign, e.g. -is:from-cache means "all resources loaded not from cache".

Any other text leaves only URLs with that text somewhere in it (in path, query, etc.)

Examples:

  • larger-than:10k resource-type:image -domain:*.net
    "all images not from *.net larger than 10 kilobytes"
  • is:from-cache resource-type:script
    "cached scripts"

19 февр. 2021 г.

Create IFRAME from string


<body>
<script>
  function makeURL(str) {
    var blob = new Blob([str], { type: "text/html" });
    return URL.createObjectURL(blob);
  }
  var ifr = document.createElement("iframe");
  ifr.src = makeURL('<button onclick="parent.navigate()">Click me</button>');
  document.body.appendChild(ifr);
  var oldTiming;
  function navigate() {
    oldTiming = frames[0].performance.navigation;
    ifr.src = makeURL('<button onclick="parent.doReload()">Now click me</button>');
  }
  function doReload() {
    ifr.onload = function() { alert(oldTiming.type + " " + frames[0].performance.navigation.type); }
    frames[0].location.reload();
  }
</script>

1 дек. 2020 г.

Написание заимствованных слов

По правилам написания заимствованных слов нет единого мнения даже у профессиональных филологов. Например, филологи активно спорят, как правильно писать — блогер или блоггер. Для соблюдения принципа единообразия в текстах лучше использовать консенсусные варианты написания:

  • ВКонтакте или ВК (не Вконтакте).
  • Фейсбук, Facebook (не Фэйсбук).
  • Фронтенд (не фронтэнд и не фронт-енд или фронт-энд).
  • Бэкенд (не бэкэнд, не бекенд и не бек-энд).
  • Фреймворк (не фрэймворк).
  • YouTube (не Youtube, не ютуб), но ютуб-канал.
  • Флекс, флекс-контейнер (не флэкс).
  • JavaScript или JS (не Javascript).
  • Node.js (не node.js, NodeJS).
  • CodePen (не Codepen, не кодпен).
  • SEO (не СЕО, когда речь идёт о поисковой оптимизации). Но можно писать сеошник.
  • Лендинг (не лэндинг).
  • Слово интернет пишется с маленькой буквы (посмотри в интернете).
  • Веб-сайт (не web-сайт).
  • Онлайн (не он-лайн).
  • Офлайн (не оф-лайн, не офф-лайн).
  • URL (не урл).
  • Деструктуризация (не дестракчеринг).
  • Колбек (не коллбек, не колбэк и не коллбэк).
  • Рантайм (не runtime, не среда исполнения).
  • Изменяемость и неизменяемость (не мутабельность и не иммутабельность).
  • Markdown (не Маркдаун).

Руководство по оформлению текстов на Хекслете

Web-standards - словарь терминов

25 окт. 2020 г.

Uninstall bloatware on Samsung J7, Samsung J5 without root via adb

  1. On phone: install App Inspector (669 kB) from Play Store
  2. On phone: with the help of App Inspector find package names of apps you want to uninstall
  3. On phone: enable USB debugging. Settings -> About phone -> Software information -> Tap on "Build number" seven times. Then Settings -> Developer options -> enable "USB debugging". Documentation
  4. On computer: download and install Android SDK Platform Tools
  5. Connect the phone to the computer with a USB cable, allow USB debugging
  6. On computer: adb devices should show connected phone
  7. adb shell pm list packages -f should show all installed packages
  8. adb shell pm uninstall -k --user 0 <package name from step 2>
    Example:
    adb shell pm uninstall -k --user 0 com.samsung.ecomm.global.in

3 авг. 2020 г.

Tools for performance analysis in Node.js

  • node-tick-processor easy-to-install processor for the v8 profiler log
  • node-gcstats exposes stats about V8 GC after it has been executed
  • 0x single-command flamegraph profiling
  • autocannon HTTP/1.1 benchmarking tool written in node, with support for HTTP pipelining and HTTPS
  • k6.io open source load testing tool and SaaS for engineering teams
  • why-did-you-render monkey patches React to notify you about avoidable re-renders (works with React Native as well)