移動端性能優化(JavaScript性能優化)

来源:https://www.cnblogs.com/chenyingying0/archive/2020/03/17/12511552.html
-Advertisement-
Play Games

JavaScript性能優化 DOM操作優化 查找DOM元素能用id就用id,是最高效的查找方法(還得看具體環境) document.getElementById('slider') 從document開始查找子元素效率不高,建議從具體父元素開始查找 減少元素查找的層級 var sliderItem ...


JavaScript性能優化

 

DOM操作優化

查找DOM元素能用id就用id,是最高效的查找方法(還得看具體環境)

document.getElementById('slider')

 

從document開始查找子元素效率不高,建議從具體父元素開始查找

減少元素查找的層級

            var sliderItemContainer = document.querySelector('.slider-item-container');//從DOM開始查找
            var sliderItemContainer = sliderEl.querySelector('.slider-item-container');//從具體元素開始查找

 

DOM操作完使用變數緩存,否則需要多次操作DOM就得多次獲取

            // 合理緩存DOM對象
            var sliderItemContainer = sliderEl.querySelector('.slider-item-container'),
                sliderItem = sliderItemContainer.querySelectorAll('.slider-item'),
                indicatorContainer = document.createElement('div');

 

在迴圈中操作字元串,最後再操作DOM;比每次迴圈操作DOM要好得多

不推薦

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

推薦

            // 減少操作DOM的次數
            var html="";
            for (var i = 0, num = sliderItem.length; i < num; i++) {
                html += '<span class="slider-indicator"></span>';
                }

                indicatorContainer.innerHTML=html ;
            }

也可以使用文檔碎片,因為還沒有被渲染呈現,因此迴圈中不涉及DOM渲染 

在迴圈外只創建一遍文檔碎片節點,在迴圈內克隆節點即可,傳入true可以帶內容一起拷貝

           var indicatorItemFragment = document.createDocumentFragment();//創建文檔片段
           var spanEl = document.createElement('span');

            // 減少操作DOM的次數
            for (var i = 0, num = sliderItem.length; i < num; i++) {
                var indicatorItem = spanEl.cloneNode(true);
                indicatorItem.className = 'slider-indicator';
                indicatorItemFragment.appendChild(indicatorItem);
            }

 

迴圈的長度也用變數保存下來,只在最初執行一次

不推薦

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

推薦

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

 

不要直接修改style,通過添加class修改 直接修改style,如果修改的內容多,需要多次操作DOM;另外會涉及重排和重繪 重排涉及元素的位置關係變化,重繪涉及到元素的顏色透明度等 重繪影響性能,重排比重繪更耗性能,因此需要減少重繪,避免重排 不推薦
                // 不要直接修改style,通過添加class修改
                if (i === activeIndex) {
                    indicatorItem.style.backgroundColor = '#007aff';
                    indicatorItem.style.opacity = 1;
                    // 重排 重繪
                }

推薦

                // 不要直接修改style,通過添加class修改
                if (i === activeIndex) {
                    indicatorItem.className += ' slider-indicator-active';
                }

 

事件的優化:

避免事件多次綁定,而且如果改變節點時還需要增加或解除綁定

避免遍歷節點,給每個元素都綁定事件

可以使用事件代理或者事件委托,給它們的父元素綁定一次事件即可(事件冒泡原理)

不推薦

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

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

        // 動態插入一個新節點
        var sliderIndicator = document.createElement('span');
        sliderIndicator.className = 'slider-indicator';
        sliderIndicatorContainer.appendChild(sliderIndicator);
        sliderIndicator.addEventListener('click', function () {
            console.log('click');
        }, false);

推薦

        // 使用事件代理,避免直接事件綁定
        // jQuery/Zepto
        $(sliderIndicatorContainer).on('click', '.slider-indicator', function () {});

        //原生js
        sliderIndicatorContainer.addEventListener('click', function (ev) {
            // console.log(ev.target);//ev.target獲取到當前點擊的元素
            if (ev.target && /(^|\s)slider\-indicator($|\s)/.test(ev.target.className)) {
                //正則判斷當前點擊的元素的className
                console.log('click');
            }
        }, false);

 

針對執行非常頻繁的事件,使用事件節流來稀釋

比如 scroll resize mousemove touchmove等事件

        // 事件節流
        // scroll resize mousemove touchmove
        var timer = null;
        window.addEventListener('scroll', function () {
            console.log('scroll');//不節流

            //100ms內有重覆執行,則取消前面的執行
            clearTimeout(timer);
            timer = setTimeout(function () {
                console.log('scroll');//節流
            }, 100);
            // ....
        }, false);

 

 

