Small program split screen loading practice
It’s easy to run into first-screen rendering problems when iterating through small programs. The possible causes of this problem are as follows: the small program package is too large and resources need to be loaded. The network environment is too poor and the download speed is too slow. Too many render nodes, rendering time.
In view of the problem of small program loading package for the first time, small program proposed the function of subcontracting loading, here is not detailed description, you can go to see the official document
Here I chose to optimize for the render node.
Technical solution
In the API document of wechat, there is an API for judging nodes and visual areas
IntersectionObserver object, which is used to infer whether certain nodes can be seen by users and what proportion can be seen by users
At this point, I wonder if it is possible to establish a relationship between IntersectionObserver and the component, so that when the component enters the visible area, its content will be displayed, but otherwise it will be hidden, so as to dynamically load the module.
/ / pseudo code
// Set up a listener
element.observer()
// Process entry
observer.handleEnterView((a)= > {
callback() // Handle the callback
disconnect() / / destroy
})
Copy the code
<! -- component -->
<view class="component">
<view class="component-header"></view>
<view class="component-observer" wx:if="{{ observer_status}}"></view>
<view class="component-content" wx:else>
<! -- your content -->
</view>
</view>
Copy the code
The development phase
Once the basic technical plan is established, it’s time to move to the code level
Component({
data: {
observer_status: true
},
// Write in ready because components are laid out in the view layer at this time
ready () {
// Since we are using the entire viewport area of the device as the reference area, we select a relativeToViewport directly. If we need another viewport, we can use a relativeTo to select the reference area
this.observer = this.createIntersectionObserver().relativeToViewport()
// My approach here is to display its own content whenever the observed node enters the viewable area
// In fact, the observer callback is triggered when the observation node enters or leaves the viewable area. I have chosen to display the area as soon as it executes and close the observation
this.observer.observe('.observer', (res) => {
this.setData({
observer_status: false
})
this.observer.disconnect()
this.observer = null
})
},
detached () {
// If you leave without entering the viewable area, you also need to destroy your own observations
this.observer && this.observer.disconnect()
}
})
Copy the code
To optimize the
Do you think this is the end? It is not.
For a widget page, it can be made up of templates or components. Template needs to be defined in the Page, and observeAll:all is required if there are too many objects to view, but the official documentation states that selecting too many nodes at once will affect rendering performance.
For component development, it is not clear that writing every component this way will affect rendering performance as observerAll: All does, and if it does, it will have to reduce the number of objects to be observed, or make it a larger container to observe. But it would be tedious to write every component like this.
This is where the benefits of components come in. When defining components, one of the most amazing properties is behaviors. Simply put, it is a code reuse mechanism. Using behaviors directly enables components to automatically acquire certain methods, attributes. With this feature, you can write a lot less code inside the component.
// mixin.js
module.exports = Behavior({
data: {
observer_status: true
},
ready () {
this.observer = this.createIntersectionObserver().relativeToViewport()
// Set the class of the observer node
this.observer.observe('.component-observer', (res) => {
this.setData({
observer_status: false
})
this.observer.disconnect()
this.observer = null
})
},
detached () {
this.observer && this.observer.disconnect()
}
})
Copy the code
// Component.js
let mixin = require('Your Mixin path')
Component({
behaviors: [mixin]
})
Copy the code
<! -- Component.wxml -->
<view class="component">
<view class="component-header"></view>
<view class="component-observer" wx:if="{{ observer_status}}"></view>
<view class="component-content" wx:else>
<! -- your content -->
</view>
</view>
Copy the code
Alternatively, you can make the entire Observer into components, thus reducing the number of observers and aggregating some modules
<! -- Observer.wxml -->
<view class="observer">
<view class="observer-element" wx:if="{{ observer_status}}"></view>
<view class="observer-content" wx:else>
<slot/>
</view>
</view>
Copy the code
It is important to note that for a component, if the observer is an observer, you need an observer node, and the observer node must be a visual object of non-zero height. If you want height without affecting the position of the page, you can use some hack methods
.component-observer {
height: 1rpx;
margin-top: -1rpx;
}
Copy the code
Some follow-up discussion
I tried to use hidden property when using IntersectionObserver. However, hiiden is actually rendered, just not displayed, and does not result in faster page loading
rendering
Here is take a demo to get, need to click here or browse the applet code snippets at https://developers.weixin.qq.com/s/oV1RFfmY7H4W
Before using
After using
If the image doesn’t move and you can click on it you can see that the improvement is quite obvious
Subsequent advanced
Picture lazyLoad scheme
Image has a lazy-load property, but it can only be used in the page and in the scrollview, so it can be used elsewhere
<! -- image-compponent -->
<view class="observer-picture">
<image src="{{ _src }}"></image>
</view>
Copy the code
// image-component js
Component({
properties: {imageSrc: {
type: String.value: ' ',}},data: {
_src: "default_image"
},
ready () {
/ / pseudo code
observer('.observer-picture')
.then((a)= > {
this.setData({
_src: this.properties.imageSrc
})
})
}
})
Copy the code
Scroll to the bottom/top
For ordinary view, if you need to do the end load, there will be scroll view to do it, but this performance will be poor, easy to appear stuck, so you can also use this to achieve after packaging a layer
The latter
This is the first time to publish an article here. Welcome to discuss and exchange your experience