rendering

While you’re here, you can have the girls.

define

Lazy loading, a performance optimization known to front-end people, simply set the image path only when the image appears in the viewable area of the browser, so that the image is displayed. This is lazy loading of images.

Realize the principle of

Listen for the scroll event of the page to check whether the top value of the element is less than or equal to the visible height of the page

The judging logic code is as follows

element.getBoundingClientRect().top <= document.documentElement.clientHeight ? Display: default

We know that the script logic of the applet page runs in JsCore, which is an environment with no window objects, so you can’t use Windows in scripts or manipulate components in scripts.

So the lazy loading of pictures on the need to work on the data.

page

If the value is false, display the default image. If the value is false, display the default image.

The code looks something like this

<view wx:for="{{list}}" class='item item-{{index}}'
 wx:key="{{index}}">
	<image class="{{item.show ? 'active': ''}}" src="{{item.show ? item.src : item.def}}"></image>
</view>
Copy the code

The layout is simple. The View component has an image and loops through the list to show as many as it has

The SRC field of the image component is bound to show for each item, with active adding a transparent transition

style

image{
	transition: all .3s ease;
	opacity: 0;
}
.active{
	opacity: 1;
}

Copy the code

logic

The standard focuses on lazy loading, so data is written to death on the page

The data structure is as follows:

We use two methods to achieve lazy loading. Ready or not, let’s have fun with lazy loading.

WXML node information

The applet supports creating a SelectorQuery instance by calling createSelectQuery, using the Select method to select nodes, and retrieving node information via boundingClientRect.

wx.createSelectorQuery().select('.item').boundingClientRect((ret)=>{
	console.log(ret)
}).exec()
 
Copy the code

The following output is displayed:

onPageScroll
getSystemInfo

Now, this is a clear idea. Or the above logic, drag drag directly write code on the line, here only write the main logic, complete code please stamp at the end of the github

showImg(){
	let group = this.data.group
	let height = this.data.height  // The visible height of the page
	
	wx.createSelectorQuery().selectAll('.item').boundingClientRect((ret) = > {
	 ret.forEach((item, index) = > {
	   if(item.top <= height) {group[index]. Show =true // Change the state according to the subscript}})this.setData({
	   group
	 })
	}).exec()

}
onPageScroll(){ // Scroll events
	this.showImg()
}
Copy the code

So far, we have completed a small program version of the picture lazy loading, but the thinking has changed, in fact, did not change the way to achieve. Let’s learn something new.

Node layout intersection status

What is the node intersection state? It is a new API called IntersectionObserver. This article only explains how to use it. Please click on me for more information

It is defined in the applet that the node layout crossover state API can be used to listen for the intersection state of two or more component nodes at the layout location. This set of apis can often be used to infer whether and to what extent certain nodes are visible to the user.

There are five main design concepts, respectively

  • Reference node: the layout area of a reference node is used as the reference area.There can be more than one reference node, multiple words reference regions take their layout regionsintersection
  • Target node: The target to listen onanode
  • Intersection region: the intersection region of the target node and the reference node
  • Intersection ratio: the intersection ratio of the target node and the reference node
  • Threshold: There can be multiple thresholds. The default is [0], which can be understood as cross ratios, for example [0.2, 0.5].

There are five apis for it, as follows

1, createIntersectionObserver ([this], [options]), see knowledge meaning, create a IntersectionObserver instance

2, intersectionObserver. RelativeTo (selector, [margins]), a specified node as a reference area, can magnify the narrow margins parameters reference area, can contain the top, left, bottom, right, four

3, intersectionObserver. RelativeToViewport ([margin]), specify the page display area as the reference area

4, intersectionObserver. The observer (targetSelector, callback), the parameter to specify the monitoring nodes and a callback function, the target element intersection status changes will trigger the function, the callback function contains a result, Here to tell

5, intersectionObserver. Disconnect () to stop listening, the callback function won’t trigger

And then the result in the callback function, which contains the field

The field name type instructions
intersectionRatio Number Intersection of proportion
intersectionRect Object The boundary of the intersection area includes left, right, top, and bottom
boundingClientRect Object The boundary of the target node layout area, including left, right, top, and bottom
relativeRect Object Refer to the boundary of the area, including left, right, top, and bottom
time Number The timestamp of the intersection detection

We mainly use intersectionRatio for judgment. If it is greater than 0, it indicates that intersecting is visible.

First, what does the following function do, and how many times will the log function be executed

1, wx. CreateIntersectionObserver (.) relativeToViewport (). The observer ('.box', (result) => {
 	console.log('Listen for functions triggered by box components')})2, wx. CreateIntersectionObserver (.) relativeTo ('.box').observer('.item', (result) => {
 	console.log('Listen for functions triggered by the Item component')})3, wx. CreateIntersectionObserver (.) relativeToViewport (). The observer ('.box', (result) => {
	if(result.intersectionRatio > 0) {console.log('.box component is visible ')}})Copy the code

Duang, here’s the answer.

The first one listens on the window of the current page. Box component, and the log triggers twice, once to enter the page and once to leave the page

The second one listens for the.item component in the layout area of the.box node, and the log fires twice, once to enter the page and once to leave the page

The third one listens on the window of the current page. The box component, log is only emitted when the node is visible

So you can use IntersectionObserver to implement lazy image loading. The main logic is as follows

let group = this.data.group // Get the image array data
for (let i in this.data.group){   wx.createIntersectionObserver().relativeToViewport().observe('.item-'+ i, (ret) => {
	   if (ret.intersectionRatio > 0){
	     group[i].show = true 
	   }
	   this.setData({
	     group
	   })
	 })
}
Copy the code

The last

So far, we have implemented lazy loading of images in the mini-program version in two ways, and it can be found that IntersectionObserver can be used to achieve not too sour and cool.

Github