Есть ли подобное: async module loaders с кэшированием в localstorage и «склейкой» запросов?
В качестве примера кода на гитхабе, ищу интересную идею чего небольшое запилить и вот пока надумал очередной загрузчик модулей с выпендрежем.
Собственно гугл пока ничего не подсказывает, есть ли аналоги, поэтому нужно больше ИТшных голов=).
Так что, кто может чего видел аналогичное.
Суть:
реализовать стандартное решение асинхронной загрузки модулей и зависимостей (js,css,*) с кэшированием их исходников в localstorage, а это дает возможность кэшировать и запрашивать за один запрос несколько модулей с сервера, и соответственно сервер бы отдавал контент нескольких модулей, и их склейки б кэшировал у себя, а клиент парсил ответ.
Т.е если фронтенду внезапно понадобились модули A, B, C. Проверили в кеше модуль А есть, профит, B и С - нету, делаем один запрос к серверу и указываем что ответе ожидаем - склейку B, С - сервер проверяет есть ли такое сочетание у него в кеше, нет - склеивает контент модулей, положил в свой кэш - отдает клиенту - клиент разбивает контент по модулям - отдельно каждый кэширует в localstorage- профит. Так как фронтенд грузил бы модуля в некотором сочетании, то на сервере бы самоорганизовался устойчивый кеш, скорее всего с избыточностью, но лишние пару десятков мегабайт никого не волнуют, приоритет - скорость.
Что в теории б это дало- быстрая асинхронная загрузка зависимостей, за минимальное количество запросов, т.е за один, нет необходимости делать статические компоновки модулей. Для случаев, когда приложения иногда подтягивает новые модули, должно сойти=)
Я делал нечто похожее для ангуляра, но не смешивал типы в один запрос (один запрос на js, один на css, один на html) и не кешировал данные в localStorage, оставив это на совести browser cache (сценарии у пользователей как правило одни и теже, поэтому browser cache вполне себе будет оправдан)
Из вашего описания видно, что есть две несвязанные задачи (они могут работать каждая по отдельности)
1) Кэширование модулей на клиенте. Вы хотите изобрести browser cache? Он уже изобретен и работает...
2) Динамическая загрузка модулей. Похоже на require.ensure из webpack, работает именно так как вы описали. "Самоорганизовался устойчивый кеш" это и есть сборка модулей.
Внутри ensure можно сделать несколько обычных require и они будут собраны в один файл (chunk). Конечно полностью произвольно в рантайме вы не можете подгружать, все зависимости должны быть известны во время сборки. Но в отличии от обсуждаемого здесь гепотетического решения это крайне упрощает серверную сторону, не нужен специальный сервер для сборки модулей, они отдаются статикой.
1) Кеширование в localstorage это не отдельная "фишка", пункт 2 нереализовать без пункта 1.
Наитивные механизмы кэширования, в случае использования одного запроса для получения нескольких модулей, не получится использовать, а не для того чтобы просто переизобрести кеширования браузера. Ну вот, как бы мы делали такой запрос? где указывали бы какие модуля запрашиваются? В теле запроса POST? отлично, но url тогда будет не уникальным и при запросе разных наборов модулей он будет тот же (например /modules/), а значит кеширование не будет работать, так как кеш по уникальному url. Как то хитро склеивать имена модулей в url запроса типа /modules/module1.js__module2.js__module3.css - сработает, но только на точную комбинацию их. Выходит если потом я запрошу в другой комбинации, или и вовсе только один из них - кеш не сработает. Отсюда проблема, что просто так одним запросом несколько модулей не получить, так чтоб при этом они кешировались механизмами браузера. А именно множество запросов при использовании динамических загрузчиков неприятная проблема. И меня бы requireJS устроил если бы не она.
2) Webpack нужно мне исследовать, но на сколько я знаю с чтения хабра, там все ровно ручками делают слепки, ну в смысле на бекенде нужно webpack объяснять что да как, чтобы он сделал выдачу с нескольких. На сервере node я предполагаю просто ввести прослойку например для express, который бы просто обрабатывал обращения к public/js|css куда как обычно gulp скомпилил исходники и отдавал слепки, без всяких конфигов, делал кеш, либо в озу, либо в файловой системе, если предполагается, что там отдельные быстрый сервер отдачи для статики. Больше ему ничего не нужно. Как то так... В принципе для github code sample идея прям не нужна уникальная, но все же...
ну не знаю причем здесь REST API то?=) SPA тоже как бы не касался как такового. Только организации динамического загрузчика с минимизацией запросов, а не один запрос -один модуль.
Digital Brain: минимизируем весь код SPA(+gzip сжатие) и грузим, больше - никогда не запрашиваем ресурсы с сервера: все запросы далее - только через RESTfull идут. А картинки и остальное - кэширует браузер и/или используем localstorage.
Т.е. нет спроса на подобный динамический загрузчик при правильном подходе. Может просто я не пойму сферу его применения?
xmoonlight: RESTfull это уже взаимодействие клиента и сервера по обмену данными, я ее никак тут не касаюсь, только о подгрузке ресурсов для этого SPA.
А насчет сборки? тот подход, что Вы описали, это статическая сборка. Он подходит для совсем небольших приложений, и/или тех которым весь набор модулей нужен сразу. Т.е все собрали в один файл, минификация, сжатие подключили как один файл на клиенте и профит. Это просто, надежно, но при первом старте приложение будет долго думать, особенно на мобильных девайсах. В больших приложениях, где есть множество функционала, на каждый "фунционал" подгружает набор необходимых модулей по требованию, т.е динамически. И тут начинаются сложности- запрашивается либо каждый модуль и зависимость его отельным запросом, т.е десятки запросов, либо нужен опять сборщик который эти файлы проанализирует и опять все в один файл запихнет. Т.е будет несколько сборных файлов для каждой функционала SPA. Все это хорошо, но многовато телодвижений и не такая гибкость.
Digital Brain: а-а... понятно. ну хотя бы пример такого "большого" приложения приведите.... а то я не пойму всю глубину проблемы....
еще: если я что-то загрузил, то я должен по ненадобности это и выгрузить же... (чтобы освободить память) вот тут - вообще непонятно как быть!
xmoonlight: да что далеко ходить, замечали сколько грузится тот же gmail? SPA вытесняет классические сайты, а попробуйте реализовать даже небольшой классический портал на SPA? Я вот не знаю как это практически реализовать с текущими инструментами, если своего ничего не пилить. А приложения с каждым годом жиреют. Обостряют проблемы мобильный сегмент. Делать облегченные версии - опять лишнее телодвижения. Ну не может даже большому приложению в один момент времени требоваться все модуля.
C выгрузкой я давно уже экспериментировал, и это работало, но тогда вообще это никому не надо было, так как приложения совсем были скромные. Простой счетчик "ссылок" для каждого модуля, когда он становится пустым, модуль рекурсивно делает release зависимостям, зануляет ссылки, удаляет себя с кеша. А пользователю в код возвращается не сам модуль, а объект унаследованный от него, т.е свой экземпляр. упрощенно instance=Object.create(module) Т.е на каждый modules.get("").then(function(module){...})
нужно вызвать
module.release();
module=null;
и не заботится что там и как.