О ленивой загрузке
Как мы все знаем, для веб-сайтов с богатым содержимым страниц парсинг dom будет очень сложным, что приведет к медленной загрузке первого экрана.Для веб-сайтов с богатыми изображениями мы знаем, что мы можем использовать ленивую загрузку изображений для улучшения скорость отклика сайта.я писала в другой статье,если интересно нажмитездесь. Домашние страницы, такие как Taobao, Jingdong и т. д., обрабатываются отложенной загрузкой.Они сначала отображают скелет, а затем заменяют скелет реальным контентом, когда область отложенной загрузки появляется в видимом диапазоне.
скелет:
реальный контент:
Таким образом, домашняя страница может быть предотвращена от загрузки слишком большого количества контента за один раз, а браузер должен отображать слишком много DOM, что вызвано медленной картой.В то же время изображения также загружаются лениво, и можно избежать блокировки рендеринга DOM, вызванной загрузкой изображений.Можно сказать, что можно убить двух зайцев одним выстрелом, тогда как в vue , как мы делаем ленивую загрузку? Здесь я делюсь ленивой загрузкой проектов, которые я сделал с помощью миксина Vue.
vue mixin
Что касается vue mixin, я думаю, что все знают, что такое vue mixin, но лично я считаю, что его основная польза заключается в обмене некоторыми данными.dataи методmethods, чтобы добиться повторного использования кода. Из-за его роли я выбираю примеси как средство для реализации отложенной загрузки.Все модули, которым требуется отложенная загрузка, импортируют примеси, необходимые для отложенной загрузки.
Как реализовать ленивую загрузку
мы знаем вьюv-ifВы можете решить, визуализировать ли компонент, поэтому мы используем v-if для управления ленивым загруженным компонентом, если компонент не находится в видимой области, установите для него значение false или разрешите ему визуализировать скелет, когда компонент появляется в области видимости. видимая область Время рендеринга реального DOM.
Как определить, появляется ли компонент в видимой области
Есть два способа определить, появляется ли компонент в видимой области:
Во-первых, использовать элементgetBoundingClientRectМетод получает позицию элемента, а затем оценивает, больше ли верхний атрибут 0 и между window.innerHeight, и должен отслеживать событие прокрутки страницы и продолжать делать вышеуказанные суждения. больше, пожалуйста, прочитайте картинку, которую я сказал в начале Загрузите реализацию.
2. Воспользуйтесь преимуществами новых функцийIntersectionObserver, эта функция не требует от нас прослушивания события прокрутки, пока элемент появляется в поле зрения, событие visible будет запущено
if ("IntersectionObserver" in window) {
let lazyCompObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
// 元素可见
if (entry.intersectionRatio > 0) {
// TODO 进行一些元素可见后的一些操作,同时该元素不需要被observe了
lazyCompObserver.unobserve(entry.target)
}
})
})
if(this.$el.nodeType === 1) {
// 需要observe的元素
lazyCompObserver.observe(this.$el)
}
}
выполнить
Подводя итог, миксин, который мы реализуем отложенной загрузкой, написан так:
// lazy-load mixin
import {throttle, getClientHeight} from 'tool/tool'
export default {
data() {
return {
isShow: false,
_throttleFn: null
}
},
methods: {
inViewShow() {
if(this.isShow) {
document.removeEventListener('scroll', this._throttleFn, false)
return
}
// 不支持IntersectionObserver api的情况下判断图片是否出现在可视区域内
let { $el } = this
const rect = $el.getBoundingClientRect()
// 出现在视野的时候加载元素
if(0 < rect.top && rect.top < getClientHeight()) {
this.isShow = true
}
}
},
mounted() {
// 支持IntersectionObserver的使用这个api
if ("IntersectionObserver" in window) {
let lazyCompObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0) {
this.isShow = true
lazyCompObserver.unobserve(entry.target)
// 当元素可见时,如果需要回调,则执行
this.onVisible && this.onVisible()
}
})
})
if(this.$el.nodeType === 1) {
lazyCompObserver.observe(this.$el)
}
} else {
// 不支持的使用getBoundingClientRect和scroll来判断
this.inViewShow()
this._throttleFn = throttle(this.inViewShow)
document.addEventListener('scroll', this._throttleFn, false)
}
}
}
// 调用
<template>
<li v-if="isShow">
.....
</li>
</template>
<script>
import lazyLoad from 'mixins/lazy-load'
export default {
mixins: [lazyLoad],
methods: {
onVisible() {
console.log('元素可见了')
}
}
}
</script>
Эффект этоПервый li виден, второй li нет, поэтому он не отображается.
Если что-то не так или исправлено, пожалуйста, оставьте сообщение, чтобы исправить меня.