React: [Guarda-chuva] Liberando Suspense

Criado em 13 jul. 2018  ·  83Comentários  ·  Fonte: facebook/react

Vamos usar esse problema para rastrear as tarefas restantes para liberar o Suspense para o código aberto.

Versão inicial (MVP)

Testemunho

  • [x] API para ler o contexto de qualquer função de fase de renderização (@acdlite) [# 13139]
  • [x] Ocultar conteúdo expirado em vez de excluí-lo (@acdlite) [# 13120]
  • [] Injeção automática de provedores de contexto por raiz React (@acdlite) [# 13293]
  • [] Remova o prefixo unstable_ de AsyncMode (talvez?)
  • [] Suporte para thenables síncronos e para promessas que são resolvidas antes que a fase de renderização seja concluída.

    • [] Confirme se um thenable síncrono que lança um erro foi tratado corretamente

  • [] Confirme se funciona com <div hidden> [# 13089]
  • [] Por que clicar em vários links de detalhes no acessório, um por um, eventualmente causa um grande espaço reservado, mesmo se eu esperar por cada um deles por menos do que o atraso do espaço reservado antes de clicar no próximo ( veja o tweet )?

Provedor de Cache Simples

  • [] Invalidação de cache (@acdlite) [# 13337]
  • [] Assinaturas (@acdlite) [# 13337]
  • [] Decida o nome real

Divisão de código

  • [x] Promessa de suporte como um tipo de componente
  • [x] (talvez) Código aberto lazyLoadComponent ?

Renderizador de teste

  • [] Finalize APIs públicas para flushAll , yield , etc.

    • O plano provisório é publicar correspondências personalizadas para cada uma das principais estruturas de teste, a la # 13236.

Docs

  • [] Postagem do blog
  • [] React.Placeholder
  • [] provedor de cache simples
  • [] Biblioteca de divisão de código sem nome

Acompanhamentos

Expiração suave (https://github.com/facebook/react/issues/14248)

  • [] Implementar uma API para indicadores de carregamento no local que não são ancestrais
  • [] Certifique-se de que haja uma maneira de evitar piscar o botão giratório embutido se ele for rápido o suficiente

Processador de servidor de streaming

  • [] Implementar um renderizador de servidor de streaming como o da conversa ZEIT de @acdlite
  • [] Hidratação parcial

Relacionado: Guarda-chuva do Time Slicing (https://github.com/facebook/react/issues/13306)

React Core Team Umbrella

Comentários muito úteis

@mschipperheyn

Este é um projeto de vários anos. A resposta honesta é que gerou muito mais trabalho do que pensávamos quando começamos, há dois anos.

Mas a boa notícia é que, como agora o usamos intensamente na produção, as peças que faltam estão claras e vemos o fim do túnel. Não é teórico - há um conjunto finito de coisas que precisamos terminar antes que possamos dizer confortavelmente que está pronto para ampla adoção.

Aqui está um estado aproximado de diferentes fluxos de trabalho hoje:

  • <Suspense> API para divisão de código com lazy . ( enviado no React 16.6)

    • Como você deve saber, você já pode usar este.

  • APIs de modo simultâneo, por exemplo, createRoot e useTransition . ( disponível em lançamentos de experimental )

    • Solução de compatibilidade para bibliotecas do tipo Flux. ( em andamento @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • Mudar o modelo de prioridade para um mais sensato. ( em andamento @acdlite , https://github.com/facebook/react/pull/18612)

    • Permita que apenas a última transição pendente termine. ( em andamento @acdlite)

    • API fora da tela (

    • Efeitos de fogo ao ocultar / mostrar conteúdo para Suspense

    • Efeitos de fogo ao ocultar / mostrar conteúdo fora da tela

    • Mostrar e ocultar os filhos do Portal quando necessário

    • Alinhe-se com o trabalho de padronização em andamento para Agendamento ( não iniciado )

    • Corrija os principais bugs conhecidos ( em andamento @gaearon e @acdlite)

    • Altere a semântica do evento. ( em andamento @sebmarkbage @trueadm)

    • Delegar às raízes em vez de documentar para permitir uma adoção mais gradual ( em andamento , @trueadm)

    • Libere eventos discretos na fase de captura.

    • Considere obter a prioridade padrão de event para jogar melhor com o código imperativo.

    • Finalize outras semânticas e padrões da API. ( não começou )

    • Atualizar tipificações e documentação.

  • Suspense para obtenção de dados

    • O suporte de baixo nível para sinalizar que um componente não está pronto para renderizar (tecnicamente disponível no React estável também, mas esta API não é considerada estável).

    • O renderizador do servidor libera imediatamente os substitutos do Suspense ( disponíveis em versões experimentais)

    • Uma solução para casos de uso GraphQL (Relay Hooks, enviado ).

    • Uma solução para casos de uso não GraphQL ( em andamento @sebmarkbage em colaboração com Next.js).

    • Uma integração de bundler para dependências baseadas em dados. ( em andamento )

    • Finalize API de blocos, incluindo contexto.

    • Uma solução de cache genérica. ( não começou )

    • Algum tipo de integração de roteador.

Quase parece "Está em produção no Facebook, então terminamos".

Posso ver como poderia ser assim, embora tbh essa leitura seja um pouco desmoralizante. :-) Temos trabalhado sem parar nisso durante todos os últimos meses, e muitos dos aspectos técnicos já foram concluídos ou estão perto de serem concluídos. A maioria das obras restantes se enquadra em duas categorias:

  • Corrigindo as falhas que descobrimos nos projetos iniciais antes de consolidá-los em uma versão estável. Se quiséssemos lançar o que temos agora, teríamos que seguir em frente com mudanças significativas e inovadoras em alguns meses. Isso só seria confuso.

  • Compatibilidade do ecossistema e bons padrões. Não ajuda se lançarmos algo que ninguém pode usar hoje porque não funciona com suas bibliotecas ou abordagens existentes. Portanto, a maior parte do trabalho (por exemplo, compatibilidade com bibliotecas semelhantes ao Flux por meio de useMutableSource , escolher melhor semântica de eventos, enviar uma estratégia de cache recomendada) é garantir que você realmente seja capaz de usar o que lançamos. Esta é uma longa cauda.

Em termos de "você pode usar hoje" ... Tecnicamente, você pode usar tudo isso hoje. Nós fazemos. Especificamente, usamos Relay Hooks e Concurrent Mode. Ainda temos mudanças planejadas significativas e problemas conhecidos, então o estado atual não está atingindo o nível que consideramos pronto para ampla adoção. Claro, se você não se importa em ter bugs ou APIs mudando em suas mãos, você pode usar os lançamentos de @experimental assim como nós.

Eu não diria que o Facebook está em uma posição especial aqui em termos de "terminarmos". Muito pelo contrário, não terminamos - mas internamente, estamos dispostos a tolerar a rotatividade e construir em cima de um trem em movimento, porque é assim que sabemos que o que estamos construindo é sólido. Sem esse dogfooding pesado, as falhas que descobrimos em seis meses levariam vários anos para serem descobertas e redesenhadas.

Para resumir: há mais trabalho a fazer.

Todos 83 comentários

Exponha unstable_AsyncMode (talvez?)

Isso não está

Eu quis dizer remover unstable_

Estou ansioso para abrir o código-fonte da biblioteca de divisão de código sem nome 💯

O que isso significa [Guarda-chuva]? 🤔☂️

Ou seja, é um recurso que impacta diversos projetos / pacotes / ferramentas.

@ghoullier entendo, muito obrigado!

Olá @acdlite , só uma pergunta sobre a melhor forma de se preparar para isso. Não pedindo / esperando nenhum tipo de cronograma, mas pensando:

No momento, você espera que esses recursos caiam no React 16 e sejam fáceis de adotar de forma incremental, como a nova API de contexto que veio com o 16.3?

Ou você está pensando que será algo que empurrará o React para a versão 17 e exigirá mais trabalho para ser adotado?

Perguntar porque estou trabalhando em um roteiro que cruza significativamente com quase tudo em sua lista e estou tentando descobrir a melhor forma de lidar com isso.

Além disso, você tem alguma dica sobre como se preparar melhor (em termos de código escrito hoje, que quer ser compatível no futuro com essas melhorias do React) - polyfills / técnicas / etc?

(desculpas se essas perguntas foram respondidas em outro lugar e eu as perdi)

Adicionando outra pergunta às perguntas de @JedWatson :

  • Também não precisamos / esperamos obter um cronograma para um lançamento estável, mas seria possível / útil obter um novo pré-lançamento? (AFAIK, o lançamento mais recente é 16.4.0-alpha.0911da3 de fevereiro.)

Obrigada! ❤️

IMO, eles fornecerão uma postagem no blog como antes.

E eu acho que você não precisa se preparar muito porque não há nenhuma mudança significativa (ele tem muitos recursos que talvez pareçam diferentes / conflitem com as práticas atuais, como redux fetch com suspense, mas haverá um codemod ou encapsulamento fácil para fazer isso, você sabe, fb tem componentes 3W +). E se você assistir a conversa de @acdlite (sobre suspense de ssr em ZEIT) e @gaearon (sobre suspense de cliente na Islândia), saberá que não precisa se preocupar muito e não é invasivo.

A propósito, você pode apenas pesquisar a chave 'Umbrella' no repo e você encontrará mais informações como # 8830 e # 12152

AFAIK, a versão mais recente é 16.4.0-alpha.0911da3 de fevereiro.

IIRC, isso é uma operação incorreta?

Estou trabalhando no lançamento do módulo de suspense e novas APIs no Facebook. Caso @acdlite esteja ocupado com outra coisa, gostaria de compartilhar alguns dos meus pensamentos sobre nossa experiência no Facebook e responder a algumas perguntas de @JedWatson.

No momento, você espera que esses recursos caiam no React 16 e sejam fáceis de adotar de forma incremental, como a nova API de contexto que veio com o 16.3?

Não tenho certeza se virá com React 16 ou 17. De acordo com a equipe do React, é provável que seja lançado antes do final deste ano, o que depende de quão bem ele funciona no Facebook e como a API relacionada está pronta ou não. Mas em termos de código, fico feliz em dizer que seria fácil de adotar, porque estamos experimentando há um bom tempo no Facebook. O recurso de suspense ainda funcionará para a base de código existente. Mas com mudanças adicionais (como renderização assíncrona), você terá mais bônus do que o novo recurso lhe trará.

Você tem alguma dica de como se preparar melhor (em termos de código escrito hoje, que quer ser compatível no futuro com essas melhorias do React) - polyfills / técnicas / etc?

Eu diria que a migração é bastante incremental e progressiva. Como @ NE-SmallTown disse, não queremos introduzir nenhuma alteração importante. Isso também seria doloroso para lançar no Facebook, porque temos uma base de código muito grande. Mas, até agora, o lançamento tem sido tranquilo e não exige que você faça alterações adicionais.

@JedWatson

No momento, você espera que esses recursos caiam no React 16 e sejam fáceis de adotar de forma incremental, como a nova API de contexto que veio com o 16.3?

Incrementalmente. Sempre de forma incremental :) Do contrário, não poderíamos enviar isso no Facebook.

Aqui está o que estou esperando:

| | Cliente | Renderização do lado do servidor |
| ----------------- | ---------------------------- | - -------------------------------------------- |
| Suspense | Funciona em qualquer lugar * | Mesmas restrições do renderizador de servidor existente |
| Renderização assíncrona | Inscreva-se usando <AsyncMode> | Mesmas restrições do renderizador de servidor existente |

* No modo de sincronização, delayMs é sempre 0 . Os marcadores de posição aparecem imediatamente.

Suspense funcionará sem qualquer alteração em seus componentes existentes. Em um ponto, pensamos que poderíamos exigir a compatibilidade de <StrictMode> , mas durante nossos testes internos, descobrimos que uma das melhores maneiras de atualizar para o modo estrito era usar Suspense. Dilema do ovo de galinha. Então, descobrimos uma maneira de fazê-lo funcionar mesmo fora do modo estrito.

Portanto, a ideia é que os usuários comecem a migrar para o Suspense antes mesmo de estarem prontos para migrar para a renderização assíncrona. Então, quando uma subárvore está pronta, eles podem optar por incluir <AsyncMode> .

Para novos aplicativos, porém, a história é diferente: vá assíncrono por padrão. Apresentaremos uma nova API raiz (uma substituição para ReactDOM.render ) que é apenas assíncrona.

Haverá um período estranho após o lançamento inicial, em que muitos frameworks de terceiros (Redux, Apollo, React Router ...) podem não funcionar corretamente no modo assíncrono. Isso pode prejudicar a adoção por um tempo. Mas a ideia é que os novos recursos serão tão atraentes que não demorará muito para que as bibliotecas se adaptem ou sejam substituídas por uma alternativa compatível com async.

Além disso, você tem alguma dica sobre como se preparar melhor (em termos de código escrito hoje, que quer ser compatível no futuro com essas melhorias do React) - polyfills / técnicas / etc?

Envolva tudo em <StrictMode> e certifique-se de que não haja avisos. Teremos guias de migração mais detalhados conforme nos aproximamos do lançamento.

Haverá um período estranho após o lançamento inicial, em que muitos frameworks de terceiros (Redux, Apollo, React Router ...) podem não funcionar corretamente no modo assíncrono.

Apollo não é estranho - estaremos prontos! 🕺😳

Mas, falando sério, nós: heart: all things React, então ter certeza de que estamos alinhados com essas mudanças para o lançamento inicial não é apenas uma alta prioridade, mas também é algo que nos deixa muito animados! Obrigado por todo o seu trabalho incrível neste @acdlite!

Vou gritar e dizer que a equipe Redux está trabalhando em compatibilidade assíncrona para React-Redux.

Apresentei um possível roteiro em https://github.com/reduxjs/react-redux/issues/950 . TL; DR:

  • Esperamos que o React-Redux 5.1 funcione com <StrictMode> sem avisos (PR atual: https://github.com/reduxjs/react-redux/pull/980)
  • 6.0 será uma reescrita interna para usar a nova API de contexto, adicionar encaminhamento de referência e possivelmente outras alterações, mas tente manter o máximo possível da API pública atual (ou seja, <Provider> e connect() ). Veremos como isso funciona bem com a renderização assíncrona e descobriremos o melhor caminho a seguir. (Minha prova de conceito anterior está em https://github.com/reactjs/react-redux/pull/898, mas provavelmente iremos refazê-la com base em outras lições aprendidas com o trabalho 5.1.) É provável que esta versão exigiria React 16.5 no mínimo, devido à necessidade de um novo contexto e provavelmente também o PR "ler contexto de métodos de ciclo de vida" ainda não lançado, que acabou de ser mesclado.
  • Depois disso, estamos abertos a ideias para uma API React-Redux diferente (sim, sim, isso possivelmente inclui adereços de renderização, pessoal).

Agradeceríamos ter mais atenção em nosso WIP, e esperançosamente as pessoas podem nos dar mais feedback e discussão sobre como eles estão olhando para o uso do Redux com React Suspense e renderização assíncrona para que possamos garantir que os casos de uso sejam cobertos adequadamente. Também esperamos ter mais discussões com a equipe React sobre exatamente quais restrições precisamos trabalhar, e seria útil se pudéssemos obter alguns aplicativos de amostra que nos permitiriam ver quais problemas precisamos resolver para todos isso funcione corretamente.

ansioso para o lançamento de renderização Async e Suspense

@acdlite Também pergunta sobre suspense e renderização assíncrona.
Minha pergunta é quando eles forem introduzidos e começarmos a escrever aplicativos com essa nova versão do react: isso significa que a API do react e a forma como as pessoas reagem ao código também mudarão? (mesmo que eles não planejem usar recursos de suspense e renderização assíncrona?)

Suponho que pode ser mais complicado escrever código de reação com suspense e renderização assíncrona (talvez devido a alguma nova API ou outras restrições), e para aqueles que não precisam disso, por que forçá-los a usar o reagir de uma nova maneira? E não permitir que eles reajam da maneira como fazem agora?

Suponho que pode ser mais complicado escrever código de reação com suspense

Você teve a chance de assistir a segunda metade da minha palestra? Eu diria exatamente o oposto - é muito menos complicado usar o suspense para obter dados do que qualquer outra coisa (incluindo Redux, estado local ou alguma outra biblioteca).

@gaearon , não. Eu estava falando mais em teoria. Imagine que já existe um conjunto de pessoas que sabem reagir. Se as pessoas não precisam do recurso de renderização assíncrona e suspense, por que forçá-las a aprender uma reação "nova"? Especialmente se a "nova" reação for mais complicada de usar? Mas: Eu não estou bem informado, então posso estar errado ao dizer sobre a parte "complicada" - estou apenas compartilhando alguns dos meus pensamentos :).

De certa forma, estou dizendo se 10% dos aplicativos precisam do recurso Suspense e renderização assíncrona, por que nesses outros 90% os casos forçam as pessoas a aprender "novo" a reagir? Mas, novamente, posso estar errado, já que não reuni muitas informações sobre suspensão e renderização assíncrona ainda.

Acho que é difícil ter uma conversa se você ainda não leu minhas demos .

Para ser claro: não há um "novo React", esses recursos não quebram nenhum padrão existente 🙂. Eles são aditivos. Você também não precisa escrever código de uma maneira completamente diferente para usar esses recursos - embora alguns deles funcionem apenas se você usar métodos modernos de ciclo de vida .

Embora isso não esteja diretamente relacionado à sua preocupação, discordo que eles são "mais complicados de usar". Acho que o suspense é muito mais simples de usar do que qualquer outro mecanismo de carregamento que existe atualmente. É por isso que estou tão animado com isso. Mas, novamente, você não precisa usar nenhum dos novos recursos se não quiser. Os padrões antigos continuarão funcionando.

Eu realmente recomendo assistir minha palestra . Tenho certeza de que isso fará muito mais sentido quando você ver esses recursos em ação.

@gaearon

Todos os padrões antigos continuam funcionando.

Obrigado pelo feedback Dan. Sim, é assim que eu pensei, suponho que se as pessoas não precisarem desses recursos, eles devem ser capazes de escrever da maneira que costumavam fazer antes de esses recursos serem adicionados.

boa sorte.

Ei Dan (@gaearon), Eu não estou criticando, mas quero descobrir. Acima você disse:

Mas, novamente, você não precisa usar nenhum dos novos recursos se não quiser. Os padrões antigos continuarão funcionando.

O que sugere que eu posso codificar no novo React da mesma forma que fiz no React "antigo", por exemplo, eu poderia usar os métodos de ciclo de vida da mesma maneira, etc., certo?

No entanto, aqui , bvaughn diz que getDerivedStateFromProps (ou componentWillReceiveProps) pode ser chamado muitas vezes para uma atualização, daí sua solução para não buscar dados dentro dele.

Portanto, minha pergunta é, afinal, parece que não podemos usar o novo React exatamente da mesma maneira que antes, certo? Porque AFAIK no componente de reação atualWillReceiveProps não é chamado muitas vezes para uma atualização, não é?

@ giorgi-m: sim, os métodos de ciclo de vida estão mudando, mas a questão é que o próprio Suspense é um recurso opcional. Todos os métodos de renderização existentes do React e o comportamento de renderização do React funcionarão como estão. No entanto, _se_ você optar por adicionar uma tag <AsyncMode> a uma parte do seu aplicativo, _e_ você começar a usar a abordagem do Suspense para indicar as necessidades de dados assíncronos, _então_ poderá tirar proveito disso. Nada disso acontecerá se você não adicionar isso à sua base de código.

@ giorgi-m componentDidUpdate deve ser usado em vez de componentWillReceiveProps ou getDerivedStateFromProps .

@markerikson Então você diz que o que bvaughn disse aqui , que _getDerivedStateFromProps_ pode ser chamado várias vezes para uma atualização, não é necessariamente o caso, se eu não habilitei <AsyncMode/> ?
(desculpe por fazer essas perguntas, apenas elas surgem para mim de vez em quando e não encontraram recursos que abrangessem todas).

ps. bvaughn também não mencionou a opcionalidade disso no tópico vinculado, portanto, levantou minha suspeita.

Um método para enfileirar atualizações assíncronas (por exemplo, deferSetState() para componentes de classe em oposição a unstable_deferredUpdates() específicos do renderizador) deve ser adicionado à lista de verificação principal?

Pelo que entendi, qualquer atualização de fibras em mode assíncrona será assíncrona, o que em teoria significa que deferSetState() seria desnecessária. No entanto, a demonstração unstable-async/suspense mistura uma atualização síncrona e uma atualização assíncrona e não tenho certeza de como isso pode ser feito no modo async (para componentes "universais").

Está na lista de verificação do guarda-chuva do tempo fatiado.

Promessa de suporte como um tipo de componente

Relacionado a isso, quando você tem:

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

Existe alguma heurística para quando componentDidMount e componentDidUpdate lifecycles seriam chamados.

  1. Quando todos os filhos forem resolvidos (incluindo a promessa), o que, neste caso, significa que eles não serão chamados porque a promessa nunca é cumprida?
  2. Quando todos os filhos do host imediato foram renderizados?

@thysultan : componentDidMount e componentDidUpdate são chamados na fase de confirmação, quando uma árvore de IU foi totalmente renderizada e aplicada ao DOM.

Portanto, com base no meu entendimento do Suspense, acho que a resposta é que a instância A nunca seria montada de fato. Se PromiseType _did_ fosse resolvido, mas um de seus descendentes também tentasse esperar por uma promessa que nunca se resolve, ela nunca mais seria montada. Assim, cDM e cDU nunca seriam executados nesses exemplos.

(Alguém sinta-se à vontade para me corrigir se minhas suposições estiverem erradas aqui :))

Sim, componentDidMount ou componentDidUpdate só são executados na fase de confirmação, que só é executada depois que toda a árvore foi resolvida. Esta árvore pode incluir alguns marcadores de posição que você colocou explicitamente lá (dependendo se algo dentro deles ainda suspende depois de termos esperado o suficiente) - mas se você renderizar explicitamente um filho sem um marcador de posição em torno dele, você nunca poderá terminar em uma situação em que "não está pronto".

Estou realmente ansioso para poder brincar com isso (até mesmo naveguei em muitos códigos-fonte apenas para descobrir que você ainda não colocou uma versão funcional disso na rede mundial de computadores).

Há algo que possamos fazer para ajudar a liberar isso? : D

Você pode compilar do mestre se quiser jogar. Veja as instruções em fixtures/unstable-async/suspense

@gaearon Estou correto que isso está em seu estado atual apenas no lado do cliente (portanto, mais trabalho a ser feito para oferecer suporte à renderização do lado do servidor)?

EDIT, encontrou a resposta: Para qualquer pessoa que esteja ansiosamente procurando usar o Suspense em SSR para aplicativos universais. Eu encontrei este comentário de Dan que nos permite saber que este é o lado do cliente apenas por enquanto. No entanto, esse comentário também aponta para https://www.youtube.com/watch?v=z-6JC0_cOns, que fala sobre as possíveis implicações para SSR.

Na verdade, estamos iniciando alguns trabalhos relacionados ao caso SSR em breve.

Imagine este cenário em um aplicativo React assíncrono em execução em um dispositivo móvel de baixo custo:

  1. Há um carregamento de anúncio externo, usando toda a CPU (😓)
  2. O usuário clica em um link e o roteador aciona uma nova renderização
  3. O React está no modo assíncrono, por isso espera até que o Chrome / Safari conceda permissão para usar a CPU, mas o anúncio continua carregando por mais 3 segundos
  4. O usuário pensa que o aplicativo não está funcionando

Este problema poderia ser evitado usando a mesma técnica <Placeholder> discutida para Suspense, mostrando um spinner após 1 segundo, por exemplo.

Este cenário foi considerado? <Placeholder> funcionará para renderizações assíncronas lentas?

@luisherranz Existem dois mecanismos para evitar isso:

  1. O React tem um prazo associado a cada atualização. Atualizações de cliques e outras interações como essa devem ser liberadas em aproximadamente 150 ms, a menos que você opte explicitamente por um prazo mais longo (por exemplo, para atualizações não essenciais). Portanto, o React forçará o flush de forma síncrona se algo estiver monopolizando o thread.

  2. Na verdade, o React não usa mais requestIdleCallback porque, de fato, os navegadores não são agressivos o suficiente quanto a agendá-lo. A abordagem de programação exata também pode mudar com o tempo, mas isso é definitivamente algo com que nos preocupamos.

Muito obrigado pela resposta rápida Dan.

  1. React tem um prazo associado a cada atualização

Impressionante. Já existe uma API que poderíamos testar?

  1. Na verdade, o React não usa mais requestIdleCallback porque, de fato, os navegadores não são agressivos o suficiente quanto a agendá-lo.

Isso é o que também experimentamos. Às vezes, em um aplicativo lotado com anúncios externos e incorporações do Twitter ou YouTube, pode levar vários segundos até que requestIdleCallback seja chamado e a renderização seja concluída. Então, 👍 para isso.

BTW, para nós, há outro caso de uso relacionado à sua primeira resposta: estamos tentando usar lazyloads com dois offsets. O primeiro aciona uma renderização assíncrona, o segundo aciona uma renderização de sincronização se a assíncrona não tiver terminado. Algo assim:

  1. O usuário rola para baixo e está a 1200px de um elemento pesado: por exemplo, a próxima postagem de um blog.
  2. O primeiro deslocamento dispara uma renderização assíncrona da próxima postagem.
  3. O usuário continua rolando para baixo e está a 600px da próxima postagem.
  4. O segundo deslocamento dispara: Se a postagem assíncrona foi concluída (componentDidMount chamado) nada acontece, mas se não, dispara uma renderização de sincronização de toda a postagem.

Portanto, em vez do tempo, gostaríamos de controlar o flush com um segundo gatilho. Isso faz sentido? Isso poderia ser possível?

Já existe uma API que poderíamos testar?

Não tenho certeza se você quer dizer no master ou não (o modo assíncrono não está oficialmente disponível nas versões npm), mas o tempo de expiração é atribuído automaticamente a cada atualização. Para eventos como cliques, é de aproximadamente 150 ms no modo de produção. Você não pode configurá-lo, embora possa optar por uma atualização adiada (mais longa) se quiser com uma API instável especial.

Portanto, em vez do tempo, gostaríamos de controlar o flush com um segundo gatilho. Isso faz sentido? Isso poderia ser possível?

Sim, é possível. Descrevi um mecanismo como este aqui: https://github.com/oliviertassinari/react-swipeable-views/issues/453#issuecomment -417939459.

Não tenho certeza se você quer dizer no mestre ou não (o modo assíncrono não está oficialmente disponível nas versões npm)

Sim, estamos usando o pacote npm com <unstable_AsyncMode> , flushSync e unstable_deferredUpdates .

Por favor, comece a lançar versões alfa / beta com essas mudanças no npm! 🙏

Sim, é possível. Descrevi um mecanismo como este aqui: oliviertassinari / react-swipeable-views # 453 (comentário).

Brilhante. Muito melhor do que nossa implementação atual usando unstable_deferredUpdates :)

Mal posso esperar para começar a usar <div hidden> . Vocês estão fazendo um trabalho incrível.

@luisherranz Tenha cuidado, essas coisas _são_ instáveis. Pode ter bugs ou ser bastante ineficiente (por exemplo, uma otimização crucial - "retomar" - ainda não foi implementada). Estamos removendo unstable_deferredUpdates também em favor do novo módulo schedule ( schedule.unstable_scheduleWork ).

Sim, estamos usando apenas uma pequena parte do aplicativo e testando intensamente, mas até agora tudo bem :)

PODE SER OFFTOPIC:
requestIdleCallback é chamado apenas 20 vezes por segundo - Chrome na minha máquina Linux com núcleo 6x2, não é realmente útil para o trabalho de IU.
requestAnimationFrame é chamado com mais freqüência, mas é específico para a tarefa cujo nome sugere.

Paramos de usar requestIdleCallback por esse motivo.

O que vocês estão usando em vez de requestIdleCallback ?

Ah, claro. Tola eu. Eu queria saber qual API do navegador o módulo do planejador usa sob o capô em vez de requestIdleCallback . Eu deveria ter apresentado a pergunta de forma mais clara. 😅

Oi,

enquanto tentava entender o Suspense, reconheci que não tenho ideia de qual parte de um aplicativo está realmente "suspensa" ao usar o componente Suspend 😳😱.

No exemplo a seguir, eu esperaria que Title ficasse visível imediatamente, Spinner após 1000 ms e UserData após ~ 2000 ms (já que "carregar" os dados desse componente leva 2000 ms).
Mas o que vejo é que Title primeiro aparece junto com Spinner após 1000 ms.

// 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 />);

(Você pode encontrar o exemplo completo que usa React 16.6.0-alpha.8af6728 aqui no codesandbox )

Existe uma maneira de tornar Title imediatamente visível e "suspender" apenas a outra parte do aplicativo? Ou eu não entendi completamente o Suspense? (Se houver uma maneira melhor de fazer esse tipo de pergunta, por favor me avise)

Obrigado!

Olá @nilshartmann! Ótima pergunta!

Existe uma maneira de tornar o Título imediatamente visível e "suspender" apenas a outra parte do aplicativo?

Se bem entendi, você precisará dizer explicitamente ao React para _não esperar_ antes de liberar Title para o DOM como neste exemplo , a fim de tornar Title imediatamente visível e "suspender" apenas o outro parte do aplicativo envolvendo as partes que você espera que sejam imediatamente renderizadas em um <Suspense maxDuration={0}> .

Imagino que seja esse o caso por causa de alguma mecânica subjacente do escalonador de nível inferior. Eu também adoraria entender isso melhor, mas isso deve resolver seu problema por enquanto.

Estou animado para ouvir o que realmente está acontecendo lá.

(Se houver uma maneira melhor de fazer esse tipo de pergunta, por favor me avise)

Não tenho certeza se existe. 😄 Parece-me bastante claro. Obrigado por perguntar!

@TejasQ No meu navegador, carregar seu exemplo renderiza o spinner de fallback imediatamente. Não deveria carregar após 1000 ms?

@TejasQ obrigado pela sua resposta, mas @karlhorky está certo: agora o spinner aparece imediatamente.

Caramba! Eu senti falta disso. Eu tentei. “Deixe-me dar uma olhada nisso e voltar para você. Eu devo ter perdido algo. 🤷‍♂️

~ Atualização: estou tentando descobrir isso aqui e podemos colaborar se alguém estiver interessado em fazer isso juntos em tempo real. ~

Segunda atualização: @philipp-spiess e eu olhamos para ele e estou genuinamente perplexo. Eu ainda não entendo. Neste ponto, não tenho certeza se é um bug, pois este é, na verdade, um recurso unstable_ e alfa, ou se é algo que simplesmente não estou vendo.

Em ambos os casos, sinto que a equipe principal terá respostas úteis ou poderá usar sua pergunta para tornar o React ainda melhor / mais acessível.

Vamos ver o que eles têm a dizer. 😄 Obrigado por apontar isso, @nilshartmann!

Ele foi lançado como parte do React v16.6? A postagem do blog mostra um exemplo de código usando Suspense:

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

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

Ele foi lançado como parte do React v16.6?

Apenas no caso de uso de carregamento lento e apenas no modo de sincronização. O modo simultâneo ainda é WIP.

@nilshartmann

No exemplo a seguir, eu esperaria que Title ficasse visível imediatamente, Spinner após 1000 ms e UserData após ~ 2000 ms (já que "carregar" os dados desse componente leva 2.000 ms).

Acho que você está um pouco confuso sobre o que maxDuration faz. É um novo modelo mental, mas ainda não tivemos tempo de documentar isso. Portanto, continuará sendo confuso por um tempo até que o modo simultâneo esteja em uma versão estável.

Parabéns por anunciar a proposta dos ganchos. Eu gostaria de compartilhar algo com a equipe. Há algum tempo, lancei um componente chamado React Async , que tem recursos semelhantes ao Suspense. Essencialmente, ele lida com a resolução de Promise e fornece metadados como isLoading, startedAt e métodos como reload e cancel, tudo com uma API declarativa (e um gancho useAsync está a caminho).

Agora, minha principal preocupação é como isso se integrará ao Suspense. Na maior parte, provavelmente posso usar as APIs do Suspense do React Async e fornecer aos usuários a API React Async familiar e simples, ao mesmo tempo que ofereço os recursos de agendamento do Suspense gratuitamente. Pelo que vi, realmente acho que a API React Async é mais sensível e acessível em comparação com as APIs Suspense mais abstratas. Essencialmente, o React Async tenta oferecer uma API mais concreta que funciona para um subconjunto ligeiramente menor de casos de uso.

Fiquei surpreso ao saber da biblioteca React Cache. Para React Async, deliberadamente não incluí um mecanismo de cache, mas optei por lidar com promessas simples. Adicionar cache em cima disso é bastante fácil.

Por fim, estou preocupado em acessar os recursos do Suspense a partir de ganchos personalizados. O suspense parece depender fortemente de vários componentes embutidos, o que torna impossível (eu acho?) Usá-los a partir de um gancho. Haverá ganchos de suspense? Ou existe alguma outra maneira de integrar os dois?

Olá. Como posso testar o código com Suspense / Lazy?
agora renderer.create (...) toTree () joga
"toTree () ainda não sabe como lidar com nós com tag = 13"

Por que os adereços maxDuration em Suspense são usados ​​apenas no Concurrent Mode vez de nos modos de sincronização e simultâneo. Alguém pode ajudar a explicar?

(No momento) significa por quanto tempo Concurrent Mode tem permissão para deixar esta árvore pendente antes de forçá-la a confirmar - controla efetivamente o prazo de divisão de tempo, e a divisão de tempo não existe no modo Sync. Esperar antes de submeter a árvore necessariamente faria com que o commit ... não fosse sincronizado.

Tenho usado o Suspense em um aplicativo interno para obtenção de dados e rapidamente descobri o motivo pelo qual ele ainda não deve ser usado para obtenção de dados.

Eventualmente, porém, ele deve ser usado para buscar dados. Considerando que parece improvável que a API mude significativamente, exceto talvez pelo provedor de cache, como o Suspense deve funcionar se você precisar modificar os dados depois de buscá-los?

Por exemplo, aqui está um gancho realmente terrível do meu aplicativo.

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)
}

Este gancho:

  1. Coleta dados usando o retorno de chamada fornecido do endpoint fornecido
  2. Transforma esses dados em um mapa ImmutableJS - Como isso é potencialmente caro, eu memorizo ​​a operação.
  3. Retorna o mapa envolvido em useCacheValue , que é a parte particularmente estranha.

useCacheValue tem esta aparência:

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

  return [state, setState]
}

com a ideia de que é um gancho que responderá à mudança de value (o que indica que os dados foram buscados novamente), mas permite que o usuário modifique a representação de aplicativos de reação desse estado. De certa forma, ele atua como um cache muito ruim (daí o nome).

Estou lutando para ver como esse padrão funciona bem com o Redux em seu estado atual. Houve alguma descoberta sobre como isso pode parecer quando escrito por um programador que não sou eu e quando o suspense está "pronto" para a busca de dados? Do jeito que está, isso é muito mais trabalhoso do que usar o Redux sozinho com a busca obrigatória de flags.

Isso provavelmente fica muito mais simples uma vez que o Redux tem seus próprios ganchos, já que a principal dificuldade em fazer os dois jogarem juntos é que o Redux usa um HOC com um contexto que não deve ser exposto, mas eu ainda gostaria de ver o que o oficial a resposta é :)

Suspense deve funcionar com um cache externo ( não um Gancho orientado por estado). Forneceremos uma implementação de referência desse cache que funciona para casos de uso simples. O Relay implementará seu próprio mecanismo de cache. Quaisquer outras ferramentas (como o Apollo) também serão capazes de implementar seu próprio cache compatível, possivelmente se inspirando nessas duas implementações.

Mutação / invalidação não é a única questão que precisa de respostas. Também precisamos pensar sobre: quando mostrar spinners, padrões comuns como "indicador embutido", que pode estar fora da árvore suspensa, coordenando os estados de carregamento (para coisas que precisam ser desbloqueadas em uma ordem de cima para baixo ou entrar como estão pronto), renderização de streaming de listas, como isso afeta a hidratação parcial e assim por diante. Estamos trabalhando nessas coisas, mas não há nenhuma “recomendação oficial” para nenhuma delas ainda. Quando houver, você saberá pelo blog em que anunciamos as atualizações.

Como uma observação lateral, o Suspense para obtenção de dados é um modelo mental suficientemente diferente do que as pessoas estão acostumadas. Não acho que seja justo esperar que seja necessariamente tão poderoso quando integrado com mecanismos muito irrestritos como o Redux. Mas veremos. É difícil dizer qualquer coisa agora.

@gaearon Quando você diz "estamos trabalhando nessas coisas", há um problema que eu possa subscrever ou essas discussões estão acontecendo em particular?

Obrigado, @gaearon :)

@ntucker Como sempre, você pode assistir à atividade em andamento como PRs. Por exemplo: 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 e assim por diante. Tentamos colocar algumas informações descritivas em cada PR, e você pode ver as mudanças de comportamento nos testes. A barra de documentação para experimentos é baixa por vários motivos.

Publicaremos explicações mais completas sobre o modelo escolhido quando estivermos mais confiantes de que ele realmente funciona. Não acho que será produtivo para nós ou para a comunidade se descrevermos meticulosamente cada experiência em detalhes à medida que acontece. A maioria de nossos primeiros experimentos falha, e documentar e explicar cada um deles tornaria nosso trabalho lento.

É ainda pior que isso geralmente resulta em pessoas construindo um modelo mental em torno de algo que mais tarde percebemos que não funciona da maneira originalmente projetada. (Como está acontecendo com maxDuration que acabamos de remover.) Portanto, preferimos adiar o compartilhamento de ideias incompletas até que seja um bom uso de seu tempo e do nosso. Isso também é consistente com a forma como desenvolvemos o React no passado. Quando algo está realmente pronto (mesmo para uma redação teórica do modelo mental), concentraremos toda a nossa atenção em documentá-lo e explicá-lo.

Como uma observação lateral, o Suspense para obtenção de dados é um modelo mental suficientemente diferente do que as pessoas estão acostumadas. Não acho que seja justo esperar que seja necessariamente tão poderoso quando integrado com mecanismos muito irrestritos como o Redux. Mas veremos. É difícil dizer qualquer coisa agora.

@gaearon , felizmente, o modelo mental do Suspense combina com o meu perfeitamente. Estou muito animado para que essa peça do quebra-cabeça se encaixe no lugar. Obrigado por todo o seu trabalho árduo!

O roteiro anunciado em novembro passado (https://reactjs.org/blog/2018/11/27/react-16-roadmap.html) indicava que a versão "simultânea" do Suspense estava prevista para o segundo trimestre de 2019. Agora estamos bem em Terceiro trimestre de 2019. Existe uma atualização que podemos obter em termos de definitivamente não terceiro trimestre, ou talvez terceiro trimestre, etc.?

Esta foi a última atualização do roteiro que consegui encontrar: https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#an -update-to-the-roadmap

Fornecemos uma versão experimental em outubro: https://reactjs.org/docs/concurrent-mode-intro.html. Este é o mesmo build que estamos executando em produção. Ainda há mais trabalho a fazer (tanto em termos de ajustes da API quanto de construção de APIs de nível superior), mas você pode começar a brincar com isso, se quiser.

Suspense está me matando

@gaearon Eu entendo que você o usa na produção. Mas estou muito relutante em usar código "experimental" na produção. Vocês não estão sendo claros sobre o roteiro, status, progresso, cronogramas, etc. Isso é alfa, beta, qualidade RC? Este termo "experimental" diz "não toque nisso" para mim.

Todos nós estamos baseando nossos negócios neste código e tenho certeza de que estamos tão sobrecarregados quanto vocês. Um pouco de clareza, um blog, ALGUMA COISA ajudaria muito. Quase parece "Está em produção no Facebook, então terminamos".

@mschipperheyn

Este é um projeto de vários anos. A resposta honesta é que gerou muito mais trabalho do que pensávamos quando começamos, há dois anos.

Mas a boa notícia é que, como agora o usamos intensamente na produção, as peças que faltam estão claras e vemos o fim do túnel. Não é teórico - há um conjunto finito de coisas que precisamos terminar antes que possamos dizer confortavelmente que está pronto para ampla adoção.

Aqui está um estado aproximado de diferentes fluxos de trabalho hoje:

  • <Suspense> API para divisão de código com lazy . ( enviado no React 16.6)

    • Como você deve saber, você já pode usar este.

  • APIs de modo simultâneo, por exemplo, createRoot e useTransition . ( disponível em lançamentos de experimental )

    • Solução de compatibilidade para bibliotecas do tipo Flux. ( em andamento @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • Mudar o modelo de prioridade para um mais sensato. ( em andamento @acdlite , https://github.com/facebook/react/pull/18612)

    • Permita que apenas a última transição pendente termine. ( em andamento @acdlite)

    • API fora da tela (

    • Efeitos de fogo ao ocultar / mostrar conteúdo para Suspense

    • Efeitos de fogo ao ocultar / mostrar conteúdo fora da tela

    • Mostrar e ocultar os filhos do Portal quando necessário

    • Alinhe-se com o trabalho de padronização em andamento para Agendamento ( não iniciado )

    • Corrija os principais bugs conhecidos ( em andamento @gaearon e @acdlite)

    • Altere a semântica do evento. ( em andamento @sebmarkbage @trueadm)

    • Delegar às raízes em vez de documentar para permitir uma adoção mais gradual ( em andamento , @trueadm)

    • Libere eventos discretos na fase de captura.

    • Considere obter a prioridade padrão de event para jogar melhor com o código imperativo.

    • Finalize outras semânticas e padrões da API. ( não começou )

    • Atualizar tipificações e documentação.

  • Suspense para obtenção de dados

    • O suporte de baixo nível para sinalizar que um componente não está pronto para renderizar (tecnicamente disponível no React estável também, mas esta API não é considerada estável).

    • O renderizador do servidor libera imediatamente os substitutos do Suspense ( disponíveis em versões experimentais)

    • Uma solução para casos de uso GraphQL (Relay Hooks, enviado ).

    • Uma solução para casos de uso não GraphQL ( em andamento @sebmarkbage em colaboração com Next.js).

    • Uma integração de bundler para dependências baseadas em dados. ( em andamento )

    • Finalize API de blocos, incluindo contexto.

    • Uma solução de cache genérica. ( não começou )

    • Algum tipo de integração de roteador.

Quase parece "Está em produção no Facebook, então terminamos".

Posso ver como poderia ser assim, embora tbh essa leitura seja um pouco desmoralizante. :-) Temos trabalhado sem parar nisso durante todos os últimos meses, e muitos dos aspectos técnicos já foram concluídos ou estão perto de serem concluídos. A maioria das obras restantes se enquadra em duas categorias:

  • Corrigindo as falhas que descobrimos nos projetos iniciais antes de consolidá-los em uma versão estável. Se quiséssemos lançar o que temos agora, teríamos que seguir em frente com mudanças significativas e inovadoras em alguns meses. Isso só seria confuso.

  • Compatibilidade do ecossistema e bons padrões. Não ajuda se lançarmos algo que ninguém pode usar hoje porque não funciona com suas bibliotecas ou abordagens existentes. Portanto, a maior parte do trabalho (por exemplo, compatibilidade com bibliotecas semelhantes ao Flux por meio de useMutableSource , escolher melhor semântica de eventos, enviar uma estratégia de cache recomendada) é garantir que você realmente seja capaz de usar o que lançamos. Esta é uma longa cauda.

Em termos de "você pode usar hoje" ... Tecnicamente, você pode usar tudo isso hoje. Nós fazemos. Especificamente, usamos Relay Hooks e Concurrent Mode. Ainda temos mudanças planejadas significativas e problemas conhecidos, então o estado atual não está atingindo o nível que consideramos pronto para ampla adoção. Claro, se você não se importa em ter bugs ou APIs mudando em suas mãos, você pode usar os lançamentos de @experimental assim como nós.

Eu não diria que o Facebook está em uma posição especial aqui em termos de "terminarmos". Muito pelo contrário, não terminamos - mas internamente, estamos dispostos a tolerar a rotatividade e construir em cima de um trem em movimento, porque é assim que sabemos que o que estamos construindo é sólido. Sem esse dogfooding pesado, as falhas que descobrimos em seis meses levariam vários anos para serem descobertas e redesenhadas.

Para resumir: há mais trabalho a fazer.

@gaearon Obrigado por esta atualização! E peço desculpas se meu tom estava errado. Admito que fiquei um pouco frustrado vasculhando o Twitter por meses e não encontrando nada. Este aspecto Server renderer immediately flushes Suspense fallbacks (available in experimental releases) parece algo em que eu poderia alocar tempo testando isso com o Apollo Graphql para nossa implementação.

Sim, deve estar pronto para autores de biblioteca e curiosos começarem a brincar. As peças que faltam são principalmente sobre como fornecer "caminhos felizes", mas a maior parte do encanamento deve estar lá.

O renderizador do servidor libera imediatamente os substitutos do Suspense (disponíveis em versões experimentais)

Onde posso ler sobre isso? Eu esperava uma referência da API do modo simultâneo (Experimental), mas não tive sorte.

Se alguém tiver uma demonstração juntando Next.js, Relay Hooks e Concurrent Mode (com SSR), isso seria incrível. Caso contrário, posso tentar a sorte se encontrar documentação suficiente.

@CrocoDillon

Não há documentos extras sobre SSR, mas principalmente porque é apenas um novo comportamento padrão.

Se você tiver uma versão experimental do que a qualquer momento em que um componente é suspenso no servidor, liberamos o substituto do Suspense mais próximo. Então, no cliente, você usaria createRoot(node, { hydrate: true }).render(<App />) .

Observe que isso já ativa todos os novos recursos de hidratação. Portanto, por exemplo, seus limites de suspensão serão “anexados” ao HTML de fallback gerado pelo servidor e, em seguida, tentarão a renderização do cliente.

Observe também que você pode começar a se hidratar antes de carregar todo o aplicativo. Quando <App> estiver carregado, você pode hidratar. Contanto que os componentes abaixo sejam suspensos quando seu código não estiver pronto (semelhante ao lazy). O que o React faria neste caso é manter o conteúdo HTML do servidor, mas “anexar” o limite do Suspense a ele. Quando os componentes filhos carregarem, ele continuará hidratando. As partes hidratadas se tornariam eventos interativos e repetidos.

Você provavelmente pode pedir a @devknoll as próximas tentativas / exemplos de integração. Ele provavelmente tem algum.

Você pode habilitar o modo simultâneo em Next.js instalando react@experimental e react-dom@experimental e adicionando o seguinte a next.config.js

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

Aqui está a discussão Next.js sobre isso: https://github.com/zeit/next.js/discussions/10645

É possível esperar por alguma suspensão na renderização do servidor (para casos como geração de site estático, por exemplo)? Eu concordo que usar callbacks é um bom padrão, apenas me perguntando se ele pode ser substituído?

Observe também que você pode começar a se hidratar antes de carregar todo o aplicativo. Quandocarregou, você pode hidratar. Contanto que os componentes abaixo sejam suspensos quando seu código não estiver pronto (semelhante ao lazy). O que o React faria neste caso é manter o conteúdo HTML do servidor, mas “anexar” o limite do Suspense a ele. Quando os componentes filhos carregarem, ele continuará hidratando. As partes hidratadas se tornariam eventos interativos e repetidos.

@gaearon , você quer dizer que pode renderizar um componente normalmente no servidor, mas usar React.lazy no cliente? Permitindo que você retorne a marcação completa do servidor, mas atrase a análise e a renderização do código do componente no cliente. A marcação renderizada do servidor atua como reserva de suspense aqui?

@robrichard Na verdade, não tentei com React.lazy especificamente (usamos um wrapper diferente no FB e o Next também tem sua própria versão), mas espero que funcione assim. Vale a pena verificar :-) Com certas limitações - por exemplo, se você atualizar seus adereços e não houver memo de salvamento acima, ou se você atualizar o contexto acima dele, teremos que removê-lo e mostrar o substituto porque não sabemos o que fazer com isso.

@gaearon qual é o estado atual de hidratação parcial? Eu sei que o # 14717 foi mesclado, mas duvido que tenha sido feito em alguma versão?

Ele está ativo em cada @experimental lançamento há muito tempo, desde que você use a API unstable_createRoot .

@gaearon, você pode explicar melhor o que entende por "dependências dirigidas por dados"?

@gaearon, você pode explicar melhor o que entende por "dependências dirigidas por dados"?

Sim claro. Devo me desculpar pela brevidade da lista acima - é muito condensada e muitos deles são subprojetos separados significativos (é por isso que estão demorando).

Deixe-me dar um passo atrás e dar um contexto mais amplo antes de responder à sua pergunta específica. O contexto mais amplo é que construir uma solução de busca de dados realmente boa é muito, muito difícil. Não apenas no sentido da implementação, mas no sentido do design. Normalmente, seria necessário fazer um compromisso entre colocation (mantendo os requisitos de dados perto de onde os dados são usados) e eficiência (quão cedo começamos a carregar os dados e podemos evitar cascatas de rede). Isso não é tão perceptível em pequena escala, mas conforme o número de componentes aumenta, você realmente precisa escolher entre um ótimo desempenho e um código fácil de escrever. Em muitos casos, infelizmente, você não consegue nenhum dos dois - é por isso que a busca de dados em geral é um tópico tão quente.

Temos uma barreira muito alta para o que entra no React "oficial". Para ser "Reacty", ele deve compor tão bem quanto os componentes normais do React. Isso significa que não podemos recomendar de boa fé uma solução que não acreditamos que possa ser dimensionada para milhares de componentes. Também não podemos recomendar uma solução que força você a escrever código de uma maneira otimizada e complicada para mantê-lo com bom desempenho. No FB, aprendemos muitas lições com a equipe de revezamento. Sabemos que nem todos podem usar GraphQL, ou gostariam de usar Relay (não é por si só muito popular e a equipe não o otimizou para adoção externa). Mas queremos ter certeza de que nossa solução de busca de dados para React geral incorpora as lições adquiridas com dificuldade do Relay e não sofre por ter que escolher entre desempenho e colocation.

Quero enfatizar que não se trata apenas de grandes aplicativos. Os problemas são mais perceptíveis em aplicativos grandes, mas aplicativos pequenos que importam vários componentes do npm também sofrem com um subconjunto dessas ineficiências. Como enviar muito código do lado do cliente e carregá-lo em uma cascata. Ou carregando muito adiantado. Além disso, pequenos aplicativos não permanecem pequenos para sempre. Queremos uma solução que funcione muito bem para um aplicativo de qualquer tamanho, assim como o modelo de componente React funciona da mesma maneira, independentemente da complexidade do seu aplicativo.

Agora, para responder à sua pergunta específica. O Relay tem um recurso chamado "dependências orientadas a dados". Uma maneira de pensar sobre isso é uma evolução da dinâmica import . Dinâmico import nem sempre é eficiente. Se você quiser carregar algum código apenas quando uma condição for verdadeira (por exemplo, "o usuário está logado" ou "o usuário tem mensagens não lidas"), sua única opção é acioná-lo preguiçosamente. Mas isso significa que você está "iniciando" a busca (como com React.lazy ) apenas quando algo é usado. Na verdade, é tarde demais. Por exemplo, se você tiver vários níveis de componentes de divisão de código (ou componentes esperando por dados), o mais interno só começará a carregar depois que o nível acima for carregado. Isso é ineficiente e é uma "cascata" da rede. Relay "dependências baseadas em dados" permitem que você especifique os módulos que deseja buscar como parte da consulta. Ou seja, "se alguma condição for verdadeira, inclua este fragmento de código com a resposta de dados". Isso permite que você carregue todos os fragmentos de divisão de código de que vai precisar o mais cedo possível. Você não tem que trocar colocation para desempenho. Isso pode não parecer grande coisa, mas economizou segundos literais no código do produto.

Agora, novamente, não estamos colocando o Relay no React e não queremos forçar as pessoas a usar o GraphQL. Mas, conceitualmente, o recurso em si é genérico e ter uma boa solução de código aberto para ele permitiria que as pessoas fizessem muito mais divisão de código do que é feito hoje (e, portanto, enviará muito menos código JS de cliente!). Esse recurso genérico não será chamado "dependências orientadas por dados" - esse é apenas um nome de Relay a que me referi. Este recurso fará parte de uma solução recomendada maior que não requer GraphQL. Eu apenas me referi a ele por esse nome na lista porque isso era muito para explicar para um único ponto da lista de marcadores.

Espero que isso esclareça tudo.

Esta página foi útil?
0 / 5 - 0 avaliações