Mobile performance optimization (JavaScript performance optimization)

JavaScript performance optimization

 

DOM operation optimization

The most efficient way to find DOM elements is to use id if you can use id (depending on the specific environment)

document.getElementById('slider')

 

It's not efficient to start from document to find child elements. It's recommended to start from specific parent elements

Reduce the level of element lookup

            var sliderItemContainer = document.querySelector('.slider-item-container');//from DOM Start searching
            var sliderItemContainer = sliderEl.querySelector('.slider-item-container');//Find from specific elements

 

Use variable cache after DOM operation, otherwise you need to operate DOM multiple times to get

            // Reasonable cache DOM object
            var sliderItemContainer = sliderEl.querySelector('.slider-item-container'),
                sliderItem = sliderItemContainer.querySelectorAll('.slider-item'),
                indicatorContainer = document.createElement('div');

 

Manipulating strings in loops, and then DOM at the end; much better than manipulating DOM in each loop

Not recommended

            for (var i = 0, num = sliderItem.length; i < num; i++) {
                 indicatorContainer.innerHTML += '<span class="slid
             }
  

Recommend

            // Reduce operation DOM Number of times
            var html="";
            for (var i = 0, num = sliderItem.length; i < num; i++) {
                html += '<span class="slider-indicator"></span>';
                }

                indicatorContainer.innerHTML=html ;
            }

You can also use document fragments because they have not yet been rendered, so DOM rendering is not involved in the loop

Only create a document fragment node once outside the loop, clone the node within the loop, and pass in true to copy with content

           var indicatorItemFragment = document.createDocumentFragment();//Create document fragment
           var spanEl = document.createElement('span');

            // Reduce operation DOM Number of times
            for (var i = 0, num = sliderItem.length; i < num; i++) {
                var indicatorItem = spanEl.cloneNode(true);
                indicatorItem.className = 'slider-indicator';
                indicatorItemFragment.appendChild(indicatorItem);
            }

 

The length of the loop is also saved as a variable, only executed once at the beginning

Not recommended

for (var i = 0; i < sliderItem.length; i++)

Recommend

for (var i = 0, num = sliderItem.length; i < num; i++) 

 

Do not modify the style directly. Modify it by adding a class
Modify style directly. If there are many contents to be modified, you need to operate DOM multiple times. In addition, rearrangement and redraw are involved
Rearrangement involves the change of the position relationship of elements, redrawing involves the color transparency of elements, etc
Redrawing affects performance and consumes more performance than redrawing, so you need to reduce redrawing and avoid redrawing
Not recommended
                // Do not modify directly style,By adding class modify
                if (i === activeIndex) {
                    indicatorItem.style.backgroundColor = '#007aff';
                    indicatorItem.style.opacity = 1;
                    // Rearrange redraw
                }

Recommend

                // Do not modify directly style,By adding class modify
                if (i === activeIndex) {
                    indicatorItem.className += ' slider-indicator-active';
                }

 

Optimization of events:

Avoid multiple binding of events, and add or unbind when changing nodes

Avoid traversing nodes and binding events to each element

You can use event agents or event delegates to bind events to their parent elements once (event bubbling principle)

Not recommended

        var sliderEl = document.getElementById('slider'),
            sliderIndicatorContainer = sliderEl.querySelector('.slider-indicator-container'),
            sliderIndicators = sliderIndicatorContainer.querySelectorAll('.slider-indicator');

        // Event binding
        for (var i = 0, num = sliderIndicators.length; i < num; i++) {
            sliderIndicators[i].addEventListener('click', function () {
                console.log('click');
            }, false);
        }

        // Dynamically insert a new node
        var sliderIndicator = document.createElement('span');
        sliderIndicator.className = 'slider-indicator';
        sliderIndicatorContainer.appendChild(sliderIndicator);
        sliderIndicator.addEventListener('click', function () {
            console.log('click');
        }, false);

Recommend

        // Use event agent to avoid direct event binding
        // jQuery/Zepto
        $(sliderIndicatorContainer).on('click', '.slider-indicator', function () {});

        //Native js
        sliderIndicatorContainer.addEventListener('click', function (ev) {
            // console.log(ev.target);//ev.target gets the currently clicked element
            if (ev.target && /(^|\s)slider\-indicator($|\s)/.test(ev.target.className)) {
                //Regular judgment of the current clicked element className
                console.log('click');
            }
        }, false);

 

For very frequent events, event throttling is used to dilute

For example, scroll resize mousemove touchmove and other events

        // Event throttling
        // scroll resize mousemove touchmove
        var timer = null;
        window.addEventListener('scroll', function () {
            console.log('scroll');//No throttling

            //100ms If there is duplicate execution, cancel the previous execution
            clearTimeout(timer);
            timer = setTimeout(function () {
                console.log('scroll');//throttle
            }, 100);
            // ....
        }, false);

 

 

Load resources on demand (lazy load, delayed load)

The src attribute of img can be placed in data src (custom attribute) first, and a uniform loading icon will be placed in the default src

Add a unified class for pictures that need to be loaded on demand

<img src="img/loading.gif" data-src="img/recommend/1.jpg" alt="recommend" class="recommend-img lazyload-img">

Get all the picture nodes that need to be loaded on demand and store them in the array

        var lazyLoadClass = '.lazyload-img';
        //Array.prototype.slice.call()Class array to array
        var imgArr = Array.prototype.slice.call(document.querySelectorAll(lazyLoadClass));//Get a list of all the nodes that need to be loaded on demand, and turn to array

        console.log(imgArr);

 

Perform on demand loading functions at initialization and every scroll

        lazyLoadImgs();//Image load on initialization

        //Image loading every time you scroll
        var timer = null;
        window.addEventListener('scroll', function () {
            clearTimeout(timer);
            timer = setTimeout(function () {
                lazyLoadImgs();
            }, 100);
        }, false);

Judge whether the element is in the visible area

        // Is it in the page visual area
        function isInVisibleArea(el) {
            var rect = el.getBoundingClientRect();
            // rect.top Top of viewing area to top of object
            // rect.bottom  Bottom of visible area to bottom of object
            // rect.right Right side of visual area to right side of object
            // rect.left From the left side of the visible area to the left side of the object

            return rect.bottom > 0 && rect.top < window.innerHeight && rect.right > 0 && rect.left < window.innerWidth;
        }

Load functions on demand

        function lazyLoadImgs() {
            for (var i = 0; i < imgArr.length; i++) {
                //Judge whether it is within the visible area
                if (isInVisibleArea(imgArr[i])) {
                    imgArr[i].src = imgArr[i].getAttribute('data-src');//use data-src Property fill to src Attribute
                    imgArr.splice(i, 1);//Exclude loaded pictures from the array
                    i--;//Array length reduction
                }
            }
        }

Full code:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <title>4.3 Resource load on demand and preload</title>
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/icons.css">
    <link rel="stylesheet" href="css/index.css">
    <script src="js/flexible.js"></script>
</head>
<body>
    <header class="header-container">
        <div class="navbar">
            <div class="navbar-left">
                <i class="iconfont icon-scan"></i>
            </div>
            <div class="navbar-center">
                <div class="searchBox">
                    <div class="searchBox-prepend">
                        <i class="iconfont icon-search"></i>
                    </div>
                    <input type="text" placeholder="Start of school season with propriety" class="searchBox-input">
                    <div class="searchBox-append">
                        <i class="iconfont icon-close"></i>
                    </div>
                </div>
            </div>
            <div class="navbar-right">
                <i class="iconfont icon-msg"></i>
            </div>
        </div>
    </header>

    <div class="main-container">
        <div class="slider-container">
            <img src="img/slider/1.jpg" alt="slider">
        </div>

        <nav class="nav-container">
            <ul class="nav">
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/1.png" alt="nav" class="nav-img">
                        <span class="nav-text">Group purchase</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/2.png" alt="nav" class="nav-img">
                        <span class="nav-text">One yuan purchase</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/3.png" alt="nav" class="nav-img">
                        <span class="nav-text">Coupon</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/4.png" alt="nav" class="nav-img">
                        <span class="nav-text">education</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/5.png" alt="nav" class="nav-img">
                        <span class="nav-text">travel</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/6.png" alt="nav" class="nav-img">
                        <span class="nav-text">Ordering online</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/7.png" alt="nav" class="nav-img">
                        <span class="nav-text">celebration</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/8.png" alt="nav" class="nav-img">
                        <span class="nav-text">Seckill</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/9.png" alt="nav" class="nav-img">
                        <span class="nav-text">auction</span>
                    </a>
                </li>
                <li class="nav-item">
                    <a href="###" class="nav-link">
                        <img src="img/nav/10.png" alt="nav" class="nav-img">
                        <span class="nav-text">service</span>
                    </a>
                </li>
            </ul>
        </nav>

        <div class="recommend-container">
            <ul class="recommend">
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/1.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">European style overall cabinet customization simple modern</p>
                        <p class="recommend-origPrice">
                            <del>¥2000.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">1000</strong></span>
                            <span class="recommend-count">985 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/2.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">SKYWORTH 55 inches 4 K Ultra HD HDR</p>
                        <p class="recommend-origPrice">
                            <del>¥2999.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">2299</strong></span>
                            <span class="recommend-count">63 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/3.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">[259 yuan] SUPOR 5 L Electric pressure cooker</p>
                        <p class="recommend-origPrice">
                            <del>¥799.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">299</strong></span>
                            <span class="recommend-count">1908 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/4.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">Gift bag of three squirrel nuts</p>
                        <p class="recommend-origPrice">
                            <del>¥125.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">108</strong></span>
                            <span class="recommend-count">9532 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/5.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">Blue moon laundry detergent 12jin</p>
                        <p class="recommend-origPrice">
                            <del>¥133.40</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">89.9</strong></span>
                            <span class="recommend-count">5399 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/6.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">Fulinmen sunflower corn oil</p>
                        <p class="recommend-origPrice">
                            <del>¥109.90</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">89.9</strong></span>
                            <span class="recommend-count">6294 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/7.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">TP-LINK Full Gigabit port dual frequency wireless router</p>
                        <p class="recommend-origPrice">
                            <del>¥179.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">169</strong></span>
                            <span class="recommend-count">4255 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/8.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">[Top 1800 minus 50] household high-pressure car washing machine</p>
                        <p class="recommend-origPrice">
                            <del>¥790.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">268</strong></span>
                            <span class="recommend-count">1599 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/9.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">Lucie, Germany rusch Mini Baby auxiliary food machine baby</p>
                        <p class="recommend-origPrice">
                            <del>¥898.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">159</strong></span>
                            <span class="recommend-count">881 Piece sold</span>
                        </p>
                    </a>
                </li>
                <li class="recommend-item">
                    <a href="###" class="recommend-link">
                        <p class="recommend-pic">
                            <img src="img/loading.gif" data-src="img/recommend/10.jpg" alt="recommend" class="recommend-img lazyload-img">
                        </p>
                        <p class="recommend-name">Shanghongzao 500 in Western Regions g*5 bag</p>
                        <p class="recommend-origPrice">
                            <del>¥89.00</del>
                        </p>
                        <p class="recommend-info">
                            <span class="recommend-price">¥<strong class="recommend-price-num">29.9</strong></span>
                            <span class="recommend-count">15049 Piece sold</span>
                        </p>
                    </a>
                </li>
            </ul>
        </div>

        <!-- Resource load on demand -->
        <div id="product" class="product" style="height: 500px; background-color: red; text-align: center; line-height: 500px; font-size: 2.5rem; color: #fff;">
            <img src="img/loading.gif" alt="">
        </div>
    </div>

    <div class="tabbar-container">
        <ul class="tabbar">
            <li class="tabbar-item tabbar-item-active">
                <a href="###" class="tabbar-link">
                    <i class="iconfont icon-home"></i>
                    <span>home page</span>
                </a>
            </li>
            <li class="tabbar-item">
                <a href="###" class="tabbar-link">
                    <i class="iconfont icon-category"></i>
                    <span>Classification page</span>
                </a>
            </li>
            <li class="tabbar-item">
                <a href="###" class="tabbar-link">
                    <i class="iconfont icon-cart"></i>
                    <span>Shopping Cart</span>
                </a>
            </li>
            <li class="tabbar-item">
                <a href="###" class="tabbar-link">
                    <i class="iconfont icon-personal"></i>
                    <span>Personal Center</span>
                </a>
            </li>
        </ul>
    </div>

    <script>
        // 1. On demand loading of pictures
        var lazyLoadClass = '.lazyload-img';
        //Array.prototype.slice.call()Class array to array
        var imgArr = Array.prototype.slice.call(document.querySelectorAll(lazyLoadClass));//Get a list of all the nodes that need to be loaded on demand, and turn to array

        console.log(imgArr);

        lazyLoadImgs();//Image load on initialization

        //Image loading every time you scroll
        var timer = null;
        window.addEventListener('scroll', function () {
            clearTimeout(timer);
            timer = setTimeout(function () {
                lazyLoadImgs();
            }, 100);
        }, false);

        function lazyLoadImgs() {
            for (var i = 0; i < imgArr.length; i++) {
                //Judge whether it is within the visible area
                if (isInVisibleArea(imgArr[i])) {
                    imgArr[i].src = imgArr[i].getAttribute('data-src');//use data-src Property fill to src Attribute
                    imgArr.splice(i, 1);//Exclude loaded pictures from the array
                    i--;//Array length reduction
                }
            }
        }

        // Is it in the page visual area
        function isInVisibleArea(el) {
            var rect = el.getBoundingClientRect();
            // rect.top Top of viewing area to top of object
            // rect.bottom  Bottom of visible area to bottom of object
            // rect.right Right side of visual area to right side of object
            // rect.left From the left side of the visible area to the left side of the object

            return rect.bottom > 0 && rect.top < window.innerHeight && rect.right > 0 && rect.left < window.innerWidth;
        }


    </script>
</body>
</html>

 

 

 

 

On demand loading of other resources

js/loadProduct.js
(function () {
    var product = document.getElementById('product');

    product.innerHTML = 'I load on demand';
})();

Add code in html:

        // 2. On demand loading of other content
        loadProduct();
        window.addEventListener('scroll', loadProduct, false);

        function loadProduct() {
            if (isInVisibleArea(document.getElementById('product'))) {
                var script = document.createElement('script');
                // script.src = 'js/loadProduct.js';
                //Use setTimeout In order to simulate network delay, there is no need to delay when going online
                setTimeout(function () {
                    script.src = 'js/loadProduct.js';
                }, 1000);
                document.body.appendChild(script);//load loadProduct.js

                window.removeEventListener('scroll', loadProduct, false);
            }
        }

 

 

 

Preload (load when idle, and then load when used)

Often used when browsing comics

        // 3. Picture preload
        var img = new Image();
        img.src = 'img/recommend/5.jpg';

 

(preloaded before scrolling)

 

Tags: Javascript Attribute Fragment JQuery

Posted on Tue, 17 Mar 2020 04:42:50 -0400 by Kibeth