"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como os componentes são renderizados em um DOM virtual e como otimizar a nova renderização

Como os componentes são renderizados em um DOM virtual e como otimizar a nova renderização

Publicado em 2024-11-07
Navegar:873

How Components are Rendered in a Virtual DOM and How to Optimize Re-Rendering

Ao construir aplicativos web modernos, atualizar eficientemente a UI (interface do usuário) é essencial para manter os aplicativos rápidos e responsivos. Uma estratégia comum usada em muitos frameworks (como React) é usar um DOM virtual e componentes. Este artigo explicará como os componentes são renderizados usando um DOM virtual e como podemos otimizar a nova renderização para que o aplicativo da web não fique lento.

1. O que é um DOM Virtual?

O DOM (Document Object Model) é uma estrutura semelhante a uma árvore que representa todos os elementos de uma página da web. Cada vez que você interage com uma página da web – clicando em botões, digitando texto – o navegador precisa atualizar o DOM, o que pode ser lento.

Um DOM virtual é como uma cópia do DOM real, mas vive apenas na memória. Em vez de atualizar o DOM real diretamente sempre que algo muda, atualizamos primeiro o DOM virtual. Depois que as alterações são feitas, o DOM Virtual se compara à versão antiga, encontra as diferenças (isso é chamado de diffing) e atualiza apenas as partes do DOM real que precisam ser alteradas.

2. O que são componentes?

Em um aplicativo da web moderno, componentes são os blocos de construção da IU. Pense neles como partes pequenas e reutilizáveis ​​de uma página da web. Por exemplo:

  • Um botão pode ser um componente.
  • Um cabeçalho pode ser um componente.
  • Uma lista de itens pode ser um componente.

Cada componente descreve como deve ser a aparência de parte da IU. Uma função de componente retorna uma árvore Virtual DOM que representa essa UI.

3. Exemplo: Criando um Componente de Botão

Vamos criar um componente Button simples usando pseudocódigo. Este componente retornará um botão com texto e uma função que será executada quando o botão for clicado.

