我准备了一个基本示例来演示我想要实现的目标。考虑下面的 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,谷歌开发者文章帮助很大。这是代码。此代码段未经测试
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
标签。我想知道为什么它不可用:/