웹 구성 요소를 위한 IntersectionObserver 믹스인
IntersectionObserver이 무엇인지 모르는 경우 기본적으로 무언가가 표시될 때 이벤트를 생성할 수 있는 낮은 수준의 자바스크립트 API입니다. 즉, 사용자가 앱에서 아래로 스크롤하여 요소를 "보는"이벤트에 응답할 수 있습니다. 요소가 표시될 때를 알면 성능 최적화를 위해 요소의 전체 내부를 조건부로 로드할 수 있습니다!
LitElement의 사용을 장려하는 동안 IntersectionObserverMixin은 모든 웹 구성 요소와 함께 작동하는 바닐라JS 믹스인입니다. 먼저 무엇을 하는지 살펴보고 다른 예를 살펴보겠습니다. 모두 거의 동일합니다.
TLDWTRTC(너무 길어서 코드를 읽고 싶지 않음)
new IntersectionObserver
를 지원하는 SuperClass를 내보냅니다.constructor
에 적용되는 몇 가지 합리적인 기본값이 있으며 구현에서 변경할 수 있습니다connectedCallback
우리는 관찰자를 활성화합니다 disconnectedCallback
우리는 관찰자의 연결을 끊습니다 elementVisible
라는 반응 속성이 있습니다.코드를 보여주세요(또는 메모리를 지연 로드하는 경우 건너뛰기)
const IntersectionObserverMixin = function (SuperClass) {
// SuperClass so we can write any web component library / base class
return class extends SuperClass {
/**
* Constructor
*/
constructor() {
super();
// listen for this to be true in your element
this.elementVisible = false;
// threasholds to check for, every 25%
this.IOThresholds = [0.0, 0.25, 0.5, 0.75, 1.0];
// margin from root element
this.IORootMargin = "0px";
// wait till at least 50% of the item is visible to claim visible
this.IOVisibleLimit = 0.5;
// drop the observer once we are visible
this.IORemoveOnVisible = true;
// delay in observing, performance reasons for minimum at 100
this.IODelay = 100;
}
/**
* Properties, LitElement format
*/
static get properties() {
let props = {};
if (super.properties) {
props = super.properties;
}
return {
...props,
elementVisible: {
type: Boolean,
attribute: "element-visible",
reflect: true,
},
};
}
/**
* HTMLElement specification
*/
connectedCallback() {
if (super.connectedCallback) {
super.connectedCallback();
}
// setup the intersection observer, only if we are not visible
if (!this.elementVisible) {
this.intersectionObserver = new IntersectionObserver(
this.handleIntersectionCallback.bind(this),
{
root: document.rootElement,
rootMargin: this.IORootMargin,
threshold: this.IOThresholds,
delay: this.IODelay,
}
);
this.intersectionObserver.observe(this);
}
}
/**
* HTMLElement specification
*/
disconnectedCallback() {
// if we have an intersection observer, disconnect it
if (this.intersectionObserver) {
this.intersectionObserver.disconnect();
}
if (super.disconnectedCallback) {
super.disconnectedCallback();
}
}
/**
* Very basic IntersectionObserver callback which will set elementVisible to true
*/
handleIntersectionCallback(entries) {
for (let entry of entries) {
let ratio = Number(entry.intersectionRatio).toFixed(2);
// ensure ratio is higher than our limit before trigger visibility
if (ratio >= this.IOVisibleLimit) {
this.elementVisible = true;
// remove the observer if we've reached our target of being visible
if (this.IORemoveOnVisible) {
this.intersectionObserver.disconnect();
}
}
}
}
};
};
export { IntersectionObserverMixin };
실제 사용
따라서 프로덕션에서 이것을 활용할 때 다음과 같은 타이밍을 얻습니다.
import()
사용)render()
요소의 내용을 조건부로 렌더링하기 위해 요소의 ${this.elementVisible ? html
삼항 문(LitElement 특정)을 사용합니다.:
가 true로 변경되면 요소}
을 추가로 수행하기 위해 ${this.elementVisibile}
수명 주기 콜백(LitElement 관련)을 적용합니다.이 접근 방식은 최소한의 노력으로 성능을 최대화합니다. 또한 HAX의 콘텐츠 작성자가
updated()
또는 import()
또는 video-player
와 같은 요소를 페이지에 추가하고 성능에 대해 생각할 필요가 없지만 CMS 기반 사용자 생성 콘텐츠에 대해 합리적으로 높은 점수를 얻을 수 있습니다.구현 방식
기본적으로 두세 가지가 있으며 단일 종속성을 가진 더 빠른 요소가 있습니다. 이 예는 wikipedia-query에서 가져온 것입니다.
import { IntersectionObserverMixin } from "@lrnwebcomponents/intersection-element/lib/IntersectionObserverMixin.js";
// LitElement render function
render() {
return html` ${this.elementVisible
? html` <h3 .hidden="${this.hideTitle}" part="heading-3">
${this._title}
</h3>
<div id="result"></div>
<citation-element
creator="{Wikipedia contributors}"
scope="sibling"
license="by-sa"
title="${this.search} --- {Wikipedia}{,} The Free Encyclopedia"
source="https://${this
.language}.wikipedia.org/w/index.php?title=${this.search}"
date="${this.__now}"
></citation-element>`
: ``}`;
}
updated(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
// element is visible, now we can search
if (propName == "elementVisible" && this[propName]) {
import("@lrnwebcomponents/citation-element/citation-element.js");
}
if (
["elementVisible", "search", "headers", "language"].includes(
propName
) &&
this.search &&
this.headers &&
this.elementVisible &&
this.language
) {
clearTimeout(this._debounce);
this._debounce = setTimeout(() => {
this.updateArticle(this.search, this.headers, this.language);
}, 10);
}
});
}
여기에서 우리는
wikipedia-query
용어와 함께 a11y-gif-player
용어, wikipedia-query
및 elementVisibile
를 사용하여 위키피디아 공개 API의 search
를 트리거한다는 점에서 language
에 대한 추가 조건부 논리를 볼 수 있습니다. 즉, 웹사이트 하단에 wikipedia 기사가 포함되어 있으면 사용자가 해당 기사가 뷰포트에 표시될 때까지 API를 호출하여 기사를 로드하지 않습니다.요소의 성능을 끌어내기 위해 이 IntersectionObserverMixin을 구현한 다른 코드 예제:
이것은 구현이 존재하지 않지만 변경에 대한 속성을 관찰하여 VanillaJS 구현과 함께 사용할 수도 있습니다. 또한 지연 로딩 이미지 자리 표시자 SVG를 수행하기 위해 IntersectionObserverMixin을 혼합하는 SuperClass인 lazyImageLoader에서 보다 고급 구현을 찾을 수 있습니다.
Reference
이 문제에 관하여(웹 구성 요소를 위한 IntersectionObserver 믹스인), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/btopro/intersectionobserver-based-import-5adh텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)