A single-page Web application (Single page Web Application,spa) loads page resources at one time, renders pages with local computing power, and improves page switching speed and user experience. This leads to the slow loading of the first screen, which is a big problem for the front-end development engineers.
Recently consulted a number of posts, found an extremely powerful method, its compatibility needs to be improved ~ ~ (but there are related Polyfill methods) on- demand loading
Load all
import ' ccharts '
//on-demand loading only the components that need to be used
import ' echarts/lib/component/title '
import ' Echarts/lib /component/tooltip '
import ' echarts/lib/component/legend '
import ' Echarts/lib/chart/bar '
You can reduce the size of the component load, save network bandwidth, and thus improve response speed. Load Components asynchronously
First we can split the application into modules and then load the components asynchronously. With Webpack code segmentation, to achieve the effect of loading on demand (the following simple statement, do not do detailed explanation).
Webpack, there are three common ways of code segmentation: Entry Start: Manually detach code using the entry configuration. Prevent repetition: Use Commonschunkplugin to go heavy and separate chunk. Dynamic import: Uses the module's inline function to separate the code.
Synchronous mode
import search from ' @/views/search/search.vue '
//Asynchronous Way
Const Search = (resolve) => require ([' @/ Views/search.vue '], resolve)
//ES6 asynchronous Method (recommended)
const SEARCH = () => import (' @/views/search.vue ')
Note that you need to configure relevant information in Webpack
Output: {
path: '/dist ',
filename: ' js/[name].[ Chunkhash].js ',
chunkfilename: ' js/[id].[ Chunkhash].js '
},
Note that filename determines the name of the bundle. However, this option does not affect those output files that "load chunk" on Demand. " For these files, use the Output.chunkfilename option to control the output. Files created by loader are also unaffected. In this case, you must try to loader the specific options available. Lazy Load
By listening to the scroll bar to determine whether the loading process in the viewable area, Document.documentElement.clientHeight > Dom.getboundingclientrect (). Top
<div class= "Content" ><span>1</span></div>
<div class= "content" ><span>2 </span></div>
<div class= "content" ><span>3</span></div>
<div class= "Content" ><span>4</span></div>
<div class= "content" ><span>5</span ></div>
Const Imageaddress = '.. /images/'
Const Viewheight = height function of document.documentElement.clientHeight//viewable region
$ (selector) {
Return Array.from (Document.queryselectorall (selector))
}
function Lazyload () {
//Get all pictures $ for lazy loading
( '. Content '). ForEach (item => {Let
rect, imgsrc let
index = item.queryselector (' span '). InnerHTML
// Resource loaded, avoid duplicate load
if (item.dataset.src!== ') return
rect = item.getboundingclientrect ()
//Picture one enters the visual area, dynamically loads C13/>if (rect.bottom >= 0 && rect.top < viewheight) {
imgsrc = ' ${imageaddress}${index}.jpg '
ITEM.DATASET.SRC = imgsrc Let
img = document.createelement (' img ')
img.src = imgsrc
item.appendchild ( IMG)}}
)
}
lazyload ()
document.addeventlistener (' scroll ', lazyload)
Note: To identify the loaded resource, prevent duplicate loading.
In this way, the Getboundingclientrect () method of the target element (Green Square) is called after the scroll event is heard, and it corresponds to the viewport information, and then it is judged whether it is within the viewport. The disadvantage of this method is that because of the intensive occurrence of scroll events (which can be handled using throttling functions, of course), the computational volume is very large, which is prone to performance problems. Intersectionobserver
The Intersectionobserver interface provides developers with the means to listen asynchronously to the intersection of the target element and its ancestors or Windows (viewport). The API is asynchronous (reduces expensive DOM and style query overhead, as well as CPU, GPU energy costs)and is useful for understanding the visibility of elements and for preload and lazy loading of DOM content without triggering a rolling synchronization of the target element.
Intersectionobserver ((entries, observer) =>{}, Options)
//observe designated target element
Observer.observe (target);
Stops observing the specified target element
Observer.unobserve (target);
Stop observing all elements
observer.disconnect ();
The entries is a Intersectionobserverentry object that contains the following properties: Time: When the visibility changes, milliseconds, target: The targeted element, the DOM node object, the Rootbounds: the rectangular region of the root element, The return value of the Getboundingclientrect () method that returns null if there is no root element (that is, scrolling directly relative to the viewport); Boundingclientrect: Information for the rectangular region of the target element; Intersectionrect: Information about the cross region of the target element and the viewport (or root element); Intersecttionratio: The visible proportions of the target element;
The options are Intersectionobserverinit objects that contain the following properties: Root: Specifies the container node (that is, the root element) where the target element is located; Rootmargin: to extend or reduce the size of the rootbounds rectangle, Thus affecting the size of the Intersectionrect cross area; Threshold: Determines when the callback function is triggered
var io = new Intersectionobserver (entries) => {
Entries.foreach (entry => {Let
{target, intersectionratio = = Entry
console.log (Target.tagname, Intersectionratio)
})
}, {
threshold: [0, 0.25, 0.5, 0.75, 1]
})
Monitor
Io.observe ($ ('. Target '))
The class name, which is called ' Target ', performs the related callback function when the visible proportions are [0, 0.25, 0.5, 0.75, 1].
To implement lazy loading:
var io = new Intersectionobserver (entries) => {
Entries.foreach (entry => {Let
{target, intersectionratio = = Entry
//target element's visible proportions are greater than 0
if (intersectionratio) {let
index = target.queryselector (' span '). InnerHTML
Let img = document.createelement (' img ')
img.src = ' ${imageaddress}${index}.jpg '
target.appendchild (IMG)
//Cancel listener, prevent duplicate load
io.unobserve (target)}}
, {
threshold: [0]
})
//Monitor
$ ('. Content '). ForEach (element => {
Io.observe (Element)
})
Instance address: https://github.com/381510688/practice/blob/master/javascript_test/lazyLoad.html compatibility
GitHub provides the related Polyfill way: Intersectionobserver Polyfill
Reference Address: https://www.w3.org/TR/intersection-observer/http://www.ruanyifeng.com/blog/2016/11/ intersectionobserver_api.html https://github.com/xunleif2e/vue-lazy-component