JS: 导入多个 Web 组件

huangapple go评论84阅读模式
英文:

JS: importing multiple web components

问题

1st method (feeling wrong):

class WorkPanel extends HTMLElement {
    //stuff in here
}

window.customElements.define('work-panel', WorkPanel)

and

class Sidebar extends HTMLElement {
    //stuff in here
}

window.customElements.define('side-bar', Sidebar)

index.html

<body>
<side-nav></side-nav>
<work-panel></work-panel>

<script type="module" src="javascripts/workPanel.js"></script>
<script type="module" src="javascripts/sideNav.js"></script>

</body>

2nd method

it differs from the first one as I have an index.js where I have the content and it's the module itself containing the web components.

import './javascripts/sideNav.js'
import './javascripts/workPanel.js'

const template = document.createElement('template')
template.innerHTML = `
    <style>
        div.content {
            display: block;
        }
        div.sidebar {}
        div.workpanel {}
    </style>
    <side-nav class="sidebar"></side-nav>
    <work-panel class="workpanel"><work-panel/>
    `;

class SiteContent extends HTMLElement {
    constructor() {
        super();

        this.attachShadow({ mode: "open"})
        this.shadowRoot.appendChild(template.content.cloneNode(true))
    }
}

window.customElements.define('site-content', SiteContent)

index.html

<body>
<site-content></site-content>
<script type="module" src="index.js"></script>
</body>

Is it better to have multiple modules loading each component or one module loading all components? How could it affect the performance or potentially the architecture later?

Thanks in advance

英文:

I am pretty new to JavaScript and just playing around with web components. Now it's not clear to me about importing different web components and how to do it a correct way, if there is a correct way. Maybe you could take a look on a way how I do it until now and tell me some advantages and drawbacks according to it, it would be great. If you think I am doing it wrong I would appreciate if you could show me the way and explain why is it better.

1st method (feeling wrong):

class WorkPanel extends HTMLElement {
    //stuff in here
}

