За последние пару лет я провёл сотни технических собеседований — от junior до senior специалистов. И я обнаружил что есть одна тема, с пониманием которой есть проблемы почти у всех кандидатов с кем мне доводилось общаться. Это Virtual DOM.

Почти каждый кандидат объясняет его примерно так:

“Virtual DOM нужен, чтобы обновлять не всю страницу, а только её часть. Поэтому всё работает быстрее.”

Формулировка вроде звучит логично. Но проблема в том, что это неверное понимание в принципе.

Браузер и без всякого Virtual DOM не перерисовывает «всю страницу» при каждом изменении. Он обновляет только затронутые участки. Да и в целом невозможно повлиять на flow работы браузерного движка взаимодействуя с DOM через Virtual DOM.

Значит, дело не в этом.

Чтобы понять Virtual DOM по-настоящему, нужно выйти из плоскости “как сделать быстрее” и перейти в плоскость “как управлять системой”.

Два мира внутри браузера

В браузере есть два разных мира:

  1. JavaScript-движок

  2. Rendering Engine (DOM, layout, paint и т.д.)

DOM — это не "обычный объект" в JavaScript. Это интерфейс к внутренней системе браузера.

Когда вы пишете:

element.textContent = 'Hello'

Вы:

  • пересекаете границу JS → браузер,

  • модифицируете DOM-дерево,

  • потенциально запускаете пересчёт стилей,

  • возможно инициируете relayout,

  • возможно запускаете repaint.

Да, современные браузеры хорошо оптимизированы и они не перерисовывают всю страницу целиком при любом мельчайшем изменении, но взаимодействие с DOM — это host-операции и они всегда дороже, нежели чем операции внутри JS. Дороже - значит медленнее.

Настоящая проблема: DOM как часть логики

Теперь представьте приложение без Virtual DOM.

У вас есть:

  • состояние пользователя

  • список задач

  • фильтры

  • загрузка

  • ошибки

  • асинхронные запросы

Всё это нужно синхронизировать с интерфейсом.

В качестве примера возьмем простенькую реализацию с манипуляциями состояния кнопки:

function updateButton() {
  if (isDisabled) {   
    button.classList.add('disabled')  
    button.setAttribute('disabled', '')  
  } else {  
    button.classList.remove('disabled') 
    button.removeAttribute('disabled')  
  } 
  
  if (isLoading) { 
    button.classList.add('loading')  
    spinner.style.display = 'block'  
  } else { 
    button.classList.remove('loading')
    spinner.style.display = 'none'  
  }  
  
  if (hasError) { 
    button.classList.add('error')  
  } else {  
    button.classList.remove('error') 
  }
}

Пока состояний мало — всё управляемо.

Но теперь представьте:

  • isLoading приходит из одного запроса,

  • isDisabled из другого,

  • hasError меняется асинхронно,

  • а isActive обновляется через WebSocket.

DOM становится:

  • местом, где хранится промежуточное состояние,

  • объектом, с которым нужно синхронизироваться вручную,

  • источником потенциальной рассинхронизации.

Вот где начинается настоящая проблема.

Когда DOM становится источником истины

Без абстракции получается двусторонняя связь:

State ↔ DOM

Вы:

  • меняете состояние,

  • обновляете DOM,

  • иногда читаете DOM,

  • принимаете решения на основе DOM.

Например:

if (button.classList.contains('active')) { 
  // что-то делаем
}

DOM начинает участвовать в логике. А он для этого не предназначен.


Virtual DOM как архитектурный сдвиг

Virtual DOM — это попытка перенести управление интерфейсом полностью в JavaScript. Вместо того чтобы работать с DOM напрямую, мы создаём его модель:

{  
  type: 'button',
  props: {   
    class: isActive ? 'active' : '', 
    disabled: isDisabled  
  }, 
  children: isLoading ? 'Loading...' : 'Submit'
}

Это просто объект.

Он:

  • не вызывает перерасчетов layout,

  • не запускает repaint,

  • не имеет побочных эффектов.

Это просто данные.

Новый поток управления

С Virtual DOM архитектура становится односторонней:

State → Virtual DOM → Real DOM

Реальный DOM перестаёт быть активным участником логики. Он становится проекцией состояния. И это фундаментальное изменение.

Почему это важно для масштабирования

В маленьком проекте можно жить без абстракции, в большом — нет.

