SUPER_OLEG_DEV Telegram 104
Почему я вообще поднял тему lazy hydration.

Сейчас исследую возможность оптимизировать тяжелый футер tinkoff.ru не только на клиенте, но и на сервере.

В теории, его можно кэшировать, и не рендерить для каждой страницы заново - а время его рендеринга занимает 20-30% от общего времени рендера большинства страниц, то есть оптимизация напрямую повлияет на максимальные нагрузки, которые могут обрабатывать приложения.

Отдельная история - это персонализация и динамика, которая пролезла в футер, и от которой надо избавиться перед кэшированием, но тут нас больше интересует техническая часть.

Если искать информацию по кэшированию React компонентов, можно найти несколько устаревших форков рендерера `ReactDOMServer`, например https://github.com/rookLab/react-component-caching

Этот подход сложный в реализации и поддержке, и не удивительно что актуальных решений кажется не существует.

Но оказалось что можно сделать очень простой локальный механизм, который отлично ложится на наш `LazyRender` компонент, настолько простой что до сих пор ищу подвох.

Сразу покажу обновленный код:

```
const LazyRender = ({ children, cacheEnabled, cacheKey, serverCache }) => {
const containerRef = useRef(null);
const isVisible = useObserver(containerRef);

if (cacheEnabled && typeof window === 'undefined') {

let html: string;

if (serverCache.has(cacheKey)) {
html = serverCache.get(cacheKey);
} else {
const reactDomServer = require('react-dom/server');

html = reactDomServer.renderToString(children);

serverCache.set(cacheKey, html);
}

return React.createElement('div', {
dangerouslySetInnerHTML: { __html: html },
});
}

if (isVisible) {

return React.createElement('div', {}, children);
}


return React.createElement('div', {
ref: containerRef,

suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: '' },
});
};

```

Где `cacheKey` - уникальный ключ для кэширования конкретной вариации children компонента, он должен иметь низкую кардинальность для эффективной работы кэша.

А `serverCache` - любой LRU кэш со стандартными методами has / get / set, и настроенным не слишком высоким временем жизни кэша.

Для этого кэша на сервере важно быть синглтоном, в принципе как и для любого другого.

В `LazyRender`, если кэш включен, мы вручную рендерим children в HTML строку, и дальше сохраняем результат в кэши и используем при рендере других страниц.

Основной минус подхода - React Context приложения будет недоступен в children компоненте. Мы планируем использовать это для микрофронта (а футер как раз такой микрофронт), где это кажется не проблема, и даже хорошая практика.

По итогу, механизм кэширования это самая простая часть, а больше времени заняла интеграция в модуль отвечающем за загрузку и рендер микрофронтов, и в модуль который добавляет микрофронт футер в лэйаут приложения.
И конечно же доработки самого футера.

Из интересного, закрыл включение кэширования за фича-тогглом - сам футер одновременно можно раскатить на все приложения, а код с кэшированием требует обновления фреймворка на приложениях, и этот рубильник даст возможность в будущем контроллируемо проверить работоспособность механизма.

Также, добавил серверную метрику - счетчик с лейблами hit / miss и уникальным ключем кэша, для возможности чекать hit rate и в целом эффективность кэширования.

Обязательно поделюсь результатами, как дело дойдет до интеграции и подключения на продакшене!
🔥17👍4



tgoop.com/super_oleg_dev/104
Create:
Last Update:

Почему я вообще поднял тему lazy hydration.

Сейчас исследую возможность оптимизировать тяжелый футер tinkoff.ru не только на клиенте, но и на сервере.

В теории, его можно кэшировать, и не рендерить для каждой страницы заново - а время его рендеринга занимает 20-30% от общего времени рендера большинства страниц, то есть оптимизация напрямую повлияет на максимальные нагрузки, которые могут обрабатывать приложения.

Отдельная история - это персонализация и динамика, которая пролезла в футер, и от которой надо избавиться перед кэшированием, но тут нас больше интересует техническая часть.

Если искать информацию по кэшированию React компонентов, можно найти несколько устаревших форков рендерера `ReactDOMServer`, например https://github.com/rookLab/react-component-caching

Этот подход сложный в реализации и поддержке, и не удивительно что актуальных решений кажется не существует.

Но оказалось что можно сделать очень простой локальный механизм, который отлично ложится на наш `LazyRender` компонент, настолько простой что до сих пор ищу подвох.

Сразу покажу обновленный код:

```
const LazyRender = ({ children, cacheEnabled, cacheKey, serverCache }) => {
const containerRef = useRef(null);
const isVisible = useObserver(containerRef);

if (cacheEnabled && typeof window === 'undefined') {

let html: string;

if (serverCache.has(cacheKey)) {
html = serverCache.get(cacheKey);
} else {
const reactDomServer = require('react-dom/server');

html = reactDomServer.renderToString(children);

serverCache.set(cacheKey, html);
}

return React.createElement('div', {
dangerouslySetInnerHTML: { __html: html },
});
}

if (isVisible) {

return React.createElement('div', {}, children);
}


return React.createElement('div', {
ref: containerRef,

suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: '' },
});
};

```

Где `cacheKey` - уникальный ключ для кэширования конкретной вариации children компонента, он должен иметь низкую кардинальность для эффективной работы кэша.

А `serverCache` - любой LRU кэш со стандартными методами has / get / set, и настроенным не слишком высоким временем жизни кэша.

Для этого кэша на сервере важно быть синглтоном, в принципе как и для любого другого.

В `LazyRender`, если кэш включен, мы вручную рендерим children в HTML строку, и дальше сохраняем результат в кэши и используем при рендере других страниц.

Основной минус подхода - React Context приложения будет недоступен в children компоненте. Мы планируем использовать это для микрофронта (а футер как раз такой микрофронт), где это кажется не проблема, и даже хорошая практика.

По итогу, механизм кэширования это самая простая часть, а больше времени заняла интеграция в модуль отвечающем за загрузку и рендер микрофронтов, и в модуль который добавляет микрофронт футер в лэйаут приложения.
И конечно же доработки самого футера.

Из интересного, закрыл включение кэширования за фича-тогглом - сам футер одновременно можно раскатить на все приложения, а код с кэшированием требует обновления фреймворка на приложениях, и этот рубильник даст возможность в будущем контроллируемо проверить работоспособность механизма.

Также, добавил серверную метрику - счетчик с лейблами hit / miss и уникальным ключем кэша, для возможности чекать hit rate и в целом эффективность кэширования.

Обязательно поделюсь результатами, как дело дойдет до интеграции и подключения на продакшене!

BY SuperOleg dev notes


Share with your friend now:
tgoop.com/super_oleg_dev/104

View MORE
Open in Telegram


Telegram News

Date: |

The Channel name and bio must be no more than 255 characters long Deputy District Judge Peter Hui sentenced computer technician Ng Man-ho on Thursday, a month after the 27-year-old, who ran a Telegram group called SUCK Channel, was found guilty of seven charges of conspiring to incite others to commit illegal acts during the 2019 extradition bill protests and subsequent months. 1What is Telegram Channels? In handing down the sentence yesterday, deputy judge Peter Hui Shiu-keung of the district court said that even if Ng did not post the messages, he cannot shirk responsibility as the owner and administrator of such a big group for allowing these messages that incite illegal behaviors to exist. fire bomb molotov November 18 Dylan Hollingsworth yau ma tei
from us


Telegram SuperOleg dev notes
FROM American