Chúng tôi là người hâm mộ của Yếu tố tùy chỉnh quanh đây. Thiết kế của họ làm cho họ đặc biệt dễ tải, đó có thể là một lợi ích cho hiệu suất.
Lấy cảm hứng từ của một đồng nghiệp thử nghiệm, gần đây tôi đã bắt đầu viết một trình tải tự động đơn giản: Bất cứ khi nào một phần tử tùy chỉnh xuất hiện trong DOM, chúng tôi muốn tải triển khai tương ứng nếu nó chưa có sẵn. Sau đó, trình duyệt sẽ đảm nhận việc nâng cấp các yếu tố đó từ đó trở đi.
Rất có thể bạn sẽ không thực sự cần tất cả những thứ này; thường có một cách tiếp cận đơn giản hơn. Được sử dụng một cách có chủ ý, các kỹ thuật hiển thị ở đây vẫn có thể là một phần bổ sung hữu ích cho bộ công cụ của bạn.
Để nhất quán, chúng tôi muốn trình tải tự động của mình cũng là một thành phần tùy chỉnh — điều đó cũng có nghĩa là chúng tôi có thể dễ dàng định cấu hình nó qua HTML. Nhưng trước tiên, hãy xác định từng phần tử tùy chỉnh chưa được giải quyết đó:
class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; this.discover(scope); }
}
customElements.define("ce-autoloader", AutoLoader);
Giả sử chúng ta đã tải trước mô-đun này (sử dụng async
là lý tưởng), chúng ta có thể thả một <ce-autoloader>
phần tử vào <body>
của tài liệu của chúng tôi. Điều đó sẽ ngay lập tức bắt đầu quá trình khám phá cho tất cả các phần tử con của <body>
, hiện tạo thành phần tử gốc của chúng ta. Chúng tôi có thể giới hạn khám phá trong một cây con của tài liệu của chúng tôi bằng cách thêm <ce-autoloader>
thay vào đó, chúng ta có thể có nhiều phiên bản cho các cây con khác nhau.
Tất nhiên, chúng ta vẫn phải thực hiện điều đó discover
phương pháp (là một phần của AutoLoader
lớp trên):
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); } }
}
Ở đây, chúng tôi kiểm tra phần tử gốc cùng với mọi phần tử con (*
). Nếu đó là một phần tử tùy chỉnh — như được biểu thị bằng các thẻ có gạch nối — nhưng chưa được nâng cấp, thì chúng tôi sẽ thử tải định nghĩa tương ứng. Truy vấn DOM theo cách đó có thể tốn kém, vì vậy chúng ta nên cẩn thận một chút. Chúng ta có thể giảm tải cho luồng chính bằng cách trì hoãn công việc này:
connectedCallback() { let scope = this.parentNode; requestIdleCallback(() => { this.discover(scope); });
}
requestIdleCallback
chưa được hỗ trợ phổ biến, nhưng chúng tôi có thể sử dụng requestAnimationFrame
như một dự phòng:
let defer = window.requestIdleCallback || requestAnimationFrame; class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; defer(() => { this.discover(scope); }); } // ...
}
Bây giờ chúng ta có thể chuyển sang thực hiện phần còn thiếu load
phương pháp tiêm động một <script>
thành phần:
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`;
}
Lưu ý quy ước mã hóa cứng trong elementURL
. Các src
URL của thuộc tính giả sử có một thư mục chứa tất cả các định nghĩa phần tử tùy chỉnh (ví dụ: <my-widget>
→ /components/my-widget.js
). Chúng tôi có thể đưa ra các chiến lược phức tạp hơn, nhưng điều này là đủ tốt cho mục đích của chúng tôi. Việc chuyển URL này sang một phương thức riêng biệt cho phép phân lớp con dành riêng cho dự án khi cần:
class FancyLoader extends AutoLoader { elementURL(tag) { // fancy logic }
}
Dù bằng cách nào, hãy lưu ý rằng chúng tôi đang dựa vào this.rootDir
. Đây là lúc khả năng cấu hình nói trên xuất hiện. Hãy thêm một trình thu thập tương ứng:
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;
}
Bạn có thể đang nghĩ đến observedAttributes
bây giờ, nhưng điều đó không thực sự làm cho mọi thứ dễ dàng hơn. Cộng với cập nhật root-dir
trong thời gian chạy có vẻ như là thứ chúng ta sẽ không bao giờ cần đến.
Bây giờ chúng ta có thể — và phải — định cấu hình thư mục phần tử của mình: <ce-autoloader root-dir="/components">
.
Với điều này, trình tải tự động của chúng tôi có thể thực hiện công việc của mình. Ngoại trừ nó chỉ hoạt động một lần, đối với các phần tử đã tồn tại khi trình tải tự động được khởi chạy. Có lẽ chúng tôi cũng muốn tính đến các yếu tố được thêm động. Đó là nơi MutationObserver
đến chơi:
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();
}
Bằng cách này, trình duyệt sẽ thông báo cho chúng tôi bất cứ khi nào một phần tử mới xuất hiện trong DOM - hay đúng hơn là cây con tương ứng của chúng tôi - mà sau đó chúng tôi sử dụng để bắt đầu lại quá trình khám phá. (Bạn có thể lập luận rằng chúng tôi đang phát minh lại các yếu tố tùy chỉnh ở đây và bạn đã đúng.)
Trình tải tự động của chúng tôi hiện có đầy đủ chức năng. Các cải tiến trong tương lai có thể xem xét các điều kiện cuộc đua tiềm năng và điều tra các tối ưu hóa. Nhưng rất có thể điều này là đủ tốt cho hầu hết các kịch bản. Hãy cho tôi biết trong phần nhận xét nếu bạn có cách tiếp cận khác và chúng ta có thể so sánh các ghi chú!
- Phân phối nội dung và PR được hỗ trợ bởi SEO. Được khuếch đại ngay hôm nay.
- Platoblockchain. Web3 Metaverse Intelligence. Khuếch đại kiến thức. Truy cập Tại đây.
- nguồn: https://css-tricks.com/an-approach-to-lazy-loading-custom-elements/
- 1
- a
- Giới thiệu
- ở trên
- Tài khoản
- thực sự
- thêm
- Ngoài ra
- Tất cả
- giảm bớt
- cho phép
- Đã
- và
- phương pháp tiếp cận
- tranh luận
- xung quanh
- có sẵn
- trình duyệt
- ứng cử viên
- không thể
- mà
- cẩn thận
- tỷ lệ cược
- kiểm tra
- trẻ em
- tốt nghiệp lớp XNUMX
- Đến
- Bình luận
- so sánh
- điều kiện
- Container
- Công ước
- Tương ứng
- có thể
- khóa học mơ ước
- khách hàng
- Thiết kế
- khác nhau
- phát hiện
- tài liệu
- Không
- DOM
- Rơi
- năng động
- dễ dàng hơn
- dễ dàng
- Kỹ lưỡng
- các yếu tố
- đủ
- lôi
- Ether (ETH)
- EV
- Ngay cả
- Mỗi
- Trừ
- đắt tiền
- thất bại
- người hâm mộ
- Tên
- từ
- đầy đủ
- chức năng
- tương lai
- đi
- tốt
- cái đầu
- tại đây
- HTML
- HTTPS
- lý tưởng
- xác định
- ngay
- thực hiện
- thực hiện
- thực hiện
- in
- thay vì
- điều tra
- IT
- JavaScript
- Việc làm
- Loại
- Biết
- Chiều dài
- LIMIT
- ít
- tải
- tải
- Xem
- Chủ yếu
- làm cho
- LÀM CHO
- có nghĩa
- phương pháp
- Might
- mất tích
- mô-đun
- chi tiết
- hầu hết
- di chuyển
- Mozilla
- nhiều
- Cần
- cần thiết
- Mới
- nút
- một phần
- hiệu suất
- plato
- Thông tin dữ liệu Plato
- PlatoDữ liệu
- Play
- thêm
- tiềm năng
- có lẽ
- quá trình
- mục đích
- Cuộc đua
- gần đây
- tẩy
- mà
- trở lại
- nguồn gốc
- kịch bản
- phạm vi
- dường như
- riêng biệt
- định
- nên
- thể hiện
- Đơn giản
- duy nhất
- So
- một cái gì đó
- Bắt đầu
- Bước
- Vẫn còn
- chiến lược
- như vậy
- Hỗ trợ
- TAG
- mất
- kỹ thuật
- Sản phẩm
- cung cấp their dịch
- điều
- Suy nghĩ
- đến
- đúng
- cập nhật
- nâng cấp
- URI
- URL
- us
- sử dụng
- thường
- thông qua
- cái nào
- sẽ
- Công việc
- công trinh
- viết
- trên màn hình
- zephyrnet