通过template标签来延迟加载组件和资源

109 阅读2分钟

HTML的<template>标签,更多的是和Web Compoenents或者Shadow DOM等话题一起出现的。不过这次要说的,和前面两个东西没啥关系,我们要通过<template>标签来对一个HTML的代码块做延迟加载(或者按需加载)。

为什么这里要用<template>标签呢,主要还是由于它的一个特性,也就是在<template>标签可以在保有了完整的HTML代码的情况下,其子元素中各种资源(script/link等)并不会在页面加载时就渲染,而是要等到其内容(这些内容的类型是DocumentFragment)被实际的attach到某个节点上时才渲染。这个特定,就可以让我们做到尽量不干预某个组件(代码块)中的内容,就可以通过<template>标签做一层wrapper来实现整个组件(代码块)的延迟加载。

我们通过一个例子来说明一下具体的使用方法:

首先,把需要延迟加载的代码包在一个<template>标签内部(具体内容不重要,反正代码):

<template id="test-tmpl">
  <style>
    p {
      font-size: 16;
      color: green;
    }
  </style>
  <div>
    <p>Hello World, too!</p>
  </div>
</template>

然后,写一个loadTemplate方法:

function loadTemplate() {
  let template = document.getElementById("test-tmpl");
  let app = document.getElementById("app");
  app.appendChild(template.content.cloneNode(true));
}

需要加载组件时,调用loadTemplate方法就可以了。如果<template>标签内部包含外部引用的<link>和<script>标签,也可以在调用loadTemplate方法之后才去加载的。这个例子的完整代码可以通过这个codepen来查看。

相对于其他的方法,采用<template>标签比较适合应用在下面的场景:

  • 通过<template>标签可以完整的保留原始的代码,非常适合用于优化和调整第三方外部插件的加载(比如广告、统计和调试组件)。
  • 通过后端渲染出的组件(当然也就是HTML),可以比较方便的通过这个方式来控制其加载的时机。后端只需要把对应的组件(不管有多复杂)包在一个<template>标签内部就可以了。
    • 同样的,通过SSR渲染的组件也可以基于同样的原理来延迟渲染。