Когда приложение растёт:

  • состояний становится больше,

  • асинхронности больше,

  • компонентов больше,

  • зависимостей больше.

Без единой модели вы получаете хаос синхронизации. В то время как Virtual DOM позволяет четко разграничить состояние от визуализации:

DOM — это UI, отображающий текущее состояние.

Иными словами Virtual DOM дает нам архитектурные гарантии.


Что происходит при изменении состояния

Когда состояние меняется:

  1. Пересобирается виртуальное дерево.

  2. Оно сравнивается с предыдущим.

  3. Вычисляется разница.

  4. В DOM применяются только необходимые изменения.

Вся сложность:

  • вычисляется в JS,

  • сравнивается в JS,

  • планируется в JS.

То есть в браузер отправляется минимальный набор мутаций. Таким образом мы уменьшаем количество переходов из JS → DOM и получаем полный контроль над дорогими операциями и это самый важный момент. Так как в конечном итоге мы все равно заплатим цену за финальные изменения в UI, но ключевое тут "за финальные изменения".

Virtual DOM - это компромисс

Да, содержание и поддержание в актуальном состоянии Virtual DOM добавляет накладных расходов на:

  • создание объектов,

  • хранение предыдущего дерева,

  • diff-алгоритм,

  • patch.

Это дополнительная CPU-нагрузка. Но эта нагрузка происходит внутри JavaScript — в контролируемой и предсказуемой среде. Мы платим вычислениями за архитектурную стабильность.

Главное, что нужно понять

Virtual DOM — это не про “обновлять только часть страницы”.

Это про:

  • перенос контроля в JavaScript,

  • устранение ручной синхронизации,

  • минимизацию дорогостоящих host-операций,

  • превращение DOM в конечное устройство вывода.

Virtual DOM не делает браузер быстрее. Он делает систему управляемой.


Итог

Если формулировать точно:

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

Если вам интересна тема, то в следующей статье можно разобрать то, как именно Virtual DOM реализован во Vue 3 и насколько он уже оптимизирован на уровне runtime.

