About lazy loading
As we all know, dom parsing will be very complicated for websites with rich page content, which will lead to slow loading of the first screen. For websites with rich images, we know that we can use lazy loading of images to improve the response speed of the site. I wrote in my other article, if you are interested, click here. Like Taobao, Jingdong and so on the home page are after lazy loading processing, they will first render out the skeleton, and then lazy loading area appears in the visual range of the skeleton to replace the real content.
Skeleton:
Real Content:
In this way, the home page can avoid loading too much content at one time, and the browser needs to render too much DOM, resulting in slow loading. At the same time, the image can also be lazy loading, avoiding the dom rendering block caused by downloading images, which can be described as two things in one move, so in vue, how do we do lazy loading? Here to share the project I do, using vue mixin lazy loading.
vue mixin
As for vue mixin, I think we all know the function of vue mixin. Personally, the biggest use of vue mixin is to share some data and methods, so as to realize code reuse. Because of its function, I choose mixin as the means to realize lazy loading. All modules that need lazy loading import mixin required by lazy loading.
How to implement lazy loading
We know that vue’s V-if determines whether or not to render the component, so we use v-if to control lazy loading of the component by setting it to false if it is not in the viewable area, or having it render the skeleton and then render the actual DOM when the component is in the viewable area.
How do I determine if a component is in the viewable area
There are two ways to determine if a component is in the viewable area: Use the getBoundingClientRect method to get the location of the element, and then check whether the top attribute is greater than 0 to window.innerHeight, and listen for the scroll event of the page. Please read the lazy image loading implementation I described at the beginning. Secondly, a new feature IntersectionObserver is adopted, which does not require us to monitor rolling events and triggers visible events as long as elements appear in view
if ("IntersectionObserver" in window) {
letLazyCompObserver = new IntersectionObserver((entries) => {entries.foreach ((entry) => {// Elements visibleif(entry.IntersectionRatio > 0) {// TODO performs some operations after some elements are visible, At the same time. This element does not need to be observe the lazyCompObserver unobserve (entry. Target)}})})if(this.$el.nodeType === 1) {// LazyCompobServer.observe (this).$el)}}Copy the code
implementation
To sum up, our lazy loading mixins are written like this
// 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} // Judge whether an image appears in the visible area if IntersectionObserver API is not supportedlet { $el } = this
const rect = $el.getboundingClientRect () // Loads the element when it appears in viewif(0 < rect.top && rect.top < getClientHeight()) {
this.isShow = true}}},mounted() {// Support the use of IntersectionObserver APIif ("IntersectionObserver" in window) {
let lazyCompObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0) {
this.isShow = trueLazyCompObserver. Unobserve (entry. Target) / / when the element is visible, if you need the callback, execute this. OnVisible && enclosing onVisible ()}})})if(this.$el.nodeType === 1) {
lazyCompObserver.observe(this.$el)}}else{// Unsupported use getBoundingClientRect and scroll to judge this.inviewShow () this._throttlefn = throttle(this.inviewshow) document.addEventListener('scroll', this._throttleFn, false// Call <template> <li v-if="isShow">... </li> </template> <script> import lazyLoad from'mixins/lazy-load'
export default {
mixins: [lazyLoad],
methods: {
onVisible() {
console.log('Element visible')
}
}
}
</script>
Copy the code
That’s what it looks likeThe first li is visible, the second li is not, so it is not rendered.
There is wrong or correct the place, forget everyone comment correct.