우리는 팬입니다 맞춤 요소 여기 주위에. 그들의 디자인은 그들을 특히 게으른 로딩에 취약, 성능에 도움이 될 수 있습니다.
에 의해 영감을 동료의 최근에 간단한 자동 로더를 작성하기 시작했습니다. 사용자 정의 요소가 DOM에 나타날 때마다 아직 사용할 수 없는 경우 해당 구현을 로드하려고 합니다. 그런 다음 브라우저는 그러한 요소의 업그레이드를 처리합니다.
실제로 이 모든 것이 필요하지 않을 가능성이 있습니다. 일반적으로 더 간단한 접근 방식이 있습니다. 의도적으로 사용하더라도 여기에 표시된 기술은 여전히 도구 세트에 유용한 추가 기능이 될 수 있습니다.
일관성을 위해 자동 로더도 사용자 지정 요소가 되기를 원합니다. 즉, HTML을 통해 쉽게 구성할 수 있습니다. 하지만 먼저 해결되지 않은 맞춤 요소를 단계별로 식별해 보겠습니다.
class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; this.discover(scope); }
}
customElements.define("ce-autoloader", AutoLoader);
이 모듈을 미리 로드했다고 가정하면(사용 async
이상적임), 우리는 <ce-autoloader>
요소에 <body>
우리 문서의. 그러면 다음의 모든 하위 요소에 대한 검색 프로세스가 즉시 시작됩니다. <body>
, 이제 루트 요소를 구성합니다. 다음을 추가하여 문서의 하위 트리로 검색을 제한할 수 있습니다. <ce-autoloader>
대신 각 컨테이너 요소에 — 실제로 다른 하위 트리에 대해 여러 인스턴스가 있을 수도 있습니다.
물론 우리는 여전히 그것을 구현해야합니다 discover
방법(의 일부로 AutoLoader
위의 클래스):
discover(scope) { let candidates = [scope, ...scope.querySelectorAll("*")]; for(let el of candidates) { let tag = el.localName; if(tag.includes("-") && !customElements.get(tag)) { this.load(tag); } }
}
여기에서 모든 단일 자손과 함께 루트 요소를 확인합니다(*
). 하이픈으로 연결된 태그로 표시된 맞춤 요소이지만 아직 업그레이드되지 않은 경우 해당 정의를 로드하려고 시도합니다. 그런 식으로 DOM을 쿼리하는 것은 비용이 많이 들 수 있으므로 약간 주의해야 합니다. 이 작업을 연기하여 메인 스레드의 로드를 완화할 수 있습니다.
connectedCallback() { let scope = this.parentNode; requestIdleCallback(() => { this.discover(scope); });
}
requestIdleCallback
아직 보편적으로 지원되지는 않지만 사용할 수 있습니다. requestAnimationFrame
대안으로:
let defer = window.requestIdleCallback || requestAnimationFrame; class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; defer(() => { this.discover(scope); }); } // ...
}
이제 누락된 구현으로 넘어갈 수 있습니다. load
동적으로 주입하는 방법 <script>
요소:
load(tag) { let el = document.createElement("script"); let res = new Promise((resolve, reject) => { el.addEventListener("load", ev => { resolve(null); }); el.addEventListener("error", ev => { reject(new Error("failed to locate custom-element definition")); }); }); el.src = this.elementURL(tag); document.head.appendChild(el); return res;
} elementURL(tag) { return `${this.rootDir}/${tag}.js`;
}
의 하드 코딩된 규칙에 유의하십시오. elementURL
. 그만큼 src
속성의 URL은 모든 맞춤 요소 정의가 있는 디렉토리가 있다고 가정합니다(예: <my-widget>
→ /components/my-widget.js
). 우리는 더 정교한 전략을 생각해낼 수 있지만, 이것은 우리 목적에 충분합니다. 이 URL을 별도의 메서드로 위임하면 필요할 때 프로젝트별 서브클래싱이 가능합니다.
class FancyLoader extends AutoLoader { elementURL(tag) { // fancy logic }
}
어느 쪽이든, 우리는 this.rootDir
. 이것은 앞서 언급한 구성 가능성이 들어오는 곳입니다. 해당 getter를 추가해 보겠습니다.
get rootDir() { let uri = this.getAttribute("root-dir"); if(!uri) { throw new Error("cannot auto-load custom elements: missing `root-dir`"); } if(uri.endsWith("/")) { // remove trailing slash return uri.substring(0, uri.length - 1); } return uri;
}
당신은 생각할 수도 있습니다 observedAttributes
하지만 그렇다고 해서 일이 더 쉬워지는 것은 아닙니다. 플러스 업데이트 root-dir
런타임에는 절대 필요하지 않을 것 같습니다.
이제 요소 디렉토리를 구성할 수 있고 구성해야 합니다. <ce-autoloader root-dir="/components">
.
이것으로 자동 로더가 제 역할을 할 수 있습니다. 자동 로더가 초기화될 때 이미 존재하는 요소에 대해 한 번만 작동하는 것을 제외하고. 동적으로 추가된 요소도 고려해야 할 것입니다. 그게 어디야 MutationObserver
작동합니다.
connectedCallback() { let scope = this.parentNode; defer(() => { this.discover(scope); }); let observer = this._observer = new MutationObserver(mutations => { for(let { addedNodes } of mutations) { for(let node of addedNodes) { defer(() => { this.discover(node); }); } } }); observer.observe(scope, { subtree: true, childList: true });
} disconnectedCallback() { this._observer.disconnect();
}
이런 식으로 브라우저는 새로운 요소가 DOM(또는 각각의 하위 트리)에 나타날 때마다 알려줍니다. 그런 다음 검색 프로세스를 다시 시작하는 데 사용합니다. (여기서 사용자 정의 요소를 다시 발명한다고 주장할 수 있으며, 어느 정도 맞을 것입니다.)
이제 자동 로더가 완전히 작동합니다. 향후 개선 사항은 잠재적 경쟁 조건을 살펴보고 최적화를 조사할 수 있습니다. 그러나 이것이 대부분의 시나리오에 충분할 가능성이 있습니다. 다른 접근 방식이 있는 경우 의견에 알려 주시면 메모를 비교할 수 있습니다!
- SEO 기반 콘텐츠 및 PR 배포. 오늘 증폭하십시오.
- 플라토 블록체인. Web3 메타버스 인텔리전스. 지식 증폭. 여기에서 액세스하십시오.
- 출처: https://css-tricks.com/an-approach-to-lazy-loading-custom-elements/
- 1
- a
- 소개
- 위의
- 계정
- 실제로
- 추가
- 또한
- All
- 덜다
- 수
- 이미
- 과
- 접근
- 논쟁
- 약
- 가능
- 브라우저
- 후보자
- 한
- 주의
- 승산
- 검사
- 아이
- 수업
- 왔다
- 댓글
- 비교
- 조건
- 컨테이너
- 컨벤션
- 동
- 수
- 코스
- 관습
- 디자인
- 다른
- 발견
- 문서
- 하지 않습니다
- DOM
- 드롭
- 역동적 인
- 쉽게
- 용이하게
- 정교한
- 요소
- 충분히
- 오류
- 에테르 (ETH)
- EV
- 조차
- 모든
- 외
- 비싼
- 실패한
- 팬
- 먼저,
- 에
- 충분히
- 기능의
- 미래
- 가는
- 좋은
- 머리
- 여기에서 지금 확인해 보세요.
- HTML
- HTTPS
- 이상
- 확인
- 바로
- 구현
- 이행
- 구현
- in
- 를 받아야 하는 미국 여행자
- 조사
- IT
- 자바 스크립트
- 일
- 종류
- 알아
- 길이
- 제한
- 작은
- 하중
- 로드
- 보기
- 본관
- 확인
- 제작
- 방법
- 방법
- 수도
- 누락
- 모듈
- 배우기
- 가장
- 움직임
- 모질라
- 여러
- 필요
- 필요
- 신제품
- 노드
- 부품
- 성능
- 플라톤
- 플라톤 데이터 인텔리전스
- 플라토데이터
- 연극
- ...을 더한
- 가능성
- 아마
- 방법
- 목적
- 경주
- 최근에
- 제거
- 그
- return
- 뿌리
- 시나리오
- 범위
- 것
- 별도의
- 세트
- 영상을
- 표시
- 단순, 간단, 편리
- 단일
- So
- 무언가
- 스타트
- 단계
- 아직도
- 전략들
- 이러한
- 지원
- TAG
- 소요
- 기법
- XNUMXD덴탈의
- 그들의
- 일
- 사고력
- 에
- 참된
- 업데이트
- 업그레이드
- URI
- URL
- us
- 사용
- 보통
- 를 통해
- 어느
- 의지
- 작업
- 일
- 쓰기
- 너의
- 제퍼 넷