如何防止 Web 组件闪烁?

How to prevent flickering with web components?

考虑一个简单的网络组件

class TimeAgo extends HTMLElement {
    constructor() {
        super();
        this.innerHTML = '2 hours ago'
    }
}

customElements.define('time-ago', TimeAgo);

这样使用

This post was created <time-ago datetime="2020-09-26T11:28:41.9731640+01:00">September 26th</time-ago>

当页面呈现时,浏览器将首先写入“9 月 26 日”,然后立即切换为“2 小时前”。

有没有办法防止这种情况发生?我更愿意在第一次绘制时显示“2 小时”。

JS 文件是通过 CDN 加载的,上下移动脚本标签响应没有任何改变。

但是你的脚本是在 DOM 的那部分被解析之前执行的吗?

下面的代码在 Chromium 中显示 1A,在 FireFox 中显示 1
因为(不要把我固定在术语上)在 Chromium 中 1 被注入到 DOM before content A 被解析。

因此,如果您不想要 FOUC,请将 <time-ago> content 留空.. 或者用 CSS

模糊它
<!DOCTYPE html>
<html>
  <head>
    <script>
      window.onload = () => {
        console.log("onload");
      };
      customElements.define(
        "my-element",
        class extends HTMLElement {
          constructor() {
            super();
            console.log("constructor");
        }
        connectedCallback() {
            console.log("connectedCallback");
            this.innerHTML = "1";
          }
        }
      );
    </script>
  </head>
  <body>
    <my-element>A</my-element>
    <script>
        console.log("end DOM");
    </script>
  </body>
</html>

我能想到的一种可能的解决方案是启用 shadow-dom

class TimeAgo extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: 'open' });
        this.innerHTML = '2 hours ago'
    }
}

customElements.define('time-ago', TimeAgo);

通过将 Web 组件定义为影子 dom,您甚至可以在内容附加到 DOM 之前更改内容。