perf(@vant/lazyload): reuse some utils (#9591)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { h } from 'vue';
|
||||
import { inBrowser } from './util';
|
||||
import { inBrowser } from '@vant/use';
|
||||
|
||||
export default (lazy) => ({
|
||||
props: {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import { find, remove } from './util';
|
||||
/* eslint-disable prefer-object-spread */
|
||||
import { remove } from './util';
|
||||
|
||||
const defaultOptions = {
|
||||
selector: 'img',
|
||||
@@ -74,13 +75,13 @@ export default class LazyContainerManager {
|
||||
}
|
||||
|
||||
update(el, binding, vnode) {
|
||||
const container = find(this._queue, (item) => item.el === el);
|
||||
const container = this._queue.find((item) => item.el === el);
|
||||
if (!container) return;
|
||||
container.update({ el, binding, vnode });
|
||||
}
|
||||
|
||||
unbind(el) {
|
||||
const container = find(this._queue, (item) => item.el === el);
|
||||
const container = this._queue.find((item) => item.el === el);
|
||||
if (!container) return;
|
||||
container.clear();
|
||||
remove(this._queue, container);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { inBrowser, loadImageAsync, noop } from './util';
|
||||
import { inBrowser } from '@vant/use';
|
||||
import { loadImageAsync, noop } from './util';
|
||||
|
||||
export default (lazyManager) => ({
|
||||
props: {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { nextTick } from 'vue';
|
||||
import { inBrowser, getScrollParent } from '@vant/use';
|
||||
import {
|
||||
inBrowser,
|
||||
remove,
|
||||
find,
|
||||
_,
|
||||
on,
|
||||
off,
|
||||
throttle,
|
||||
supportWebp,
|
||||
getDPR,
|
||||
scrollParent,
|
||||
getBestSelectionFromSrcset,
|
||||
isObject,
|
||||
hasIntersectionObserver,
|
||||
@@ -147,7 +146,7 @@ export default function () {
|
||||
}
|
||||
|
||||
if (!$parent) {
|
||||
$parent = scrollParent(el);
|
||||
$parent = getScrollParent(el);
|
||||
}
|
||||
|
||||
const newListener = new ReactiveListener({
|
||||
@@ -186,7 +185,7 @@ export default function () {
|
||||
let { src } = value;
|
||||
src = getBestSelectionFromSrcset(el, this.options.scale) || src;
|
||||
|
||||
const exist = find(this.ListenerQueue, (item) => item.el === el);
|
||||
const exist = this.ListenerQueue.find((item) => item.el === el);
|
||||
if (!exist) {
|
||||
this.add(el, binding, vnode);
|
||||
} else {
|
||||
@@ -212,7 +211,7 @@ export default function () {
|
||||
remove(el) {
|
||||
if (!el) return;
|
||||
this._observer && this._observer.unobserve(el);
|
||||
const existItem = find(this.ListenerQueue, (item) => item.el === el);
|
||||
const existItem = this.ListenerQueue.find((item) => item.el === el);
|
||||
if (existItem) {
|
||||
this._removeListenerTarget(existItem.$parent);
|
||||
this._removeListenerTarget(window);
|
||||
@@ -273,7 +272,7 @@ export default function () {
|
||||
*/
|
||||
_addListenerTarget(el) {
|
||||
if (!el) return;
|
||||
let target = find(this.TargetQueue, (target) => target.el === el);
|
||||
let target = this.TargetQueue.find((target) => target.el === el);
|
||||
if (!target) {
|
||||
target = {
|
||||
el,
|
||||
@@ -315,7 +314,7 @@ export default function () {
|
||||
*/
|
||||
_initListen(el, start) {
|
||||
this.options.ListenEvents.forEach((evt) =>
|
||||
_[start ? 'on' : 'off'](el, evt, this.lazyLoadHandler)
|
||||
(start ? on : off)(el, evt, this.lazyLoadHandler)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ export default class ReactiveListener {
|
||||
this.elRenderer = elRenderer;
|
||||
this._imageCache = imageCache;
|
||||
this.performanceData = {
|
||||
init: Date.now(),
|
||||
loadStart: 0,
|
||||
loadEnd: 0,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const inBrowser = typeof window !== 'undefined';
|
||||
import { inBrowser } from '@vant/use';
|
||||
|
||||
export const hasIntersectionObserver =
|
||||
inBrowser &&
|
||||
@@ -11,13 +11,13 @@ export const modeType = {
|
||||
observer: 'observer',
|
||||
};
|
||||
|
||||
function remove(arr, item) {
|
||||
export function remove(arr, item) {
|
||||
if (!arr.length) return;
|
||||
const index = arr.indexOf(item);
|
||||
if (index > -1) return arr.splice(index, 1);
|
||||
}
|
||||
|
||||
function getBestSelectionFromSrcset(el, scale) {
|
||||
export function getBestSelectionFromSrcset(el, scale) {
|
||||
if (el.tagName !== 'IMG' || !el.getAttribute('data-srcset')) return;
|
||||
|
||||
let options = el.getAttribute('data-srcset');
|
||||
@@ -82,21 +82,10 @@ function getBestSelectionFromSrcset(el, scale) {
|
||||
return bestSelectedSrc;
|
||||
}
|
||||
|
||||
function find(arr, fn) {
|
||||
let item;
|
||||
for (let i = 0, len = arr.length; i < len; i++) {
|
||||
if (fn(arr[i])) {
|
||||
item = arr[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
const getDPR = (scale = 1) =>
|
||||
export const getDPR = (scale = 1) =>
|
||||
inBrowser ? window.devicePixelRatio || scale : scale;
|
||||
|
||||
function supportWebp() {
|
||||
export function supportWebp() {
|
||||
if (!inBrowser) return false;
|
||||
|
||||
let support = true;
|
||||
@@ -114,7 +103,7 @@ function supportWebp() {
|
||||
return support;
|
||||
}
|
||||
|
||||
function throttle(action, delay) {
|
||||
export function throttle(action, delay) {
|
||||
let timeout = null;
|
||||
let lastRun = 0;
|
||||
return function (...args) {
|
||||
@@ -135,19 +124,18 @@ function throttle(action, delay) {
|
||||
};
|
||||
}
|
||||
|
||||
const _ = {
|
||||
on(el, type, func, capture = false) {
|
||||
el.addEventListener(type, func, {
|
||||
capture,
|
||||
passive: true,
|
||||
});
|
||||
},
|
||||
off(el, type, func, capture = false) {
|
||||
el.removeEventListener(type, func, capture);
|
||||
},
|
||||
};
|
||||
export function on(el, type, func) {
|
||||
el.addEventListener(type, func, {
|
||||
capture: false,
|
||||
passive: true,
|
||||
});
|
||||
}
|
||||
|
||||
const loadImageAsync = (item, resolve, reject) => {
|
||||
export function off(el, type, func) {
|
||||
el.removeEventListener(type, func, false);
|
||||
}
|
||||
|
||||
export const loadImageAsync = (item, resolve, reject) => {
|
||||
const image = new Image();
|
||||
|
||||
if (!item || !item.src) {
|
||||
@@ -160,61 +148,23 @@ const loadImageAsync = (item, resolve, reject) => {
|
||||
image.crossOrigin = item.cors;
|
||||
}
|
||||
|
||||
image.onload = function () {
|
||||
image.onload = () =>
|
||||
resolve({
|
||||
naturalHeight: image.naturalHeight,
|
||||
naturalWidth: image.naturalWidth,
|
||||
src: image.src,
|
||||
});
|
||||
};
|
||||
|
||||
image.onerror = function (e) {
|
||||
reject(e);
|
||||
};
|
||||
image.onerror = (e) => reject(e);
|
||||
};
|
||||
|
||||
const style = (el, prop) =>
|
||||
typeof getComputedStyle !== 'undefined'
|
||||
? getComputedStyle(el, null).getPropertyValue(prop)
|
||||
: el.style[prop];
|
||||
|
||||
const overflow = (el) =>
|
||||
style(el, 'overflow') + style(el, 'overflow-y') + style(el, 'overflow-x');
|
||||
|
||||
const scrollParent = (el) => {
|
||||
if (!inBrowser) return;
|
||||
if (!(el instanceof HTMLElement)) {
|
||||
return window;
|
||||
}
|
||||
|
||||
let parent = el;
|
||||
|
||||
while (parent) {
|
||||
if (parent === document.body || parent === document.documentElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!parent.parentNode) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (/(scroll|auto)/.test(overflow(parent))) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
return window;
|
||||
};
|
||||
|
||||
function isObject(obj) {
|
||||
export function isObject(obj) {
|
||||
return obj !== null && typeof obj === 'object';
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
export function noop() {}
|
||||
|
||||
class ImageCache {
|
||||
export class ImageCache {
|
||||
constructor({ max }) {
|
||||
this.options = {
|
||||
max: max || 100,
|
||||
@@ -238,19 +188,3 @@ class ImageCache {
|
||||
this._caches.shift();
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
ImageCache,
|
||||
inBrowser,
|
||||
remove,
|
||||
find,
|
||||
noop,
|
||||
_,
|
||||
isObject,
|
||||
throttle,
|
||||
supportWebp,
|
||||
getDPR,
|
||||
scrollParent,
|
||||
loadImageAsync,
|
||||
getBestSelectionFromSrcset,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user