<is-land>
将交互式客户端组件添加到您网站中的一种注重绩效的新方式.
或更从技术上讲:框架独立的部分水合岛屿建筑实施.
- 查看 演示
- 看看这个 11th的YouTube频道的初播 财务报告和审定财务报表 包含更多框架实例的后续屏幕播放。 。 。 .
- 深入了解岛屿建筑
特征 :
- 容易添加到现有组件中
- 零依赖关系
- 不与服务器框架或站点生成工具紧密结合.
- 小脚印 (1.79 kB 压缩)
- 为方便安全部门改革框架提供的服务器(SSR)组件实例(提供Lit、Svelte、Vue、Preact)
实例如下:
- Web 组件
- 使用声明阴影 DOM 的 Web 组件 (新见v3.0.0
- 丝绒 (和安全部门改革)
- Vue (又小又可爱) (和安全部门改革)
- 预录 (和安全部门改革)
- 升 (和安全部门改革)
- 阿尔卑斯山.js
- 嵌入于马克下
defer-hydration组件属性支持 (新为v3) (单位:千美元)更多信息defer-hydration在 zachleat.com (中文(简体) )(中文(简体) )- 使用导入地图来简化导入 URL。 。 。 .
- 重命名
<is-land>标签名称或on:属性前缀 - 实验: 图像加载
- 1万个岛屿的压力测试
- 复杂筑巢
is-land测试
野外融合: 十一号, (中文(简体) ), 网络C, (中文(简体) ), 连接度, (中文(简体) ), 斯维尔特基特, (中文(简体) ), 桥镇, (中文(简体) ), 升
安装
备查 时间 @11ty/is-land。 。 。 .
npm install @11ty/is-land
<script type="module" src="/is-land.js"></script>
添加 is-land.js 给您的主捆.
它可以被推迟和/或同步装入. 在使用网络组件时,必须在其他自定义元素之前加载(通过 customElements.define在页面上。 选择您的样式 :
使用量
<is-land>This is an island.</is-land>
在此标签上添加任何数量的加载条件,以控制岛屿的初始化方式和时间. 你可以混合和匹配. 全体 满足初始化的条件.
on:visible- 改变
IntersectionObserverrootMargin与on:visible="200px 0px"
- 改变
on:load(v5新增)on:idle- 设置最大值
requestIdleCallback等待(以毫秒计)on:idle="2000"
- 设置最大值
on:interaction(违约)touchstart,click(中文(简体) )- 更改事件
on:interaction="mouseenter,focusin"
- 更改事件
on:media- 当 Viewport 大小匹配时 :
on:media="(min-width: 64em)" - 减少运动:
- 当用户喜欢减少运动时
on:media="(prefers-reduced-motion)" - 当用户对运动没有偏好时
on:media="(prefers-reduced-motion: no-preference)"
- 当用户喜欢减少运动时
- 当 Viewport 大小匹配时 :
- 保存数据( E)读取关于保存 MDN 数据的内容(中文(简体) )
- 当保存数据激活时
on:save-data - 当保存数据不活动时
on:save-data="false"
- 当保存数据激活时
<is-land on:visible on:idle>
<!-- your HTML here -->
<is-land on:media="(min-width: 64em)">
<!-- Islands can be nested -->
<!-- Islands inherit all of their parents’ loading conditions -->
</is-land>
</is-land>
程序化 API
每个装入条件也可作为保证返回方法 Island。 。 。 .
await Island.onidle(); // or Island.onidle("2000")
await Island.onvisible(element); // or Island.onvisible(element, "200px 0px")
await Island.onload();
await Island.oninteraction(element); // or Island.oninteraction(element, "mouseenter,focusin")
await Island.onmedia("(min-width: 64em)");
await Island.onsavedata(); // or Island.onsavedata("false")
控制后退内容
预编
<is-land on:visible on:idle>
<vanilla-web-component>
Put your pre-JS fallback content in your web component.
</vanilla-web-component>
</is-land>
JS后设置 <template>
将任何后 JS 内容置于一个或多个内 <template data-island> 元素在任何地方 <is-land>。这些将与其模板内容相换。 你可以筑起一个 <is-land> 如果你想进去的话!
<is-land on:visible on:idle>
<template data-island>
<vanilla-web-component>
This component is post-JS.
</vanilla-web-component>
</template>
</is-land>
- 使用
data-island="replace"以取代本指南的内容<is-land>带有模板. - 使用
data-island="once"以每页一次运行模板内容(按模板内容键). (新见v2.0.1)
运行自定义 JavaScript, 加载自定义 CSS
当岛上的装载条件得到满足时,将一个脚本嵌入模板内运行定制JS!
<is-land on:visible>
<template data-island>
<!-- CSS -->
<style>/* My custom CSS */</style>
<link rel="stylesheet" href="my-css-file.css">
<!-- JS -->
<script type="module">console.log("Hydrating!");</script>
<script type="module" src="my-js-file.js"></script>
</template>
</is-land>
导入一个模块
使用 import 在岛上装入条件得到满足时装入 JavaScript 模块。 添加 import-mount 并使用 <is-land> 元素(返回内容恢复后和返回前) ready 已设定,等待任何应许.
<is-land on:visible import="my-component.js" import-mount></is-land>
// my-component.js
export default async function(island) {
// hydrate `island` here
}
你也可以使用这个 ready 样式属性,添加到 <is-land> 当小岛被水淹没时.
<style>
is-land[ready] {
background-color: lightgreen;
}
</style>
查看过渡
使用 Island.setSwapBehavior 将模板和倒置内容互换成 查看过渡。在互换后运行的框架输入类型不包括在内.
Island.setSwapBehavior((swap, island) => {
if(document.startViewTransition) {
document.startViewTransition(swap);
} else {
swap();
}
});
您必须打回电话 swap否则这个岛就永远不会水合物 这个 island 参数是 <is-land> 元素被水化.
框架构成部分支助
type:初始化一个框架初始化类型,由您注册. 实例包括:alpine, (中文(简体) ),petite-vue, (中文(简体) ),vue, (中文(简体) ),vue-ssr, (中文(简体) ),preact, (中文(简体) ),preact-ssr, (中文(简体) ),svelte,或svelte-ssr。 。 。 .
演示文稿、示例和源代码 此处列出的每个框架都有.
微小的阴道
- 实例
- 小图书馆(~9K)
- 渲染模式: 客户端
- 有利于逐步加强(控制回落内容)
<script type="module">
// Define once for any number of Petite Vue islands.
Island.addInitType("petite-vue", async (target) => {
const { createApp } = await import("https://unpkg.com/[email protected]/dist/petite-vue.es.js");
createApp().mount(target);
});
</script>
<is-land on:visible type="petite-vue" v-scope="{ name: 'Vue' }">
Hello from <span v-html="name">HTML</span>
</is-land>
阴道
- 实例
- 大图书馆(~73 kB)
- 渲染模式:客户端(shown),服务器,服务器+客户端(Hydration)
<script type="module">
// Define once for any number of Vue islands.
Island.addInitType("vue", async (target) => {
const { createApp } = await import("https://unpkg.com/[email protected]/dist/vue.esm-browser.js");
createApp({
data: () => (target.dataset), // use <is-land data-> attributes as component data
}).mount(target);
});
</script>
<is-land on:visible type="vue" data-name="Vue">
Hello from <span v-text="name"></span>
</is-land>
丝绒
- 实例 (使用导入地图)
- 中型图书馆
- 渲染模式:客户端,服务器,服务器+客户端(编码)
- 需要客户端模式的编译器( 非常见)
<script type="module">
// Define once for any number of Svelte islands.
Island.addInitType("svelte", async (target) => {
// requires an Import map and svelte is lazy loaded when island is ready
const { mount } = await import("svelte");
const component = await import(target.getAttribute("import"));
mount(component.default, {
target: target,
props: {},
});
});
</script>
<!-- This example uses an Eleventy `svelte` Universal Filter (see SveltePlugin.cjs) -->
{% assign component = "./lib/svelte/my-component-js-only.svelte" | svelte %}
<is-land on:visible type="svelte" import="{{ component.clientJsUrl }}"></is-land>
显示样本导入地图
<!-- importmap from https://generator.jspm.io/ -->
<script type="importmap">
{
"imports": {
"svelte": "https://unpkg.com/[email protected]/src/index-client.js",
"svelte/internal/client": "https://unpkg.com/[email protected]/src/internal/client/index.js",
"svelte/internal/flags/legacy": "https://unpkg.com/[email protected]/src/internal/flags/legacy.js"
},
"scopes": {
"https://unpkg.com/": {
"clsx": "https://unpkg.com/[email protected]/dist/clsx.mjs",
"esm-env": "https://unpkg.com/[email protected]/index.js",
"esm-env/browser": "https://unpkg.com/[email protected]/true.js",
"esm-env/development": "https://unpkg.com/[email protected]/false.js",
"esm-env/node": "https://unpkg.com/[email protected]/false.js"
}
}
}
</script>
预录
- 实例
- 小图书馆(~9 kB)
- 渲染模式:客户端(shown),服务器,服务器+客户端(Hydration)
- 使用时不需要编译器
htm而不是JSX. 互联网档案馆的存檔,存档日期2013-12-21.
<script type="module">
// Define once for any number of Preact islands.
Island.addInitType("preact", async (target) => {
const component = await import(target.getAttribute("import"));
component.default(target);
});
</script>
<is-land on:visible type="preact" import="preact-component.js"></is-land>
示例组件代码 preact-component.js数字 :
import { html, render } from 'https://unpkg.com/htm/preact/index.mjs?module'
function App (props) {
return html`<p><strong>Hello ${props.name}!</strong></p>`;
}
export default function(el) {
render(html`<${App} name="from Preact" />`, el);
}
升
- 实例 (使用导入地图)
- 小图书馆(~10 kB)
- 渲染模式:客户端,服务器,服务器+客户端(编码)
<is-land on:visible import="lit-component.js">
<lit-component name="Post-JS">Pre-JS Content</lit-web-component>
</is-land>
显示样本导入地图
<!-- importmap from https://generator.jspm.io/ -->
<script type="importmap">
{
"imports": {
"lit": "https://unpkg.com/[email protected]/index.js"
},
"scopes": {
"https://unpkg.com/": {
"@lit/reactive-element": "https://unpkg.com/@lit/[email protected]/reactive-element.js",
"lit-element/lit-element.js": "https://unpkg.com/[email protected]/lit-element.js",
"lit-html": "https://unpkg.com/[email protected]/lit-html.js",
"lit-html/is-server.js": "https://unpkg.com/[email protected]/is-server.js"
}
}
}
</script>
示例组件代码 lit-component.js数字 :
import {html, css, LitElement} from "lit";
customElements.define('lit-component', class extends LitElement {
static properties = {
name: {type: String},
};
render() {
return html`<p>Hello, ${this.name || "Stranger"}!</p>`;
}
});
阿尔卑斯山.js
- 实例
- 小图书馆(~20 kB)
- 渲染模式: 客户端
- 有利于逐步加强(控制回落内容)
<script type="module">
// Define once for any number of Alpine islands.
Island.addInitType("alpine", async (target) => {
await import("https://unpkg.com/[email protected]/dist/cdn.min.js");
});
// Workaround for Alpine global mount
Island.addFallback("[x-data]", (node) => {
if(node.hasAttribute("x-ignore")) {
return;
}
node.setAttribute("x-ignore", "");
return () => {
node.removeAttribute("x-ignore");
if(Alpine) {
Alpine.nextTick(() => Alpine.initTree(node));
}
};
});
</script>
<is-land on:visible type="alpine">
<div x-data="{ name: 'Alpine.js' }">
Hello from <span x-text="name">HTML</span>!
</div>
</is-land>
实相.js
- 实例 (使用导入地图)
- 中型图书馆(~40 kB)
- 渲染模式: 客户端