React: [Umbrella] Отключение саспенса

Созданный на 13 июл. 2018  ·  83Комментарии  ·  Источник: facebook/react

Давайте воспользуемся этой проблемой, чтобы отслеживать оставшиеся задачи по выпуску Suspense с открытым исходным кодом.

Первоначальный выпуск (MVP)

Основной

  • [x] API для чтения контекста из любой функции фазы рендеринга (@acdlite) [# 13139]
  • [x] Скрыть содержимое с истекшим временем ожидания вместо его удаления (@acdlite) [# 13120]
  • [] Автоматическая инъекция поставщиков контекста в корень React (@acdlite) [# 13293]
  • [] Удалить префикс unstable_ из AsyncMode (может быть?)
  • [] Поддержка синхронных таблиц и обещаний, которые разрешаются до завершения фазы рендеринга.

    • [] Подтвердите, что синхронный файл, который выдает ошибку, обрабатывается правильно

  • [] Подтвердите, что это работает с <div hidden> [# 13089]
  • [] Почему нажатие на несколько ссылок на детали в приспособлении одна за другой в конечном итоге приводит к появлению большого заполнителя, даже если я жду каждой из них меньше, чем задержка заполнителя, прежде чем щелкнуть следующую ( см. Твит )?

Поставщик простого кэша

  • [] Аннулирование кеша (@acdlite) [# 13337]
  • [] Подписки (@acdlite) [# 13337]
  • [] Определитесь с настоящим именем

Разделение кода

  • [x] Обещание поддержки как компонентный тип
  • [x] (возможно) Открытый исходный код lazyLoadComponent ?

Тестовый рендерер

  • [] Завершить общедоступные API для flushAll , yield и т. Д.

    • Предварительный план состоит в публикации пользовательских сопоставителей для каждой из основных сред тестирования, а-ля № 13236.

Документы

  • [ ] Сообщение блога
  • [] React.Placeholder
  • [] простой-кеш-провайдер
  • [] Безымянная библиотека для разделения кода

Последующие действия

Мягкое истечение срока (https://github.com/facebook/react/issues/14248)

  • [] Реализуйте API для индикаторов загрузки на месте, которые не являются предками
  • [] Убедитесь, что есть способ избежать мигания встроенного счетчика, если он достаточно быстрый

Рендерер сервера потоковой передачи

  • [] Реализуйте рендерер сервера потоковой передачи, подобный тому, который лекции ZEIT от
  • [] Частичное увлажнение

Связанный: Зонтик Time Slicing (https://github.com/facebook/react/issues/13306)

React Core Team Umbrella

Самый полезный комментарий

@mschipperheyn

Это многолетний проект. Честно говоря, он потребовал больше работы, чем мы думали, когда начали над ним два года назад.

Но хорошая новость заключается в том, что ,

Вот примерное состояние различных направлений работы на сегодняшний день:

  • <Suspense> API для разделения кода с помощью lazy . ( поставляется в React 16.6)

    • Как вы, возможно, знаете, вы уже можете использовать это.

  • API параллельного режима, например createRoot и useTransition . ( доступно в выпусках experimental )

    • Решение для совместимости с Flux-подобными библиотеками. ( в процессе @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • Смена модели приоритета на более разумную. ( в процессе @acdlite , https://github.com/facebook/react/pull/18612)

    • Дождитесь завершения только последнего ожидающего перехода. ( в процессе @acdlite)

    • Offscreen API ( в процессе @lunaruan)

    • Огненные эффекты при скрытии / отображении контента для Suspense

    • Эффекты огня при скрытии / отображении контента вне экрана

    • Показывать и скрывать дочерние элементы портала при необходимости

    • Согласование с текущей работой по стандартизации для планирования ( не начато )

    • Исправить основные известные ошибки ( в процессе @gaearon и @acdlite)

    • Измените семантику события. ( в процессе @sebmarkbage @trueadm)

    • Делегировать на root вместо document, чтобы обеспечить более постепенное внедрение ( в процессе , @trueadm)

    • Сбрасывать дискретные события в фазе захвата.

    • Рассмотрите возможность получения приоритета по умолчанию из event чтобы лучше играть с императивным кодом.

    • Завершите работу над семантикой и значениями по умолчанию для других API. ( не началось )

    • Обновите типографии и документацию.

  • Приостановка получения данных

    • Низкоуровневая поддержка сигнализации о том, что компонент не готов к рендерингу (технически доступен и в стабильном React, но этот API не считается стабильным).

    • Серверный рендерер немедленно сбрасывает резервные копии Suspense ( доступно в экспериментальных выпусках)

    • Решение для случаев использования GraphQL (Relay Hooks, поставляется ).

    • Решение для случаев использования, отличных от GraphQL ( в разработке @sebmarkbage в сотрудничестве с Next.js).

    • Интеграция сборщика для зависимостей, управляемых данными. ( в процессе )

    • Завершить API блоков, включая контекст.

    • Общее решение для кеширования. ( не началось )

    • Какая-то интеграция с роутером.

Такое ощущение, что «он находится в разработке в Facebook, так что мы закончили».

Я понимаю, как это могло бы выглядеть таким образом, хотя это чтение немного деморализует. :-) Мы непрерывно работали над этим все последние месяцы, и многие технические аспекты либо уже завершены, либо близки к завершению. Большинство оставшихся работ делятся на две категории:

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

  • Совместимость экосистемы и хорошие настройки по умолчанию. Не поможет, если мы выпустим то, что сегодня никто не может использовать, потому что это не работает с их библиотеками или существующими подходами. Таким образом, основная работа (например, совместимость с Flux-подобными библиотеками через useMutableSource , выбор лучшей семантики событий, доставка рекомендованной стратегии кэширования) заключается в том, чтобы убедиться, что вы действительно сможете использовать то, что мы выпустили. Это длинный хвост.

С точки зрения «можете ли вы использовать сегодня» ... Технически, вы можете использовать все это сегодня. Мы делаем. В частности, мы используем Relay Hooks и Concurrent Mode. У нас все еще есть значительные запланированные изменения и известные проблемы, поэтому текущее состояние не соответствует планке, на которой мы бы считали его готовым к широкому применению. Конечно, если вы не против, чтобы ошибки или API менялись прямо у вас под рукой, вы можете использовать выпуски @experimental как и мы.

Я бы не сказал, что Facebook находится здесь в особом положении с точки зрения того, что мы «закончили». Напротив, мы еще не закончили, но внутренне мы готовы терпеть отток и строить на вершине движущегося поезда, потому что именно так мы знаем, что то, что мы строим, является прочным. Без этого тяжелого кормления недостатки, которые мы обнаружили за шесть месяцев, потребовалось бы несколько лет, чтобы их обнаружить и переработать.

Подводя итог: есть над чем поработать.

Все 83 Комментарий

Выставить unstable_AsyncMode (может быть?)

Разве это еще не разоблачено ?

Я имел в виду удалить unstable_

Я с нетерпением жду открытия исходного кода безымянной библиотеки для разделения кода 💯

Что это значит [Зонт]? 🤔☂️

Это означает, что это функция, которая влияет на несколько проектов / пакетов / инструментов.

@ghoullier Понятно , большое вам спасибо!

Привет, @acdlite , просто вопрос о том, как лучше к этому подготовиться. Не спрашивая / не ожидая какой-либо временной шкалы, но задаваясь вопросом:

Ожидаете ли вы, что эти функции появятся в React 16 и их будет легко внедрять постепенно, как новый Context API, который появился в 16.3?

Или вы думаете, что это будет что-то, что подтолкнет React к версии 17 и потребует дополнительной работы для внедрения?

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

Также есть ли у вас какие-либо советы о том, как лучше всего подготовиться (с точки зрения кода, написанного сегодня, который в будущем хочет быть совместимым с этими улучшениями в React) - полифиллы / методы / и т. Д.?

(извиняюсь, если на эти вопросы есть ответы в другом месте, а я их пропустил)

Добавляем еще один вопрос к вопросам @JedWatson :

  • Нам также не нужны / не ожидаются сроки выпуска стабильного выпуска, но будет ли возможно / полезно получить новый предварительный выпуск? (AFAIK новейший выпуск - 16.4.0-alpha.0911da3 с февраля.)

Спасибо! ❤️

ИМО, они, как и раньше, предоставят сообщение в блоге, прежде чем оно будет отправлено.

И я думаю, что вам не нужно слишком много готовиться, потому что нет критических изменений (у него есть много функций, которые могут показаться разными / противоречащими текущим практикам, например, redux fetch с ожиданием, но будет codemod или простая инкапсуляция для этого у fb есть 3W + компоненты). И если вы посмотрите разговоры о @acdlite (о приостановке ssr в ZEIT) и @gaearon (о приостановке работы клиента в Исландии), вы поймете, что вам не о чем беспокоиться слишком много, и это не агрессивно.

Кстати, вы можете просто выполнить поиск по ключу «Umbrella» в репо, и вы найдете дополнительную информацию, например, # 8830 и # 12152.

AFAIK, самый последний выпуск - 16.4.0-alpha.0911da3 от февраля.

IIRC, это ошибка?

Я работаю над развертыванием модуля саспенса и новых API в facebook. Если @acdlite занят чем-то другим, я хотел бы поделиться некоторыми своими мыслями о нашем опыте работы в Facebook и ответить на некоторые вопросы @JedWatson.

Ожидаете ли вы, что эти функции появятся в React 16 и их будет легко внедрять постепенно, как новый Context API, который появился в 16.3?

Я не уверен, будет ли он поставляться с React 16 или 17. По словам команды React, он, вероятно, будет выпущен до конца этого года, что зависит от того, насколько хорошо он работает в facebook и готов ли соответствующий API или нет. Но с точки зрения кода, я счастлив сказать, что его будет легко принять, потому что мы довольно долго экспериментировали в facebook. Функция неизвестности по-прежнему будет работать для существующей кодовой базы. Но с дополнительными изменениями (такими как асинхронный рендеринг) у вас будет больше бонусов, которые вам принесет новая функция.

Есть ли у вас какие-либо советы о том, как лучше всего подготовиться (с точки зрения кода, написанного сегодня, который в будущем хочет быть совместимым с этими улучшениями в React) - полифиллы / методы / и т. Д.?

Я бы сказал, что миграция идет постепенно и постепенно. Как сказал @ NE-SmallTown, мы не хотим вносить никаких критических изменений. Развернуть это на facebook также было бы болезненно, потому что у нас очень большая кодовая база. Но до сих пор развертывание было плавным и не требовало дополнительных изменений.

@JedWatson

Ожидаете ли вы, что эти функции появятся в React 16 и их будет легко внедрять постепенно, как новый Context API, который появился в 16.3?

Постепенно. Всегда постепенно :) В противном случае мы не сможем отправить это на Facebook.

Вот чего я жду:

| | Клиент | Серверный рендеринг |
| ----------------- | ---------------------------- | - -------------------------------------------- |
| Саспенс | Работает везде * | Те же ограничения, что и у существующего серверного рендерера |
| Асинхронный рендеринг | Включение с использованием <AsyncMode> | Те же ограничения, что и у существующего серверного рендерера |

* В режиме синхронизации delayMs всегда равно 0 . Заполнители появляются немедленно.

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

Таким образом, идея состоит в том, что пользователи начнут переход на приостановку еще до того, как они будут готовы перейти на асинхронный рендеринг. Затем, когда поддерево будет готово, они могут подписаться, заключив в него <AsyncMode> .

Однако с новыми приложениями все обстоит иначе: по умолчанию используется асинхронный режим. Мы представим новый корневой API (замену ReactDOM.render ), который является только асинхронным.

После первоначального выпуска наступит неловкий период, когда многие сторонние фреймворки (Redux, Apollo, React Router ...) могут некорректно работать в асинхронном режиме. На какое-то время это может повредить усыновлению. Но идея состоит в том, что новые функции будут настолько убедительными, что библиотекам не потребуется много времени, чтобы адаптироваться или быть заменены асинхронно-совместимой альтернативой.

Также есть ли у вас какие-либо советы о том, как лучше всего подготовиться (с точки зрения кода, написанного сегодня, который в будущем хочет быть совместимым с этими улучшениями в React) - полифиллы / методы / и т. Д.?

Оберните все в <StrictMode> и убедитесь, что нет предупреждений. По мере приближения к выпуску у нас будут более подробные руководства по миграции.

После первоначального выпуска наступит неловкий период, когда многие сторонние фреймворки (Redux, Apollo, React Router ...) могут некорректно работать в асинхронном режиме.

Аполлон не делает неудобств - мы будем готовы! 🕺😳

А если серьезно, мы: heart: все, что касается React, поэтому обеспечение соответствия этим изменениям для первоначального выпуска - это не только высокий приоритет, но и то, что нас очень волнует! Спасибо за вашу потрясающую работу над этим @acdlite!

Я вмешаюсь и скажу, что команда Redux работает над асинхронной совместимостью для React-Redux.

Я выложил потенциальную дорожную карту на https://github.com/reduxjs/react-redux/issues/950 . TL; DR:

  • Мы надеемся, что React-Redux 5.1 будет работать с <StrictMode> без предупреждений (текущий PR: https://github.com/reduxjs/react-redux/pull/980)
  • 6.0 будет внутренним переписанным, чтобы использовать новый контекстный API, добавить пересылку ссылок и, возможно, другие изменения, но постарайтесь сохранить как можно большую часть текущего общедоступного API (т. Е. <Provider> и connect() ). Мы увидим, насколько хорошо это работает с асинхронным рендерингом, и выясним, как лучше всего двигаться дальше. (Мой предыдущий PR-подтверждение концепции находится на https://github.com/reactjs/react-redux/pull/898, но мы, вероятно, переделаем его, основываясь на других уроках, извлеченных из работы 5.1.) Вероятно, что для этого выпуска потребуется как минимум React 16.5 из-за необходимости нового контекста и, вероятно, еще не выпущенного PR "чтения контекста из методов жизненного цикла", который был только что объединен.
  • После этого мы открыты для идей для другого React-Redux API (да, да, это, возможно, включает в себя реквизиты для рендеринга, людей).

Мы были бы признательны за то, чтобы больше внимания уделяли нашему WIP, и, надеюсь, люди дадут нам больше отзывов и обсуждений о том, как они смотрят на использование Redux с React Suspense и асинхронным рендерингом, чтобы мы могли убедиться, что варианты использования рассмотрены должным образом. Мы также надеемся провести еще несколько дискуссий с командой React о том, с какими ограничениями нам нужно работать, и было бы полезно, если бы мы могли получить несколько примеров приложений, которые позволили бы нам увидеть, какие проблемы нам нужно решить для всех. это работает правильно.

с нетерпением жду выпуска асинхронного рендеринга и приостановки

@acdlite Также вопрос о
Мой вопрос: как только они будут представлены и кто-то начнет писать приложения с этой новой версией response: означает ли это, что API-интерфейс реагирования и способ реагирования людей тоже изменится? (даже если они не планируют использовать функции саспенса и асинхронного рендеринга?)

Я предполагаю, что может быть сложнее написать код реакции с ожиданием и асинхронным рендерингом (возможно, из-за какого-то нового API или других ограничений), а для тех, кому это не нужно, зачем заставлять их использовать реакцию по-новому? И не позволять им кодировать так, как они это делают сейчас?

Я предполагаю, что может быть сложнее написать код реакции с неопределенностью

Вы успели посмотреть вторую половину моего выступления? Я бы сказал , совсем наоборот - это путь менее сложный для использования подвешенных выборок данных , чем все остальное ( в том числе Redux, местное государства или какой - либо другая библиотеки).

@gaearon Нет. Я говорил больше в теории. Представьте, что уже есть люди, которые знают, как отреагировать. Если людям не нужна функция асинхронного рендеринга и неизвестности, зачем заставлять их изучать «новую» реакцию? Особенно, если «новую» реакцию хитрее использовать? Но: я не очень хорошо информирован, поэтому могу ошибаться, говоря о "более сложной" части - я просто делюсь некоторыми своими мыслями :).

В каком-то смысле я говорю, что если 10% приложений нуждаются в функции Suspense и асинхронного рендеринга, почему в этих 90% случаев люди вынуждены изучать «новую» реакцию? Но опять же, я могу ошибаться, так как я еще не собрал много информации о приостановке и асинхронном рендеринге.

Думаю, сложно разговаривать, если вы еще не смотрели мои демки .

Чтобы было ясно: нет «нового React», эти функции не нарушают никаких существующих шаблонов 🙂. Они аддитивны. Вам также не нужно писать код совершенно другим способом, чтобы использовать эти функции, хотя некоторые из них работают только при использовании современных методов жизненного цикла .

Хотя это не имеет прямого отношения к вашей проблеме, я не согласен, что они «сложнее в использовании». Я думаю, что саспенс использовать гораздо проще, чем любой другой механизм загрузки, который существует в настоящее время. Вот почему я так взволнован. Но опять же, вам не нужно использовать какие-либо новые функции, если вы не хотите. Старые выкройки будут работать.

Я действительно рекомендую посмотреть мой доклад . Я уверен, что в этом будет больше смысла, когда вы увидите эти функции в действии.

@gaearon

Все старые шаблоны продолжают работать.

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

удачи.

Привет, Дэн (@gaearon), я не придираюсь к мелочам, но хочу разобраться. Выше вы сказали:

Но опять же, вам не нужно использовать какие-либо новые функции, если вы не хотите. Старые выкройки будут работать.

Из чего следует, что я могу кодировать в новом React так же, как и в «старом» React, например, я мог бы использовать методы жизненного цикла таким же образом и т. Д., Верно?

Однако здесь bvaughn говорит, что getDerivedStateFromProps (или componentWillReceiveProps) может вызываться много раз для одного обновления, поэтому его решение не извлекать данные внутри него.

Итак, мой вопрос: в конце концов, кажется, что мы не можем использовать новый React точно так же, как раньше, верно? Поскольку AFAIK в текущем компоненте реакции WillReceiveProps не вызывается много раз для одного обновления, не так ли?

@ giorgi-m: да, методы жизненного цикла меняются, но дело в том, что задержка сама по себе является дополнительной функцией. Все ваши существующие методы рендеринга React и поведение рендеринга React будут работать как есть. Однако, _если_ вы согласитесь, добавив тег <AsyncMode> к части вашего приложения, _и_ вы начнете использовать подход Suspense для указания потребностей в асинхронных данных, _ тогда_ вы можете воспользоваться этим. Ничего из этого не произойдет, если вы не добавите это в свою кодовую базу.

@ giorgi-m componentDidUpdate следует использовать вместо componentWillReceiveProps или getDerivedStateFromProps .

@markerikson Итак, вы говорите, что то, что здесь сказал bvaughn, что _getDerivedStateFromProps_ может вызываться много раз для одного обновления, это не обязательно так, если я не включил <AsyncMode/> ?
(извините, что задаю такие вопросы, просто они время от времени всплывают у меня, и я не нашел ресурса, который бы охватил все).

пс. bvaughn также не упомянул о возможности этого в связанном потоке, поэтому это вызвало у меня подозрение.

Следует ли добавить в основной контрольный список метод для постановки в очередь асинхронных обновлений (например, deferSetState() для компонентов класса в отличие от unstable_deferredUpdates() для конкретного средства визуализации)?

Насколько я понимаю, любые обновления волокон в async mode будут асинхронными, что теоретически означает, что в deferSetState() необходимости. Однако демонстрация unstable-async/suspense смешивает синхронное обновление и асинхронное обновление, и я не уверен, как это можно сделать в режиме async (для «универсальных» компонентов).

Это есть в контрольном списке зонтика для квантования времени.

Обещание поддержки как компонентный тип

В связи с этим, если у вас есть:

const PromiseType = new Promise(() => {})
class A extends Component {
    componentDidMount() {}
    componentDidUpdate() {}
    render() {
        return <div><PromiseType></PromiseType></div>
    }
}

Существуют ли какие-либо эвристики относительно того, когда будут вызваны жизненные циклы componentDidMount и componentDidUpdate .

  1. Когда все дочерние элементы были разрешены (включая обещание), что в этом случае означает, что они не будут вызваны, поскольку обещание никогда не будет разрешено?
  2. Когда все дочерние элементы Immediate host были визуализированы?

@thysultan : componentDidMount и componentDidUpdate вызываются на этапе фиксации, когда дерево пользовательского интерфейса полностью отрисовано и применено к DOM.

Итак, исходя из моего понимания Suspense, я думаю, что ответ заключается в том, что экземпляр A никогда не будет монтироваться. Если PromiseType _did_ было разрешено, но один из его последующих потомков также попытался дождаться обещания, которое никогда не выполняется, оно снова никогда не будет выполнено. Таким образом, cDM и cDU никогда не будут выполняться в этих примерах.

(Кто-то может меня поправить, если мои предположения здесь ошибочны :))

Да, componentDidMount или componentDidUpdate выполняются только на этапе фиксации, который выполняется только после разрешения всего дерева . Это дерево может включать в себя некоторые заполнители, которые вы явно поместили туда (в зависимости от того, приостанавливается ли что-то внутри них после того, как мы достаточно долго ждали), но если вы явно визуализируете дочерний элемент без заполнителя вокруг него, вы никогда не сможете закончить ситуация, когда он «не готов».

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

Есть ли что-нибудь, что мы можем сделать, чтобы его выпустить? : D

Вы можете скомпилировать из мастера, если хотите поиграть. См. Инструкции в fixtures/unstable-async/suspense

@gaearon Правильно ли я, что в текущем состоянии он находится только на стороне клиента (так что для поддержки рендеринга на стороне сервера необходимо проделать дополнительную работу)?

РЕДАКТИРОВАТЬ, нашел ответ: для всех, кто жаждет использовать Suspense в SSR для универсальных приложений. Я нашел этот комментарий Дэна, который сообщает нам, что это только на стороне клиента. Однако этот комментарий также указывает на https://www.youtube.com/watch?v=z-6JC0_cOns, в котором говорится о возможных последствиях для SSR.

На самом деле мы скоро начинаем некоторую работу, связанную с делом SSR.

Представьте себе этот сценарий в приложении async React, запущенном на мобильном устройстве низкого уровня:

  1. Загрузка внешней рекламы с использованием всего ЦП (😓)
  2. Пользователь щелкает ссылку, и маршрутизатор запускает новый рендеринг.
  3. React находится в асинхронном режиме, поэтому он ждет, пока Chrome / Safari не разрешит ему использовать ЦП, но реклама продолжает загружаться еще 3 секунды.
  4. Пользователь думает, что приложение не работает

Этой проблемы можно избежать, используя ту же технику <Placeholder> , описанную для Suspense, например, показывая счетчик через 1 секунду.

Рассматривался ли этот сценарий? Подойдет ли <Placeholder> для медленного асинхронного рендеринга?

@luisherranz Есть два механизма, чтобы предотвратить это:

  1. У React есть крайний срок, связанный с каждым обновлением. Обновления от щелчков и других взаимодействий, подобных этому, должны сбрасываться в течение ~ 150 мс, если вы явно не выберете более длительный срок (например, для несущественных обновлений). Таким образом, React будет синхронно принудительно выполнить сброс, если что-то задержит поток.

  2. На самом деле React больше не использует requestIdleCallback , потому что на самом деле браузеры недостаточно агрессивны в планировании этого. Точный подход к планированию также может измениться со временем, но это определенно то, о чем мы заботимся.

Большое спасибо за быстрый ответ, Дэн.

  1. У React есть крайний срок, связанный с каждым обновлением

Потрясающий. Есть ли уже API, который мы могли бы протестировать?

  1. На самом деле React больше не использует requestIdleCallback, потому что браузеры недостаточно агрессивны в планировании этого.

Это то, что мы тоже экспериментировали. Иногда в загруженном приложении с внешней рекламой и встраиванием из твиттера или YouTube может пройти несколько секунд, пока не будет вызван requestIdleCallback и рендеринг не будет завершен. Так что к этому.

Кстати, у нас есть еще один вариант использования, связанный с вашим первым ответом: мы пытаемся использовать ленивые загрузки с двумя смещениями. Первый запускает асинхронный рендеринг, второй запускает синхронный рендеринг, если асинхронный рендеринг не завершен. Что-то вроде этого:

  1. Пользователь прокручивает вниз, и он находится на расстоянии 1200 пикселей от тяжелого элемента: например, следующего сообщения в блоге.
  2. Первое сообщение запускает асинхронный рендеринг следующего сообщения.
  3. Пользователь продолжает прокрутку вниз, и это 600 пикселей следующего сообщения.
  4. Триггеры второго смещения: если асинхронное сообщение завершено (вызвано componentDidMount), ничего не происходит, но если этого не произошло, запускается синхронный рендеринг всего сообщения.

Поэтому вместо времени мы хотели бы управлять смывом с помощью второго триггера. Имеет ли это смысл? Возможно ли такое?

Есть ли уже API, который мы могли бы протестировать?

Я не уверен, имеете ли вы в виду мастер или нет (асинхронный режим официально не доступен в выпусках npm), но время истечения срока действия назначается автоматически для каждого обновления. Для таких событий, как щелчки, это ~ 150 мсек в режиме воспроизведения. Вы не можете установить его, хотя вы можете выбрать отложенное (более длительное) обновление, если хотите, со специальным нестабильным API.

Поэтому вместо времени мы хотели бы управлять смывом с помощью второго триггера. Имеет ли это смысл? Возможно ли такое?

Да, это возможно. Я описал такой механизм здесь: https://github.com/oliviertassinari/react-swipeable-views/issues/453#issuecomment -417939459.

Я не уверен, имеете ли вы в виду мастер или нет (асинхронный режим официально не доступен в выпусках npm)

Да, мы используем пакет npm с <unstable_AsyncMode> , flushSync и unstable_deferredUpdates .

Пожалуйста, начните выпускать альфа / бета версии с этими изменениями в npm! 🙏

Да, это возможно. Я описал такой механизм здесь: oliviertassinari / react-swipeable-views # 453 (комментарий).

Блестяще. Намного лучше, чем наша текущая реализация с использованием unstable_deferredUpdates :)

Не могу дождаться, чтобы начать использовать <div hidden> . Вы, ребята, делаете потрясающую работу.

@luisherranz Будьте осторожны, эти вещи _на_ нестабильны. Может иметь ошибки или быть довольно неэффективным (например, критическая оптимизация - «возобновление» - еще не реализована). Мы также удаляем unstable_deferredUpdates в пользу нового модуля schedule ( schedule.unstable_scheduleWork ).

Да, мы используем его только для небольшой части приложения и интенсивно тестируем, но пока все хорошо :)

МОЖЕТ БЫТЬ ОФТОПИЧНЫМ:
requestIdleCallback вызывается только 20 раз в секунду - Chrome на моей машине с Linux 6x2, это не очень полезно для работы пользовательского интерфейса.
requestAnimationFrame вызывается чаще, но зависит от задачи, название которой предполагает.

По этой причине мы перестали использовать requestIdleCallback .

Что вы используете вместо requestIdleCallback ?

Ну конечно. Я такой глупый. Мне было интересно, какой API-интерфейс браузера модуль планировщика использует под капотом вместо requestIdleCallback . Надо было более четко поставить вопрос. 😅

Ого, нашел.
https://github.com/facebook/react/blob/eeb817785c771362416fd87ea7d2a1a32dde9842/packages/scheduler/src/Scheduler.js#L212 -L222

Это круто следующего уровня.

Привет,

пытаясь понять Suspense, я понял, что понятия не имею, какая часть приложения фактически «приостанавливается» при использовании компонента Suspend 😳😱.

В следующем примере я ожидал бы, что Title будет видимым немедленно, Spinner после 1000 мс и UserData после ~ 2000 мс (поскольку «загрузка» данных для этого компонента занимает 2000 мс).
Но я вижу, что Title сначала появляется вместе с Spinner после 1000 мс.

// longRunningOperation returns a promise that resolves after 2000ms
const UserResource = createResource(longRunningOperation);

function UserData() {
  const userData = UserResource.read(cache, "Lorem Ipsum");
  return <p>User Data: {userData}</p>;
}

function Spinner() {
  return <h1>Fallback Loading Spinner</h1>;
}

function Title() {
  return <h1>Hello World</h1>;
}

function App() {
  return (
    <React.Fragment>
      <Title />
      <Suspense maxDuration={1000} fallback={<Spinner />}>
        <UserData />
      </Suspense>
    </React.Fragment>
  );
}

unstable_createRoot(document.getElementById("mount")).render(<App />);

(Вы можете найти полный пример, в котором используется React 16.6.0-alpha.8af6728, здесь, вcodeandbox )

Есть ли способ сделать Title сразу видимым и "приостановить" только другую часть приложения? Или я неправильно понял, может быть, саспенс полностью? (Если есть лучший способ задать такие вопросы, дайте мне знать)

Спасибо!

Привет @nilshartmann! Отличный вопрос!

Есть ли способ сделать заголовок сразу видимым и "приостановить" только другую часть приложения?

Если я правильно понимаю, вам нужно явно указать React _ not wait_ перед сбросом Title в DOM, как в этом примере , чтобы сделать Title сразу видимым и "приостановить" только другой часть приложения, обернув части, которые, как вы ожидаете, будут немедленно визуализированы, в <Suspense maxDuration={0}> .

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

Я очень рад услышать, что там на самом деле происходит.

(Если есть лучший способ задать такие вопросы, дайте мне знать)

Я не уверен, что есть. 😄 Мне это кажется совершенно ясным. Спасибо за вопрос!

@TejasQ В моем браузере загрузка вашего примера сразу отображает резервный счетчик. Разве он не должен загружаться через 1000 мс?

@TejasQ благодарит за ответ, но @karlhorky прав: теперь сразу появляется счетчик.

Ой! Я пропустил это. Я пытался. - Позвольте мне еще раз взглянуть на это и вернуться к вам. Я, должно быть, что-то упустил. 🤷‍♂️

~ Обновление: я пытаюсь понять это здесь, и мы можем сотрудничать, если кому-то интересно, сделать это вместе в реальном времени. ~

Второе обновление: мы с @ philipp-spiess посмотрели на него и искренне озадачены. Я до сих пор этого не понимаю. На данный момент я не уверен, что это ошибка, поскольку это, по сути, unstable_ и альфа-функция, или это то, чего я просто не вижу.

В любом случае, я чувствую, что основная команда либо получит полезные ответы, либо сможет использовать ваш вопрос, чтобы сделать React еще лучше / доступнее.

Посмотрим, что они скажут. 😄 Спасибо, что указали на это, @nilshartmann!

Это было выпущено как часть React v16.6? В сообщении блога показан пример кода с использованием Suspense:

import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));

function MyComponent() (
  <Suspense fallback={<div>Loading...</div>}>
    <OtherComponent />
  </Suspense>
);

Это было выпущено как часть React v16.6?

Только вариант с отложенной загрузкой и только в режиме синхронизации. Параллельный режим по-прежнему остается незавершенным.

@nilshartmann

В следующем примере я ожидаю, что Title будет виден сразу, Spinner - через 1000 мс, а UserData - через ~ 2000 мс (поскольку «загрузка» данных для этого компонента занимает 2000 мс).

Я действительно думаю, что вы немного запутались в том, что делает maxDuration . Это новая ментальная модель, но у нас еще не было времени задокументировать ее. Так что некоторое время это будет сбивать с толку, пока в стабильной версии не появится параллельный режим.

Поздравляем с объявлением предложения о крючках. Хочу чем-то поделиться с командой. Некоторое время назад я выпустил компонент под названием React Async , который имеет функции, аналогичные Suspense. По сути, он обрабатывает разрешение Promise и предоставляет метаданные, такие как isLoading, StartAt и методы, такие как перезагрузка и отмена, все с декларативным API (и перехватчик useAsync уже на подходе).

Теперь меня больше всего беспокоит, как это будет интегрировано с Suspense. По большей части я, вероятно, могу использовать API-интерфейсы Suspense из React Async и предоставить пользователям знакомый и простой API-интерфейс React Async, предлагая при этом функции планирования Suspense бесплатно. Что касается того, что я видел, я искренне считаю, что React Async API более разумный и доступный по сравнению с более абстрактными Suspense API. По сути, React Async пытается предложить более конкретный API, который работает для немного меньшего набора вариантов использования.

Я был удивлен, узнав о библиотеке React Cache. Для React Async я сознательно не включил механизм кеширования, но решил иметь дело с ванильными обещаниями. Добавить кеширование поверх этого довольно просто.

Наконец, меня беспокоит доступ к функциям Suspense с помощью настраиваемых хуков. Suspense, похоже, сильно зависит от нескольких встроенных компонентов, что делает невозможным (я так думаю?) Использовать их без проблем. Будут ли зацепки Suspense? Или есть другой способ их интеграции?

Привет. Как я могу протестировать код с помощью Suspense / Lazy?
теперь renderer.create (...) toTree () выбрасывает
"toTree () еще не знает, как обрабатывать узлы с tag = 13"

Почему свойства maxDuration в Suspense используются только в Concurrent Mode а не в синхронном и параллельном режимах. Кто-нибудь может помочь объяснить?

(Прямо сейчас) это означает, как долго Concurrent Mode может оставлять это дерево в ожидании, прежде чем принудительно выполнить его фиксацию - он эффективно контролирует крайний срок квантования времени, а квантование времени не существует в режиме синхронизации. Ожидание перед фиксацией дерева обязательно приведет к фиксации ... не Sync.

Я использовал Suspense во внутреннем приложении для выборки данных и очень быстро обнаружил причину, по которой он еще не предназначен для использования для выборки данных.

В конце концов, однако, он предназначен для получения данных. Учитывая, что кажется маловероятным, что API существенно изменится, за исключением, возможно, поставщика кеша, как может работать Suspense, если вам нужно изменить данные после того, как вы их получили?

В качестве примера приведу действительно ужасную ловушку из моего приложения.

function useComponentList(id) {
  const incomingComponents = useSuspenseFetch(
    React.useCallback(() => getComponentAPI().listComponents(id), [id])
  )

  const map = React.useMemo(
    () =>
      Map(
        (incomingComponents || []).map(component => [component.id, component])
      ),
    [incomingComponents]
  )

  return useCacheValue(map)
}

Этот хук:

  1. Получает данные с помощью заданного обратного вызова из заданной конечной точки
  2. Преобразует эти данные в карту ImmutableJS. Поскольку это потенциально дорого, я запомнил операцию.
  3. Возвращает карту, заключенную в useCacheValue , что особенно неудобно.

useCacheValue выглядит так:

export default function useCacheValue(value) {
  const [state, setState] = React.useState(value)
  React.useEffect(() => {
    setState(value)
  }, [value])

  return [state, setState]
}

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

Я изо всех сил пытаюсь понять, насколько хорошо этот шаблон работает с Redux в его текущем состоянии. Было ли открытие того, как это может выглядеть, когда написано не мной, а программистом, и когда ожидание «готово» к выборке данных? В нынешнем виде это намного труднее, чем использование Redux самостоятельно с флагами императивной выборки.

Это, вероятно, станет намного проще, если у Redux есть свои собственные хуки, поскольку основная трудность в том, чтобы заставить их играть вместе, заключается в том, что Redux использует HOC с контекстом, который не предназначен для раскрытия, но я все же хотел бы увидеть, что официальное ответ :)

Suspense предназначен для работы с внешним кешем (а не с хуком, управляемым состоянием). Мы предоставим эталонную реализацию такого кеша, которая подходит для простых случаев использования. Relay будет реализовывать собственный механизм кэширования. Любые другие инструменты (такие как Apollo) также смогут реализовать свой собственный совместимый кеш, возможно, вдохновленный этими двумя реализациями.

Мутация / признание недействительности - не единственный вопрос, на который нужны ответы. Нам также нужно подумать о том, когда показывать счетчики, общие шаблоны, такие как «встроенный индикатор», который может находиться за пределами приостановленного дерева, координировать состояния загрузки (для вещей, которые необходимо разблокировать в порядке сверху вниз или которые входят в исходное состояние). готово), потоковая визуализация списков, как это влияет на частичную гидратацию и т. д. Мы работаем над этими вещами, но пока нет «официальных рекомендаций» ни по одному из них. Когда появится, вы узнаете об этом из блога, в котором мы сообщаем об обновлениях.

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

@gaearon Когда вы говорите «мы работаем над этими вещами», есть ли проблема, на которую я могу подписаться, или эти обсуждения происходят наедине?

Спасибо, @gaearon :)

@ntucker Как всегда, вы можете наблюдать за текущей активностью в виде PR. Например: https://github.com/facebook/react/pull/14717 , https://github.com/facebook/react/pull/14884 , https://github.com/facebook/react/pull/15061. , https://github.com/facebook/react/pull/15151 , https://github.com/facebook/react/pull/15272 , https://github.com/facebook/react/pull/15358 , https : //github.com/facebook/react/pull/15367 и так далее. Мы стараемся добавить описательную информацию в каждый PR, и вы можете увидеть изменения в поведении по результатам тестов. Панель документации для экспериментов низкая по нескольким причинам.

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

Еще хуже то, что это часто приводит к тому, что люди строят ментальную модель вокруг чего-то, что, как мы позже понимаем, не работает так, как было задумано изначально. (Как это происходит с maxDuration который мы только что удалили.) Поэтому мы бы предпочли не делиться недоработанными идеями до тех пор, пока они не будут эффективно использовать как ваше, так и наше время. Это согласуется с тем, как мы разрабатывали React в прошлом. Когда что-то действительно готово (даже для теоретического описания ментальной модели), мы сосредоточим все свое внимание на документировании и объяснении этого.

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

@gaearon , к счастью, ментальная модель

В дорожной карте, объявленной в ноябре прошлого года (https://reactjs.org/blog/2018/11/27/react-16-roadmap.html), указано, что «параллельная» версия Suspense намечена на второй квартал 2019 года. Третий квартал 2019 года. Есть ли обновления, которые мы можем получить точно не за третий квартал или, может быть, за третий квартал и т. Д.?

Это было последнее обновление дорожной карты, которое я смог найти: https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#an -update-to-the-roadmap

Мы представили экспериментальный выпуск еще в октябре: https://reactjs.org/docs/concurrent-mode-intro.html. Это та же самая сборка, которую мы запускаем в производстве. Еще многое предстоит сделать (как в плане настройки API, так и создания API более высокого уровня), но вы можете начать с ним поиграть, если хотите.

Неизвестность убивает меня

@gaearon Я понимаю, что вы используете его в продакшене. Но я очень не хочу использовать «экспериментальный» код в продакшене. Вы, ребята, не совсем понимаете дорожную карту, статус, прогресс, сроки и т. Д. Это качество альфа, бета, RC? Этот термин «экспериментальный» говорит мне «не трогай это».

Мы все строим свой бизнес на этом коде, и я уверен, что мы все так же завалены, как и вы, ребята. Немного ясности, блог, ЧТО-ТО действительно помогло бы. Такое ощущение, что «он находится в разработке в Facebook, так что мы закончили».

@mschipperheyn

Это многолетний проект. Честно говоря, он потребовал больше работы, чем мы думали, когда начали над ним два года назад.

Но хорошая новость заключается в том, что ,

Вот примерное состояние различных направлений работы на сегодняшний день:

  • <Suspense> API для разделения кода с помощью lazy . ( поставляется в React 16.6)

    • Как вы, возможно, знаете, вы уже можете использовать это.

  • API параллельного режима, например createRoot и useTransition . ( доступно в выпусках experimental )

    • Решение для совместимости с Flux-подобными библиотеками. ( в процессе @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • Смена модели приоритета на более разумную. ( в процессе @acdlite , https://github.com/facebook/react/pull/18612)

    • Дождитесь завершения только последнего ожидающего перехода. ( в процессе @acdlite)

    • Offscreen API ( в процессе @lunaruan)

    • Огненные эффекты при скрытии / отображении контента для Suspense

    • Эффекты огня при скрытии / отображении контента вне экрана

    • Показывать и скрывать дочерние элементы портала при необходимости

    • Согласование с текущей работой по стандартизации для планирования ( не начато )

    • Исправить основные известные ошибки ( в процессе @gaearon и @acdlite)

    • Измените семантику события. ( в процессе @sebmarkbage @trueadm)

    • Делегировать на root вместо document, чтобы обеспечить более постепенное внедрение ( в процессе , @trueadm)

    • Сбрасывать дискретные события в фазе захвата.

    • Рассмотрите возможность получения приоритета по умолчанию из event чтобы лучше играть с императивным кодом.

    • Завершите работу над семантикой и значениями по умолчанию для других API. ( не началось )

    • Обновите типографии и документацию.

  • Приостановка получения данных

    • Низкоуровневая поддержка сигнализации о том, что компонент не готов к рендерингу (технически доступен и в стабильном React, но этот API не считается стабильным).

    • Серверный рендерер немедленно сбрасывает резервные копии Suspense ( доступно в экспериментальных выпусках)

    • Решение для случаев использования GraphQL (Relay Hooks, поставляется ).

    • Решение для случаев использования, отличных от GraphQL ( в разработке @sebmarkbage в сотрудничестве с Next.js).

    • Интеграция сборщика для зависимостей, управляемых данными. ( в процессе )

    • Завершить API блоков, включая контекст.

    • Общее решение для кеширования. ( не началось )

    • Какая-то интеграция с роутером.

Такое ощущение, что «он находится в разработке в Facebook, так что мы закончили».

Я понимаю, как это могло бы выглядеть таким образом, хотя это чтение немного деморализует. :-) Мы непрерывно работали над этим все последние месяцы, и многие технические аспекты либо уже завершены, либо близки к завершению. Большинство оставшихся работ делятся на две категории:

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

  • Совместимость экосистемы и хорошие настройки по умолчанию. Не поможет, если мы выпустим то, что сегодня никто не может использовать, потому что это не работает с их библиотеками или существующими подходами. Таким образом, основная работа (например, совместимость с Flux-подобными библиотеками через useMutableSource , выбор лучшей семантики событий, доставка рекомендованной стратегии кэширования) заключается в том, чтобы убедиться, что вы действительно сможете использовать то, что мы выпустили. Это длинный хвост.

С точки зрения «можете ли вы использовать сегодня» ... Технически, вы можете использовать все это сегодня. Мы делаем. В частности, мы используем Relay Hooks и Concurrent Mode. У нас все еще есть значительные запланированные изменения и известные проблемы, поэтому текущее состояние не соответствует планке, на которой мы бы считали его готовым к широкому применению. Конечно, если вы не против, чтобы ошибки или API менялись прямо у вас под рукой, вы можете использовать выпуски @experimental как и мы.

Я бы не сказал, что Facebook находится здесь в особом положении с точки зрения того, что мы «закончили». Напротив, мы еще не закончили, но внутренне мы готовы терпеть отток и строить на вершине движущегося поезда, потому что именно так мы знаем, что то, что мы строим, является прочным. Без этого тяжелого кормления недостатки, которые мы обнаружили за шесть месяцев, потребовалось бы несколько лет, чтобы их обнаружить и переработать.

Подводя итог: есть над чем поработать.

@gaearon Спасибо за это обновление! И прошу прощения, если мой тон был неправильным. Признаюсь, я был немного разочарован, просматривая Твиттер в течение нескольких месяцев и ничего не нашел. Этот аспект Server renderer immediately flushes Suspense fallbacks (available in experimental releases) выглядит как то, на что я мог бы выделить время при тестировании его с помощью Apollo Graphql для нашей реализации.

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

Серверный рендерер немедленно сбрасывает резервные копии Suspense (доступно в экспериментальных выпусках)

Где я могу прочитать об этом? Я надеялся, что справочник по API параллельного режима (экспериментальный), но не повезло.

Если у кого-то есть демо, сшивающее вместе Next.js, Relay Hooks и Concurrent Mode (с SSR), это было бы здорово. В противном случае я мог бы просто попытать счастья, если найду достаточно документации.

@CrocoDillon

Нет никаких дополнительных документов о SSR, но в основном потому, что это просто новое поведение по умолчанию.

Если у вас экспериментальный выпуск, чем когда-либо компонент приостанавливается на сервере, вместо этого мы сбрасываем ближайший резервный вариант Suspense. Затем на клиенте вы должны использовать createRoot(node, { hydrate: true }).render(<App />) .

Обратите внимание, что это уже включает все новые функции гидратации. Так, например, ваши границы Suspense будут «прикреплены» к сгенерированному сервером резервному HTML, а затем попытаются выполнить рендеринг на клиенте.

Также обратите внимание, что вы можете начать пить до того, как загрузится все приложение. Когда <App> загрузится, вы можете гидратировать. Пока компоненты ниже приостанавливаются, когда их код не готов (аналогично ленивому). В этом случае React сохранит HTML-контент сервера, но «прикрепит» к нему границу Suspense. Когда дочерние компоненты загрузятся, он продолжит увлажнение. Гидратированные части станут интерактивными и будут воспроизводить события.

Вероятно, вы можете спросить @devknoll о следующих попытках / примерах интеграции. Вероятно, он есть.

Вы можете включить параллельный режим в Next.js, установив react@experimental и react-dom@experimental и добавив следующее в next.config.js

// next.config.js
module.exports = {
  experimental: {
    reactMode: 'concurrent'
  }
}

Вот обсуждение Next.js по этому поводу: https://github.com/zeit/next.js/discussions/10645

Можно ли дождаться каких-либо задержек в рендеринге сервера (например, в таких случаях, как создание статического сайта)? Я согласен с тем, что использование обратных вызовов - хорошее решение по умолчанию, просто интересно, можно ли его переопределить?

Также обратите внимание, что вы можете начать пить до того, как загрузится все приложение. Когдазагрузился, вы можете гидратировать. Пока компоненты ниже приостанавливаются, когда их код не готов (аналогично ленивому). В этом случае React сохранит HTML-контент сервера, но «прикрепит» к нему границу Suspense. Когда дочерние компоненты загрузятся, он продолжит увлажнение. Гидратированные части станут интерактивными и будут воспроизводить события.

@gaearon , вы имеете в виду, что вы можете нормально рендерить компонент на сервере, но использовать React.lazy на клиенте? Позволяет вернуть полную разметку с сервера, но отложить синтаксический анализ и рендеринг кода компонента на клиенте. Разметка, созданная сервером, здесь действует как резервное решение?

@robrichard Я на самом деле не пробовал это с React.lazy специально (мы используем другую оболочку в FB, и Next также имеет свою версию), но я ожидаю, что это будет работать именно так. Стоит проверить :-) С определенными ограничениями - например, если вы обновляете его реквизиты, а выше нет спасения для мемо, или если вы обновляете контекст над ним, нам придется удалить его и показать запасной вариант, потому что мы не знаем, что делать. с этим.

@gaearon каково текущее состояние частичной гидратации? Я знаю, что # 14717 был объединен, но я сомневаюсь, что он вошел в какой-либо релиз?

Он уже давно присутствует в каждом выпуске @experimental , если вы используете unstable_createRoot API.

@gaearon , пожалуйста, поясните, что вы подразумеваете под «зависимостями, управляемыми данными»?

@gaearon , пожалуйста, поясните, что вы подразумеваете под «зависимостями, управляемыми данными»?

Да, конечно. Я должен извиниться за краткость приведенного выше списка - он очень сжат, и многие из них являются важными отдельными подпроектами (поэтому они требуют времени).

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

У нас очень высокая планка того, что попадает в «официальный» React. Чтобы быть «Reacty», он должен составлять так же хорошо, как и обычные компоненты React. Это означает, что мы не можем добросовестно рекомендовать решение, которое, по нашему мнению, не может масштабироваться до тысяч компонентов. Мы также не можем рекомендовать решение, которое заставляет вас писать код запутанным оптимизированным способом, чтобы поддерживать его работоспособность. В FB мы извлекли много уроков из этого от команды Relay. Мы знаем, что не все могут использовать GraphQL или хотели бы использовать Relay (сам по себе он не очень популярен, и команда не оптимизировала его для внешнего внедрения). Но мы хотим убедиться, что наше решение для получения данных для общего React включает в себя с трудом заработанные уроки Relay и не страдает от необходимости выбирать между производительностью и размещением.

Я хочу подчеркнуть, что речь идет не только о больших приложениях. Проблемы наиболее заметны в больших приложениях, но небольшие приложения, которые импортируют набор компонентов из npm, также страдают от подмножества этих недостатков. Например, отправка слишком большого количества клиентского кода и загрузка его в виде водопада. Или слишком много загружается заранее. Кроме того, небольшие приложения не остаются маленькими навсегда. Нам нужно решение, которое отлично работает для приложения любого размера, точно так же, как модель компонентов React работает одинаково, независимо от сложности вашего приложения.

Теперь, чтобы ответить на ваш конкретный вопрос. Relay имеет функцию, называемую «зависимостями, управляемыми данными». Один из способов подумать об этом - это эволюция динамического import . Динамический import не всегда эффективен. Если вы хотите загрузить какой-то код только тогда, когда условие истинно (например, «пользователь вошел в систему» ​​или «есть ли у пользователя непрочитанные сообщения»), ваш единственный вариант - запустить его лениво. Но это означает, что вы «начинаете» загрузку (например, с React.lazy ) только тогда, когда что-то используется. На самом деле уже слишком поздно. Например, если у вас есть несколько уровней компонентов с разделением кода (или компонентов, ожидающих данных), самый внутренний из них начнет загружаться только после того, как загрузится тот, который находится над ним. Это неэффективно и представляет собой сетевой «водопад». «Зависимости, управляемые данными» ретранслятора позволяют указать модули, которые вы хотите получить как часть запроса. Т.е. «если какое-то условие истинно, включить этот фрагмент кода в ответ с данными». Это позволяет загружать все фрагменты с разделением кода, которые вам понадобятся, как можно раньше. Вам не нужно менять колокацию на производительность. Это может показаться не таким уж большим делом, но это позволило сократить буквально секунды в коде продукта.

Опять же, мы не внедряем Relay в React и не хотим заставлять людей использовать GraphQL. Но концептуально сама функция является универсальной, и наличие хорошего решения с открытым исходным кодом для нее позволило бы людям выполнять гораздо больше разделения кода, чем это делается сегодня (и, таким образом, отправлять намного меньше клиентского JS-кода!) Эта универсальная функция не будет вызываться. «зависимости, управляемые данными» - это просто название Relay, о котором я говорил. Эта функция будет частью более крупного рекомендованного решения, которое не требует GraphQL. Я просто упомянул его под этим именем в списке, потому что для одного пункта маркированного списка было много объяснений.

Надеюсь, это проясняет это.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги