How to use functions to optimize performance?

I. Throttle function

1. Use scenarios

DOM.onclick() event, we bind a click event to a DOM node, trigger the execution of the event function when clicking on the element, but when we click on the element frequently, it will continue to trigger the click event. If the event function triggered by the click event is DOM element, it will cause high performance consumption and may cause page jamming.

So at this point we should limit the trigger frequency of the event and reduce the page overhead.

2. principle

Events are triggered continuously, but the event function is only executed once within a specified period.

3. Code Implementation

function throttle(fn, wait = 500) {
    let lastTime = 0 // Initialize the event of the last call
    return function () {
        let args = [].slice.call(arguments) // Converting class arrays to arrays
        let nowTime = new Date().getTime() // Get the current time
        if(nowTime - lastTime > wait) { 
            fn.apply(this, args)
            lastTime = nowTime // Reassign the last call time
        }
    }
}

// Use
let btn = document.getElementById('btn')
let fn = function () {
    console.log(1)
}
btn.onclick = throttle(fn, 1000)

After adding a click event to the button, even if the button is clicked continuously, the event handler will only be executed once every 1000ms.

2. Anti-jitter Function

1. Use scenarios

For example, when we enter the content we want to search in the input box of Baidu search, we will have you enter the content of the input box and search after a short time after we stop typing. If you pause less than the specified time after typing, you will recalculate the time.

2. principle

The so-called anti-jitter means that the function can only execute once in N seconds after triggering an event. If the event is triggered again in n seconds, the execution time of the function will be recalculated.

3. Code Implementation

function debounce(fn, delay) {
    let timer = null
    return function () {
        let _self = this
        let args = [].slice.call(arguments)
        clearTimout(timer)
        timer = setTimout(function () {
            fn.apply(_self, args)
        }, delay)
    }
} 

// Use
let inp = document.getElementById('inp')
function handler() {
    console.log(this.value)
}
inp.oninput = debounce(handler, 500)

After using the throttle function, we will input the value in the input box after pausing the input for 500 ms. If the pause time is less than 500 ms, we will not output, and the execution time of the function will be recalculated.

3. Time-sharing function

For example, when we render a large data into a list, we require that all data must be rendered, not lazy loading, so when we add a large number of DOM nodes to the page in a short time, it will obviously cause browser jamming.

let arr = []
for(let a = 0; a < 1000; a++) {
    arr.push(a)
}
function render(data) {
    for(let i = 0; i < arr.length; i++) {
        let div = document.createElement('div')
        div.innerHTML = arr[i]
        document.body.appenChild(div)
    }
}
render(arr)

So we create a function that adds nodes in a time-sharing manner, such as adding 1000 nodes in 1s instead of adding 20 nodes every 200 ms.

let timeChunk = function (data, fn, count = 20, delay = 200) {
    let obj,timer
    let start = function () {
        for(let i = 0; i < Math.min(count, data.length); i++) {
            let obj = data.shift()
            fn(obj)
        }
    }
    return function () {
        timer = setInterval(function () {
            if(data.length === 0) {
                return clearInterval(timer)
            }
            start()
        }, delay)
    }
}

Using time-sharing functions

let arr = []
for (let a = 0; a < 1000; a++) {
    arr.push(a)
}

function render(data) {
    let div = document.createElement('div')
    div.innerText = data
    document.body.appendChild(div)
}
let renderlist = timeChunk(arr, render, 20, 200)
renderlist()

This creates 20 nodes every 200 ms after calling the time-sharing function.

IV. INERTIVE FUNCTIONS

In front-end development, because of the differences of browsers, some sniffing work is unavoidable, such as the implementation of a common add event function in all browsers. Common Writing:

let addEvent = function (element, type, handler) {
    if(window.addEventListener) {
        return element.addEventLisenter(type, handler, false)
    } else if (window.attachEvent) {
        return element.attachEvent('on'+type, handler)
    }
}

But every time we execute a function, we have to make branch judgment. Then when we decide which browser to execute the function, we only need to make the first judgment, and then use it without judgment, because we execute the function in the same browser.

So we can use the lazy loading function, there are always some branch judgments in the body of the function, but after the first entry into the branch condition, the function will be rewritten inside the function. After the rewriting, the function we expect will be the function. When we re-enter the function next time, we do not need to make branch judgments.

let addEvent = function (element, type, handler) {
    if(window.addEventListener) {
        addEvemt = function(element, type, handler) {
            element.addEventLisenter(type, handler, false)
        }
    } else if (window.attachEvent) {
        addEvent = function(element, type, handler) {
            element.attachEvent('on'+type, handler)
        }
    }
    addEvent(element, type, handler)
}

You can pay attention to me. Nuggets address

Reference

Keywords: Javascript less

Added by metroblossom on Tue, 14 May 2019 21:56:43 +0300