Сделайте свой сайт адаптивным — Vue Lazy Loading

Vue.js
Сделайте свой сайт адаптивным — Vue Lazy Loading

О ленивой загрузке

Как мы все знаем, для веб-сайтов с богатым содержимым страниц парсинг dom будет очень сложным, что приведет к медленной загрузке первого экрана.Для веб-сайтов с богатыми изображениями мы знаем, что мы можем использовать ленивую загрузку изображений для улучшения скорость отклика сайта.я писала в другой статье,если интересно нажмитездесь. Домашние страницы, такие как Taobao, Jingdong и т. д., обрабатываются отложенной загрузкой.Они сначала отображают скелет, а затем заменяют скелет реальным контентом, когда область отложенной загрузки появляется в видимом диапазоне.

скелет:image

реальный контент:
image

Таким образом, домашняя страница может быть предотвращена от загрузки слишком большого количества контента за один раз, а браузер должен отображать слишком много 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>

Эффект этоimageПервый li виден, второй li нет, поэтому он не отображается.

Примечание: Поскольку вы хотите определить положение элемента, вам нужно использовать стиль для установки высоты li.Если вы лениво загружаете другие элементы, вам также необходимо установить высоту

Если что-то не так или исправлено, пожалуйста, оставьте сообщение, чтобы исправить меня.