window.customElements.define(&#39;work-panel&#39;, WorkPanel)

and

class Sidebar extends HTMLElement {
    //stuff in here
}

window.customElements.define(&#39;side-bar&#39;, Sidebar)

index.html

&lt;body&gt;
&lt;side-nav&gt;&lt;/side-nav&gt;
&lt;work-panel&gt;&lt;/work-panel&gt;

&lt;script type=&quot;module&quot; src=&quot;javascripts/workPanel.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;module&quot; src=&quot;javascripts/sideNav.js&quot;&gt;&lt;/script&gt;

&lt;/body&gt;

2nd method

it differs from the first one as I have an index.js where I have the content and it't the module itself containing the web components.

import &#39;./javascripts/sideNav.js&#39;
import &#39;./javascripts/workPanel.js&#39;

const template = document.createElement(&#39;template&#39;)
template.innerHTML = `
    &lt;style&gt;
        div.content {
            display: block;
        }
        div.sidebar {}
        div.workpanel {}
    &lt;/style&gt;
    &lt;side-nav class=&quot;sidebar&quot;&gt;&lt;/side-nav&gt;
    &lt;work-panel class=&quot;workpanel&quot;&gt;&lt;work-panel/&gt;
    `;

class SiteContent extends HTMLElement {
    constructor() {
        super();

        this.attachShadow({ mode: &quot;open&quot;})
        this.shadowRoot.appendChild(template.content.cloneNode(true))
    }
}

window.customElements.define(&#39;site-content&#39;, SiteContent)

index.html

&lt;body&gt;
&lt;site-content&gt;&lt;/site-content&gt;
&lt;script type=&quot;module&quot; src=&quot;index.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;

Is it better to have multiple modules loading each component or one module loading all components. How could it affect the performance or potentially the architecture later?

Thanks in advance

答案1

得分: 0

Preamble

在你注意到 明显性能下降 之前,不必担心性能问题。即使在这种情况下,也不要优化每一个细节,只优化通过测量、分析和基准测试确定的重要方面。


两种方式都确保脚本的 执行顺序

索引 &lt;script&gt; 元素

导入其他脚本的单个脚本必须在其他脚本的下载之前(部分地?)下载。

这理论上可能导致加载时间较慢,但实际上不应显著影响加载时间,如果有的话。

每页一个独立脚本的好处可以说是更好的组织:页面的所有代码都包含在一个“入口点”JS-only文件中。还可以包含任何小的代码,而不必链接另一个小脚本。

由于“延迟链接”,保持更轻量级的HTML可能导致更早的页面呈现

单独的 &lt;script&gt; 元素

显式链接所有资源在HTML的初始扫描/解析期间向浏览器提供了所有相关的URL。这可能导致加载时间更快

此外,单独链接使得独立脚本的导入更加可靠:如果一个导入其他脚本的脚本无法下载,那么这些导入也不会发生。

&lt;head&gt;部分链接所有资源提供了一个HTML的所有依赖项概览,这可能更可取。


理论上,来自相同来源的许多小脚本可能下载比一个大脚本慢,因为必须发送许多单独的请求。这意味着:如果可能的话,应该捆绑尽可能多的脚本。

但是,为每个页面量身定制的单个大脚本也不是有益的:资源可以被缓存,但如果这些资源从未被重复使用,那么缓存它们是没有意义的。


注意: 具有 type=module 的脚本被延迟,因此晚于早期链接它们只会阻止浏览器预加载资源。您应该始终尽早链接资源(即在&lt;head&gt;中),甚至可以使用&lt;link rel=preload&gt;来处理大资源。

英文:

Preamble

You should not worry about performance unless you notice significant underperformance. Even then, don't optimize every detail but only the aspects that matter, identified by measuring, analyzing and benchmarking.


Both ways ensure the execution order of your scripts.

Index &lt;script&gt; element

A single script that imports others has to be (partially?) downloaded before downloads of the others can start.

This could result in theoretically slower loading times, but practically it shouldn't affect loading times significantly, if at all.

A benefit of a distinct script per page is arguably better organization: All of a page's code is contained in a single "entry point" JS-only file. Any small code may be included as well, instead of having to link yet another small script.

Keeping a more lightweight HTML due to "deferred linking" may result in earlier page rendering.

Individual &lt;script&gt; elements

Linking all resources explicitly provides the browser with all relevant URLs during initial scan/parse of the HTML. This may result in faster loading times.

Also, individual linking makes for robust imports of independent scripts: If a script that imports others fails to download, then those imports won't happen.

Linking all resources in the &lt;head&gt; section provides an overview of all dependencies with a quick glance at the HTML, which may be preferable.


Theoretically, many small scripts from the same origin may be downloaded slower than one large script, because many individual request have to be sent. This means: If possible, you should bundle as many scripts as possible.

However, a single large script tailored to each page individually is also not beneficial: Resources can be cached, but if those aren't ever re-used than caching them is pointless.


Note: Scripts with type=module are deferred, so linking them late instead of early only prevents the browser to preload the resource. You should always link resources early (i.e. in &lt;head&gt;), and maybe even use &lt;link rel=preload&gt; for large resources.

答案2

得分: -1

没有更好的方法;只有根据您的要求的方法。

注:<template> 可以很好,但不是必需的,您的代码可以被压缩:

import './javascripts/sideNav.js';
import './javascripts/workPanel.js';

customElements.define('site-content', class extends HTMLElement {
  constructor() {
    super() // 设置并返回'this'范围
      .attachShadow({mode: "open"}) // 设置并返回this.shadowRoot
      .innerHTML = `
          <style>
               div.content {
                  display: block;
               }
               div.sidebar {}
               div.workpanel {}
          </style>
          <side-nav class="sidebar"></side-nav>
          <work-panel class="workpanel"></work-panel>`;
  }
})

依赖项

如果您有依赖关系,其中组件B只能在加载组件A时才能工作;
使用:customElements.whenDefined
https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/whenDefined

英文:

The is no better way; there is only your way, depending on your requirements

Note: &lt;template&gt; can be great, but are not required, your code can be condensed:

import &#39;./javascripts/sideNav.js&#39;
import &#39;./javascripts/workPanel.js&#39;

customElements.define(&#39;site-content&#39;, class extends HTMLElement {
  constructor() {
    super() // sets AND returns the &#39;this&#39; scope
      .attachShadow({mode: &quot;open&quot;}) // sets AND returns this.shadowRoot
      .innerHTML = `
          &lt;style&gt;
               div.content {
                  display: block;
               }
               div.sidebar {}
               div.workpanel {}
          &lt;/style&gt;
          &lt;side-nav class=&quot;sidebar&quot;&gt;&lt;/side-nav&gt;
          &lt;work-panel class=&quot;workpanel&quot;&gt;&lt;work-panel/&gt;`
  }
})

Dependencies

If you have dependenies, where Component B can only work when Component A is loaded;
use: customElements.whenDefined
https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/whenDefined

huangapple
  • 本文由 发表于 2023年3月4日 04:44:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631717.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定