資源按需載入(懶載入,延遲載入)

將img的src屬性可以先放在data-src(自定義屬性)里,預設src里放一個統一的loading小圖標

給需要按需載入的圖片添加一個統一的類

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

獲取到所有需要按需載入的圖片節點,存入數組中

        var lazyLoadClass = '.lazyload-img';
        //Array.prototype.slice.call()類數組轉數組
        var imgArr = Array.prototype.slice.call(document.querySelectorAll(lazyLoadClass));//獲取到所有需要按需載入的節點列表,轉數組

        console.log(imgArr);

 

 初始化時和每次滾動時,都執行按需載入函數

        lazyLoadImgs();//初始化時執行圖片載入

        //每次滾動時也執行圖片載入
        var timer = null;
        window.addEventListener('scroll', function () {
            clearTimeout(timer);
            timer = setTimeout(function () {
                lazyLoadImgs();
            }, 100);
        }, false);

判斷元素是否在可視區內

        // 是否在頁面可視區內
        function isInVisibleArea(el) {
            var rect = el.getBoundingClientRect();
            // rect.top 可視區頂部到物體頂部
            // rect.bottom  可視區底部到物體底部
            // rect.right 可視區右邊到物體右邊
            // rect.left 可視區左邊到物體左邊

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

按需載入函數

        function lazyLoadImgs() {
            for (var i = 0; i < imgArr.length; i++) {
                //判斷是否在可視區範圍
                if (isInVisibleArea(imgArr[i])) {
                    imgArr[i].src = imgArr[i].getAttribute('data-src');//用data-src屬性填充到src屬性中
                    imgArr.splice(i, 1);//數組中剔除已經載入的圖片
                    i--;//數組長度減少
                }
            }
        }

完整代碼:

<!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 資源按需載入和預載入</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="開學季有禮,好貨5折起" 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">團購</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">一元購</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">優惠券</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">教育</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">旅行</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">線上訂餐</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">慶典</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">秒殺</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">拍賣</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">服務</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">歐派整體櫥櫃定製簡約現代</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件已售</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">創維55吋4K超高清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件已售</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元】蘇泊爾 5L電壓力鍋</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件已售</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">三隻松鼠堅果禮包</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件已售</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">藍月亮洗衣液12斤</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件已售</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">福臨門葵花玉米油</p>
                        <p class="recommend-origPrice">
                            <del
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • async async 是 ES7 才有的與非同步操作有關的關鍵字,和 Promise , Generator 有很大關聯的。 語法 async function name([param[, param[, ... param]]]) { statements } name: 函數名稱。 param: ...
  • ES6 新引入了 Generator 函數,可以通過 yield 關鍵字,把函數的執行流掛起,為改變執行流程提供了可能,從而為非同步編程提供解決方案。 基本用法 Generator 函數組成 Generator 有兩個區分於普通函數的部分: 一是在 function 後面,函數名之前有個 * ; 函數 ...
  • simple-mind-map插件可用於在 markdown 文檔中生成超高顏值的思維導圖,同時支持 markdown,json,txtmap和 mindmup等多種格式. ...
  • javascript中object.className=classname;通過className屬性設置或返回元素的class 屬性,作用為:1.獲取元素的class 屬性2. 為網頁內的某個元素指定一個css樣式來更改該元素的外觀 ...
  • <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>畫橢圓</title> <style> div{ width:200px; height:100px; background-color:#ffa500; border-radiu ...
  • 1 完整代碼下載 https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ 提取碼 3fzt (壓縮包名: 2020-3-14-demo.zip) 2 圖片展示: ...
  • 前端自學大概的路線圖 因為剛開始學習,沒有完整的前端知識體系,所以是大概的路線圖,希望大家可以幫我一起修改完善。 大致的思路是:1.先打好基礎,在學習框架。 基礎方面主要涉及到的語言是Html、CSS、JavaScript,如果在這三個裡面在挑基礎的話應該就是Html、CSS了。 所以,2.基礎知識 ...
  • 主要記錄以下幾點: 1、整體的佈局為採用 流式佈局(%) 或 彈性佈局(Flexbox); 2、字體大小、內外間距、dom元素尺寸等 ,使用rem單位; 3、可以配合css的calc()函數、單位vh、vw進行,個別情況可以考慮採用媒體查詢; ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...