// Component to display a button
function Button(props) {
    // The Button component returns a Virtual DOM node for a 

Neste exemplo:

  • O componente Button recebe props (propriedades), como o texto do botão e um manipulador de eventos para quando ele é clicado.
  • Ele retorna um nó Virtual DOM que representa um elemento

4. Renderizando Vários Componentes

Digamos que queremos construir um aplicativo que tenha um cabeçalho e um botão. Cada uma dessas partes pode ser representada como componentes. A estrutura do aplicativo poderia ser assim:

// App component with a header and button
function App() {
    return new VirtualNode("div", {}, [
        new Header(), // The Header component
        new Button({ text: "Click Me", onClick: handleClick }) // The Button component
    ])
}

// Header component
function Header() {
    return new VirtualNode("h1", {}, ["Welcome to the App!"])
}

// Function to handle button clicks
function handleClick() {
    console.log("Button clicked!")
}
  • O componente App retorna uma Árvore DOM virtual contendo dois componentes: Cabeçalho e Botão.
  • O componente Header retorna um nó Virtual DOM representando um elemento

    .

  • O componente Button funciona conforme descrito anteriormente.

5. Como funciona a renderização inicial

Quando o aplicativo é executado pela primeira vez, ele:

  1. Chama os componentes: App(), Header() e Button() são executados.
  2. Cria o DOM Virtual: O resultado é uma árvore de nós do DOM Virtual que representa a UI.
  3. Atualiza o DOM real: O DOM Virtual é usado para construir os elementos HTML reais no DOM real.
// Initial render of the app
function renderApp() {
    let virtualDOM = App()          // Render the app's Virtual DOM
    let realDOM = createRealDOM(virtualDOM)  // Convert the Virtual DOM into real DOM elements
    attachToPage(realDOM)           // Attach the real DOM elements to the webpage
}

6. Rerenderização e por que precisamos de otimização

Digamos que algo no aplicativo mude, como o texto do botão. Normalmente, todo o aplicativo seria renderizado novamente, mas isso pode ser lento se o aplicativo for grande. Em vez disso, podemos otimizar a nova renderização atualizando apenas as partes que foram alteradas.

Aqui está o que acontece quando ocorre uma nova renderização:

  1. Diferença: Comparamos o antigo Virtual DOM com o novo e descobrimos o que mudou.
  2. Patching: Somente as partes do DOM real que precisam ser atualizadas são alteradas (esse processo é chamado de patching).

Exemplo: alterando o texto do botão

Digamos que o texto do botão mude de "Click Me" para "Clicked!". Veja como renderizaríamos novamente o botão:

// New Button component with updated text
function Button(props) {
    return new VirtualNode("button", { onClick: props.onClick }, [props.text])
}

// Re-rendering with the new text
let oldButton = Button({ text: "Click Me", onClick: handleClick })
let newButton = Button({ text: "Clicked!", onClick: handleClick })

// Diff the old and new Button
let diffResult = diff(oldButton, newButton)

// Patch the real DOM with the changes
patch(realButtonDOM, diffResult)

7. Otimizando a nova renderização: O componente deve ser atualizado

Uma das principais maneiras de otimizar a nova renderização é verificar se um componente realmente precisa ser atualizado. Se nada mudou nos props ou state, podemos pular a nova renderização desse componente. É aqui que entra a lógica shouldComponentUpdate.

// Function to check if a component should update
function shouldComponentUpdate(oldProps, newProps) {
    return oldProps !== newProps // Only update if the props have changed
}

Agora, antes de renderizar novamente, verificamos se o componente deve ser atualizado:

// Example: Optimized re-rendering of Button component
function renderButtonIfNeeded(oldButton, newButton) {
    if (shouldComponentUpdate(oldButton.props, newButton.props)) {
        let realButton = createRealDOM(newButton)
        patch(realButton)
    }
}

8. Usando chaves para otimização de lista

Ao renderizar listas de itens (por exemplo, uma lista de botões), podemos otimizar usando chaves para identificar cada item de maneira exclusiva. Isso ajuda o algoritmo de comparação a combinar itens novos e antigos na lista e aplicar apenas as alterações necessárias.

// List of buttons with unique keys
function ButtonList(items) {
    return new VirtualNode("div", {}, items.map(item => 
        new Button({ key: item.id, text: item.text, onClick: handleClick })
    ))
}

Com chaves, se um dos itens da lista for alterado (como adicionar ou remover um botão), o algoritmo pode identificar rapidamente qual botão foi alterado e atualizar apenas aquele.

9. Otimizando Mudanças de Estado

Os componentes também podem ter seu próprio estado. Quando o estado de um componente muda, queremos renderizar novamente apenas aquele componente específico, não o aplicativo inteiro. Aqui está um exemplo de botão com estado:

// Button component with state
function ButtonWithState() {
    let [clicked, setClicked] = useState(false) // Create state for button

    function handleClick() {
        setClicked(true) // Update state when clicked
    }

    return new VirtualNode("button", { onClick: handleClick }, [clicked ? "Clicked!" : "Click Me"])
}

Nesse caso:

  • O texto do botão muda quando ele é clicado.
  • Apenas o componente ButtonWithState é renderizado novamente, e o DOM real apenas atualiza o texto do botão.

10. Evite re-renderizar componentes pais

Outra otimização é evitar a nova renderização dos componentes pais quando apenas um componente filho é alterado. Por exemplo, se o botão mudar, mas o cabeçalho permanecer o mesmo, podemos pular a nova renderização do cabeçalho.

// Optimized App component
function App() {
    if (!shouldComponentUpdate(oldHeaderProps, newHeaderProps)) {
        return oldHeader // Reuse the old Header if it hasn't changed
    }

    return new VirtualNode("div", {}, [
        new Header(), // Re-render the Header only if necessary
        new ButtonWithState() // Button re-renders based on state
    ])
}

11. Conclusão: atualizações eficientes da interface do usuário com um DOM virtual

Para resumir, podemos dividir o processo de renderização e otimização de componentes usando o Virtual DOM nestas etapas:

  1. Renderização inicial: Na primeira vez que o aplicativo é renderizado, construímos a árvore do DOM virtual e a convertemos no DOM real.
  2. Rerenderização: quando algo muda (como o texto ou o estado do botão), atualizamos o DOM virtual e aplicamos apenas as alterações necessárias ao DOM real.
  3. Otimizando novas renderizações: Ao usar estratégias como shouldComponentUpdate, chaves para listas e atualizações baseadas em estado, podemos evitar novas renderizações desnecessárias, mantendo o aplicativo rápido e responsivo.

Pensando cuidadosamente sobre quando e o que renderizar novamente, podemos garantir que os aplicativos da Web permaneçam eficientes mesmo à medida que aumentam em complexidade. O Virtual DOM é uma ferramenta poderosa que ajuda a alcançar esse equilíbrio entre simplicidade e desempenho!

Declaração de lançamento Este artigo está reproduzido em: https://dev.to/biswasprasana001/how-components-are-rendered-in-a-virtual-dom-and-how-to-optimize-re-rendering-5f61?1Se houver algum violação, entre em contato com [email protected] para excluir
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3