Потоковая передача html/ содержимого, но есть контроль над тем, какая часть вставляется в уже проанализированный контент (не в виде добавления)
Я подготовил простой пример, чтобы продемонстрировать, чего я хочу достичь. Рассмотрим HTML-код ниже.
<html>
<head></head>
<body>
<header> </header>
<div class='container'></div>
<footer></footer>
</body>
</html>
Довольно просто. Все динамические данные находятся в контейнере div. Отдых статичен. Я использовал сервис-воркеров и модель оболочки приложения (вроде), чтобы ускорить время загрузки. Я сделал что-то вроде этого
top-shell.html
- который заканчивается непосредственно перед контейнером. bottom-shell.html
- начинается с нижнего колонтитула. И сам контейнер.
<!-- top-shell.html -->
<html>
<head></head>
<body>
<header> </header>
<!-- bottm-shell.html -->
<footer></footer>
</body>
</html>
Контейнер имеет динамические данные. Так что придется загружать через запрос. Я пробовал транслировать его вместе с остальными. Dev.to, статьи Google Developer очень помогли. Это код. Этот фрагмент не протестирован
function pageStream(request) {
const stream = new ReadableStream({
start(controller) {
const fetchHeader = caches.match('/top-shell.html')
const fetchContainer = fetch('/container.html')
.then(response => response)
function push(stream) {
const reader = stream.getReader();
return reader.read().then(function process(result) {
if (result.done) return
controller.enqueue(result.value);
return reader.read().then(process);
});
}
fetchHeader.then(response => push(response.body))
.then(() => fetchContainer)
.then(response => push(response.body))
.then(() => controller.close())
}
});
return new Response(stream, {
headers: {
'Content-Type': 'text/html; charset=utf-8'
}
});
}
self.addEventListener('fetch', event => {
// Checks ... (assets excluded, only html)
event.respondWith(pageStream(event.request));
});
Я исключил некоторые части и нижнюю часть корпуса, чтобы разместить меньше кода. Работает нормально.
Дело в том, что я не люблю разделять html-теги, как это тело. Я хотел бы, чтобы в этом файле заканчивалось тело и тег html. А затем укажите конкретную точку, куда будет вставлен контейнер во время потоковой передачи. Нравится
<html>
<body>
<header></header>
<!-- {{ container here }} -->
<!-- {{ footer here from cache }} -->
</body>
</html>
Итак, этот файл будет загружен из кеша. Затем контейнер начнет потоковую передачу и будет вставлен в{{ container here }}
. Я могу написать простую систему шаблонов типа jinja2, которая выполнит эту работу. Я хочу, чтобы все это происходило внутри сервис-воркера. Конечно, я не хочу, чтобы пользователи видели эти фигурные скобки.
Я достиг точки, в которой я могу декодировать уже передаваемый фрагмент, используя TextDecoder
но не мог двигаться вперед, потому что весь файл, включая container
идет потоковая передача, я не могу полностью заменить фигурные скобки. Если я удалю его, будет вставлен следующий кусок.
Простите мои ошибки. Довольно запутанный и не обладающий твердым пониманием некоторых вещей, чтобы подойти к этому в одиночку.
Кстати, может кто-нибудь добавить ReadableStream
тег. Интересно, почему он недоступен:/