Комментарии (33)


  1. DimitriyWhite
    27.02.2026 06:32

    Отличная статья! Добавил себе в избранное.


    1. wisead Автор
      27.02.2026 06:32

      Спасибо


  1. diakin
    27.02.2026 06:32

    А почему минусы поставили?


    1. wisead Автор
      27.02.2026 06:32

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


      1. diakin
        27.02.2026 06:32

        Это видимо, что-то персональное ) В комментариях тоже минусов наставили.


        1. wisead Автор
          27.02.2026 06:32

          Очень может быть)


    1. Femistoklov
      27.02.2026 06:32

      Я не ставил, но догадываюсь: это потому, что статья - гавно, извиняюсь за выражение. После её прочтения у фронтендеров понимание предмета станет хуже, а не лучше.

      DOM становится:

      • местом, где хранится промежуточное состояние,

      DOM не становится местом, где хранится промежуточное состояние, если isDisabled, isLoading и т.п. сделать свойствами, а не просто параметрами. Никто в здравом уме в UI (хоть на фронте, хоть где) уже давно не читает эти значения напрямую из контролов (кроме изменений, сделанных руками пользователя). Всякие утерянные древние знания типа MVC, MVVM, MVP - они в т.ч. про это. Никакой VDOM для этого не нужен.

      Без абстракции получается двусторонняя связь:

      State ↔ DOM

      Делать без двусторонней связи придумали ещё в 1978 году.

      Видимо, нужна ещё сотня собеседований.


      1. wisead Автор
        27.02.2026 06:32

        Видимо говно ваши знания по работе с реальным DOM без прослойки, изввиняюсь за выражение, cделай ты isDisabled хоть свойством хоть параметром тебе всеравно придется сопоставлять/синхронизировать состояние флага с реальным состоянием элемента DOM, особенно если учитывать что проект не маленький и состояние может меняться не из одного кокретного места. Думаю собеседование вы бы провалили)


        1. Femistoklov
          27.02.2026 06:32

          Ну-ка, ну-ка. "Show me the code."

          У вас вот так:

          if (button.classList.contains('active')) { // что-то делаем}

          Делаем свойство вместо параметра:

          state = { isDisabled: false }

          Ваше обращение к DOM превращается в:

          if (state.isDisabled) { // что-то делаем }

          Везде, естественно, пишем:

          onDisabledChanged(value) {

          button.classList.remove('active')

          state.isDisabled = value;

          }

          Вы бы у меня тоже собеседование, скорее всего, провалили : )


          1. wisead Автор
            27.02.2026 06:32

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


            1. Femistoklov
              27.02.2026 06:32

              Так это же ваш пример. Никаких 10 изменений за тик для состояния кнопки не прилетит. Там, где действительно бывает частое обновление, либо обновления по многим частям состояния разом, это решается очередью обновлений. Про глобальный стейт я ничего не говорил, он может быть какой угодно - хоть локальный, хоть глобальный, это к теме не относится. Проблема состояния гонки одинаково возникает, и если писать всё напрямую в DOM, и при использовании Virtual DOM, и без него тоже. Ну либо я не понял, про какую вы именно гонку.

              Я бы посоветовал статью скрыть в черновики, доскональнее разобраться в вопросе, включить у чатаГПТ опцию "думать", и переписать статью. Я с радостью помогу с финальной тех. проверкой и вычиткой, если хотите. Сейчас у вас буквально написано: "шурупы очень неудобно забивать молотком, но есть решение этой фундаментальной проблемы - шуруповёрт".


              1. wisead Автор
                27.02.2026 06:32

                ))) Да мы уже обсуждаем ваш пример кода)) Который ну просто плоский и не учитывает кучи факторов, раз уж решили знаниями своими блеснуть, то уж будьте добры не после моих комментариев по вашему коду, а сразу описывайте нюансы. Пример кода который я привел с кнопокой - это сильное упрощение, ну и даже тут ваши советы и примеры просто не выдерживают критики) Ненужно все сводить к состоянию одной кнопки, состояний чего угодно может быть тысячи. И за тик может прилететь еще как и 10 и 20 апдейтов)) Вы предлагаете реализовать очередь обновлений собственноручно?) Вы случайно не из тех кто не использует ничего стороннего потому что "Я сделаю лучше"?)) Окей очередь вы реализовали, затем встанет вопрос оптимизации патчинга DOM, то есть по факту вы начнете пилить свой VirtualDOM)) Или что - то отдаленно напоминающее, при этом судя по вашим комментариям, отстрелите себе обе ноги.

                Ваш ответ очень сильно тянет на ГПТшный, причем беслатной версии) И в вашей помощи уж точно нужды нет) Скорее наоборот.


                1. Femistoklov
                  27.02.2026 06:32

                  Видят боги, я пытался.


                  1. wisead Автор
                    27.02.2026 06:32

                    Вы лишь пытались повыделываться, но не вышло))

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

                    Ваши комментарии были просто не в тему. Выздоравливайте


                  1. feelamee
                    27.02.2026 06:32

                    а можете в двух словах написать зачем нужен Virtual DOM? Или дать ссылку на годный ресурс?

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

                    В итоге люди придумали скопировать состояние и пытаться его синхронизировать, что по моему опыту только добавляет багов.


                    1. Femistoklov
                      27.02.2026 06:32

                      Ну, разрабы Vue (который я использую) пишут:

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

                      Т.е. это абстракция, упрощающая работу с DOM как самих разрабов Vue, так и его пользователей.


            1. feelamee
              27.02.2026 06:32

              А можете привести пример когда условно булеан 10 раз меняется туда и обратно.
              Вы в статье писали что благодаря Virtual DOM в DOM пойдет только измененное состояние. Т.е. в случае булеана может ничего не пойти, если он вернулся в конце в изначальное состояние. Случай вроде валидный и показывает зачем нужен Virtual DOM.
              Но где на практике такое бывает? - что одни и те же данные меняются очень часто? Это явно не кнопка


  1. enderman08
    27.02.2026 06:32

    ChatGPT, разлогинься


    1. wisead Автор
      27.02.2026 06:32

      Так зачем ты залогинился?


      1. Petr_axeman
        27.02.2026 06:32

        Так это явно иишный текст, причем процентов на 60


        1. wisead Автор
          27.02.2026 06:32

          Даже процентовку вывел?) Почему не 70?


        1. pravosleva
          27.02.2026 06:32

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


          1. wisead Автор
            27.02.2026 06:32

            Можно, а зачем?)


            1. pravosleva
              27.02.2026 06:32

              Затем, что гордость - низменное чувство!)


              1. wisead Автор
                27.02.2026 06:32

                Ну смотря кто и чем гордится)


  1. MtTheDamos
    27.02.2026 06:32

    Статья действительно похожа на нейросетевую.

    Так мало того, она еще и устаревшая - уже давно существую фреймворки без VDom: Svelte, Solidjs, а также режимы сборки без VDom (помню только Vapor во Vue). Это относительно новые фреймворки, которые как раз опираются на быстрое изменение обычного DOM. И, как указано в статье, они не делают из DOM источник истины - они работают также, как и другие фреймворки. Вообще это странный тезис, больше походит на плохой стиль.


    1. wisead Автор
      27.02.2026 06:32

      Почему устаревшая? VDom по сей дееь существует и отказываться от него вроде и не собираются. А альтернатива была всегда, тот же Angular работает без Vdom, так что это не что -то новое, а инструменты без VDom существуют давно. Да во vue появился vapor mode, но он не пришел на замену VDom, это альтернатива для желающих. Но вот что то подсказывает мне что желающих будет немного.


      1. MtTheDamos
        27.02.2026 06:32

        Почему это не описано в статье?

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


        1. wisead Автор
          27.02.2026 06:32

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


          1. MtTheDamos
            27.02.2026 06:32

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

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

            А не затрагивать альтернативный подход - используя только обычный DOM - вы видимо не стали, потому что тогда статья развалится. Ведь получается, что всë, о чëм вы написали, можно переложить на библиотеку для манипуляций обычным DOM.

            Virtual DOM изначально создавался как раз для скорости, для обновления только части страницы, потому что обновления обычного DOM было дорогостоящими операциями. Теперь браузеры стали оптимизированней и обновления обычного DOM быстрые. И для DOM также можно сделать прокладку, которая выполняет и решает описанные в статье операции.

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

            https://krausest.github.io/js-framework-benchmark/2026/chrome145.html


            1. wisead Автор
              27.02.2026 06:32

              Меня реально нейронка троллит, причем не самая умная ее модель видимо)) Задеть за живое точно не получится даже бенчмарками))
              Это еще раз подтверждает что статью вы не прочитали либо прочитали вскользь бегло, там ведь черным по белому написано

              "Чтобы понять Virtual DOM по-настоящему, нужно выйти из плоскости “как сделать быстрее” и перейти в плоскость “как управлять системой”.

              Теперь к вашим тезисам:
              - "Virtual DOM изначально создавался как раз для скорости, для обновления только части страницы, потому что обновления обычного DOM было дорогостоящими операциями."

              Отвечаю:
              Vurtual DOM изначально создавался как архитектурная прослойка между состоянием приложения и реальным DOM и улучшение скорости это следствие, а не первопричина. Если бы вопрос стоял именно в миллисекундах, никто бы не вводил промежуточное представление дерева в памяти — потому что любая дополнительная абстракция имеет накладные расходы и об этом тоже указано в моей статье.

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

              Ссылаться на бенчмарк как на доказательство ненужности VDOM в корне неверно. Он показывает, что compile-time или fine-grained решения могут быть быстрее VDOM в синтетических сценариях. Но это не означает, что они работают "без промежуточной модели" или что DOM вдруг стал быстрее JS.

              Разница в том, где и как устроена прослойка, а не в том, есть она или нет. Выигрыш в бенчмарке связан с отсутствием универсального runtime-diff'а, а не с тем, что можно просто работать с DOM напрямую и всё будет быстрее.

              Статья разъясняет, что такое Virtual DOM как архитектурная модель, зачем он появился и какой принцип лежит в его основе. В ней не утверждается, что альтернатив не существует. В ней объясняется конкретная модель — её логика и её место в архитектуре.

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

              Я понимаю ваше состояние) Хочется поумничать в комментариях, как вам кажется "аргументированно", а по факту все ваши аргументы мимо)) Выздоравливайте






              1. MtTheDamos
                27.02.2026 06:32

                Мда, спорить бессмысленно.

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

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


                1. wisead Автор
                  27.02.2026 06:32

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

                  Матчасти следует учиться вам и выдать желаемое за действительное пытались как раз таки вы. Не вышло! Сели в лужу, от сюда и оскорбления пошли "Клоун" )) Клоун - это вы! Выздоравливайте