Решение задачи сброса тяжелой логики на одну из множества открытых вкладок

    Не так давно я начал разрабатывать библиотеку DuelJS, которая предоставила удобный интерфейс для определения состояния вкладки Master (активная) или Slave (неактивная). Однако позже мне начали поступать предложения для оптимизации соединений по веб-сокетам. Подход DuelJS: если вкладка активна -> держать соединение, если неактивна -> класть — является не продуктивным. На помощь приходит расширение TabNinja.




    Новая логика


    Понять старую логику легко взглянув на нижеприведенный скриншот:

    TabNinja предлагает новую логику поверх старой:

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

    TabNinja по сути есть одна простая функция:
    window.isSuperMaster(); // при использовании вместе с duel не путайте с window.isMaster()
    

    Вы также можете использовать TabNinja без DuelJS, в этом случае вам стоит использовать файл из репозитория с соответствующей пометкой (tabninja.without_duel.min.js)

    Обзор алгоритма работы


    Алгоритм TabNinja весьма прост и базируется на localStorage + sessionStorage.
    1. Если localStorage недоступен — все вкладки будут являться superMaster
    2. Текущая вкладка обращается к переменной контроля аварийности в sessionStorage
    3. В случае если переменной нет — устанавливается переменная и удаляется стек активных вкладок
    4. Текущая вкладка обращается к стеку активных вкладок через localStorage
    5. Если в стеке активных вкладок пусто — создать стек и поместить туда себя
    6. Если кто-либо уже присутствует в стеке активных вкладок, значит главный тот кто первый в стеке
    7. При закрытии вкладки: вытащить её из стека

    Полезные ссылки


    Демо DuelJS без TabNinja
    Демо DuelJS с TabNinja
    Демо TabNinja без DuelJS
    Репозиторий TabNinja на GitHub
    Репозиторий DuelJS на GitHub
    Краткий обзор DuelJS на сайте
    Документация DuelJS на readthedocs
    — Картинка топика взята с people.howstuffworks.com/ninja.htm

    Предлагайте свои идеи по улучшению библиотеки DuelJS сюда или в issues, спасибо.
    Чуть не забыл: внимательно смотрите список тестируемых браузеров в README.md

    P.S: Сейчас работаю над улучшением работы TabNinja в Internet Explorer 11 — иногда происходит неадекватное поведение, которое рушит работу tabNinja.
    Поделиться публикацией

    Похожие публикации

    Комментарии 20

      +1
      Только недавно обсуждали варианты реализации, Ваш хорош лаконичностью и альтернативными механизмами (передача данных через кукизы и использованием событий закрытия вкладок/окон), но есть и минусы: если вкладки виснут, или залипают на время (что не редкость) то мастеров станет несколько, поэтому без heartbeat для каждой вкладки не обойтись. Надеюсь, кто-то слепит все вместе, уже почти-почти.
      +4
      А почему не использовать WebWorkers? Почему не «сбросить тяжелую логику» в отдельный thread?
        0
        Это не поменяет смысла. Идея в том, что когда открыто 10 вкладок одного сайта — можно обрабатывать логику только в одном из потоков. Можно сделать этот поток на веб воркере, но это не принципиально и зависит только от того как реализован конкретный проект.
          +2
          Для этого есть SharedWebWorkers и тогда решения с localStorage уходят в прошлое — не нужно никаких костылей. Но поддержка их браузерами к сожалению пока не радует: caniuse.com/#feat=sharedworkers
            0
            Что такое «10 вкладок одного сайта»?

            Это 10 instances одного приложения или одно приложение открывает 10 страниц?
            Если второе то почему это не SPA?
              0
              Я открыл gmail, нажал Ctrl+T, в открывшейся новой вкладке руками вписал plus.google.com, потом переключился обратно на первую страницу и перелогинился. Plus в этот момент должен меня тоже перелогинить.

              Как вы это в SPA запихнете?

                +1
                «Plus в этот момент должен меня тоже перелогинить.» это еще зачем? В смысле спорный вопрос.
                Я например хотел бы видеть две tabs с моими gmail ящиками.

                А вообще это вопрос взаимодействия двух приложений. Решаемо банальным повешением observers на localStorage.
                Если они часть одной suite то должны отдаваться с одного URL.

                Ну да ладно, вопрос то был в другом: зачем для тяжелой логики отдельное окно?
                  0
                  Как это «вопрос был в другом»?

                  Для тяжелой логики gmail — одно окно, для тяжелой логики plus — второе. А пользователь один. Он один и в Гугле, и в Яндексе; иначе все запросы, которые должны пройти через passport офигеют. Или мы окажемся недалеко от отсылки пароля плейнтекстом.

                  Подгружать логику плюса (и всего остального) в почту — не вариант, вы же понимаете.
                    0
                    Я не очень понял, откуда в посте вдруг всплыла «тяжёлая логика», но изначально там было вполне разумное условие: есть соединение по вебсокету, есть туча вкладок сайта — вполне естественно не открывать по соединению на каждую вкладку, а держать только одно соединение, в какой-то одной вкладке, а с остальными общаться внутри браузера.
            0
            Слышал, будто браузеры понижают приоритет неактивных вкладок.
              0
              Подтверждаю, есть такое. Правда на cross-window общение это не сильно влияет, в основном на таймеры.
                0
                Но влияет на скорость работы супер-мастера. Может, имеет смысл супер-мастером делать активное окно, когда оно есть?
                  0
                  То что вы описали было у меня по умолчанию (в проекте dueljs). Я предложил философию (о которой ведется речь в статье) в качестве эксперимента. Я сам лично тоже придерживаюсь вашей точки зрения.
              +8
              Писать в тексте «ложить» ещё до ката — это очень, очень плохая идея :)
                –2
                Ну, коли это поправили, так добавьте запятую (а лучше — тире) после слова «класть», потому что иначе предложение воспринимается как:
                1. вкладка активна => держать
                2. вкладка неактивна => класть является не продуктивным
                0
                Что используется в качестве идентификатора вкладки?

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое