我可以通过缓存动态加载 Web 组件引用的数据吗?
Posted
技术标签:
【中文标题】我可以通过缓存动态加载 Web 组件引用的数据吗?【英文标题】:Can i load data referenced by a Web Component dynamically, with caching? 【发布时间】:2021-08-20 12:18:41 【问题描述】:我目前正在学习 Web 组件,我想知道是否可以让组件动态加载自己的数据,类似于 <img>
从其 src
属性中所做的那样,即类似这样:
<my-fancy-thingy src='/stuff.json'></my-fancy-thingy>
如果stuff.json
可能相当大,这个功能显然会很有用,所以它也应该可以利用浏览器的缓存机制,所以每次我们请求页面时都不会重新加载引用的文件,除非更改.
这个可以吗?
【问题讨论】:
【参考方案1】:当然,从
/*
defining the <load-file> Web Component,
yes! the documenation is longer than the code
License: https://unlicense.org/
*/
customElements.define("load-file", class extends htmlElement
// declare default connectedCallback as sync so await can be used
async connectedCallback(
// attach a shadowRoot if none exists (prevents displaying error when moving Nodes)
// declare as parameter to save 4 Bytes: 'let '
shadowRoot = this.shadowRoot || this.attachShadow(mode:"open")
)
// load SVG file from src="" async, parse to text, add to shadowRoot.innerHTML
shadowRoot.innerHTML = await (await fetch(this.getAttribute("src"))).text()
// append optional <tag [shadowRoot]> Elements from inside <load-svg> after parsed <svg>
shadowRoot.append(...this.querySelectorAll("[shadowRoot]"))
// if "replaceWith" attribute
// then replace <load-svg> with loaded content <load-svg>
// childNodes instead of children to include #textNodes also
this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes)
)
将 .text()
更改为 .json()
并解析 JSON 文件
可以通过将字符串存储在 localStorage 中来完成缓存(但我认为总共限制为 5MB):
https://en.wikipedia.org/wiki/Web_storage
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
你需要想出“数据已经改变”的策略;因为客户端不知道数据何时 实际更改了。如果(大)JSON 文件 发生更改,可能会有一个额外的 信号量 文件/端点提供信息。
【讨论】:
我想更像是重用浏览器内置的chaching策略,即如果服务器发送304,浏览器会重用其缓存副本。但我想这对于webcomponents是不可能的,所以我们必须重新发明使用您描述的某种方法进行相同的操作。 Web 组件是(自定义)HTML 标记。它们与 如何 浏览器缓存网络请求和任何其他 HTML 标记一样...无。跨度> 不确定这应该是什么意思...您是说“获取”功能会在适当时自动重用文件的浏览器端缓存版本,就像任何其他 html 触发的文件加载一样?但是为什么我需要手动将结果缓存在本地存储中呢? 如果您的服务器发送正确的标头以允许缓存,是的,那么 fetch 将使用缓存的版本。 nitropack.io/blog/post/web-caching-beginners-guide 和 developer.mozilla.org/en-US/docs/Web/HTTP/Caching。所有这些都与“Web 组件”无关【参考方案2】:这就像一个魅力
export class MonElement extends HTMLElement
constructor()
super();
this.attachShadow(mode:'open');
(...)
this.shadowRoot.appendChild(atemplate);
connectedCallback()...
static get observedAttributes()
return ['src'];
attributeChangedCallback(nameattr,oldval,newval)
if (nameattr==='src')
this[nameattr]=newval;
here do the fetch for the src value which is newval then update what you got in the innerdom
(...)
【讨论】:
以上是关于我可以通过缓存动态加载 Web 组件引用的数据吗?的主要内容,如果未能解决你的问题,请参考以下文章
可以通过动态生成的 <script> 注册 Knockout 组件吗?