從這一篇文章入坑前端性能優化

前端性能優化的概念

  • web性能概述css

    Web 性能其實就是**頁面性能**,一個頁面的性能如何,與頁面是否能夠快速加載,是否容許用戶快速開始與之交互,滾動和動畫是否流暢等問題有關。
  • 爲何要進行性能優化呢?html

    在構建web站點的過程當中,任何一個細節都有可能影響網站的訪問速度,若是不瞭解性能優化知識,不少不利網站訪問速度的因素會造成累加,從而嚴重影響網站的性能,**致使網站訪問速度變慢,用戶體驗低下,最終致使用戶流失**。

# 一個例子引入爲何優化
當代前端有兩大驅動的開發模式,分別是以DOM爲驅動的傳統開發模式和以數據爲驅動的MVVM開發模式。
這裏就以DOM爲驅動的傳統開發模式來介紹吧,主要講解的是優化的必要性,這裏先不深刻探究前端優化的具體方面。前端

  • 話很少說,舉個例子:web

    <body>
     <div id="container"></div>
     <!-- script腳本放在最後面也是一種優化,這樣靜態頁面能夠立刻出來 -->
     <script>
         //由於一萬次輸出,一直加載不出頁面,js阻塞了。爲何?怎麼優化
        for (var count = 0; count < 1000; count++) {
               document
                  .getElementById('container')
                 .innerHTML += '<span>我是一個小測試</span>';
      }
     </script>
    </body>
  • 解釋一下這一段代碼
    這一段代碼在html的body裏寫了一個盒子div,其id爲container,下面使用script標籤寫了一段JavaScript代碼,這一段JavaScript代碼是一段DOM的操做,其要循環執行一萬次,document.getElementById('container').innerHTML += '<span>我是一個小測試</span>';

方法介紹(爲了還沒學習DOM的前端新人們):getElementById() 方法可返回對擁有指定 ID 的第一個對象的引用。
而innerHTML 屬性設置或返回表格行的開始和結束標籤之間的 HTML。
因此dom操做執行的就是獲取id爲container的那一段HTML,併爲其添加上一萬個<span>我是一個小測試</span>瀏覽器

得到下圖效果:
在這裏插入圖片描述性能優化

獲得一個充滿一萬個「我是一個小測試」的頁面dom

在這裏插入圖片描述

DOM操做下<span>我是一個小測試</span>也所有添加進了div盒子裏。
這段代碼要實現的是,在div盒子裏添加10000句話,因此寫了一個for循環,在for循環裏。進行DOM操做,找到節點,添加元素,進行一萬次,完美實現!前端優化

  • 但是你真的覺得能那麼輕易的出的來嗎?

確定出不來!
除非你電腦性能比個人好,並且就算能出來也很慢。前端性能

給大家看看真實效果!
在這裏插入圖片描述性能

不信能夠複製代碼,本身運行一遍~~

# 爲何會出現這樣的問題

## 簡單介紹頁面顯示

    • 頁面由三個文檔構成,HTML,CSS,和JavaScript腳本。
      渲染引擎內部的HTML解析器(HTMLParser)模塊,將 HTML 字節流轉換爲 DOM 結構。 造成了DOM樹,css解析執行 基於DOM樹 樹生成css渲染樹(CSSOM 樹) ,遍歷這顆渲染樹。因而出現了靜態頁面。
    • js做爲專爲瀏覽器設計的腳本語言,其的做用就算負責頁面的交互和操做頁面,就像上面 代碼的DOM操做,爲頁面添加了10000個span。

    代碼注意事項

    • HTML文檔執行時,是按照先後順序來執行的,上面代碼中,咱們把JavaScript代碼放到 了最後面也是一種優化,最後執行JavaScript代碼能把時間都讓給頁面渲染,讓用戶 先看到頁面,交互後產生。固然這裏放後面的主要緣由是:要對div盒子進行操做,首 先要有這個div盒子,要是JavaScript代碼放最前面先運行,這個時候div都尚未運 行出來,得到的結點對象都是空,何談加入10000個span。

    爲何會耗時

    咱們逐步分析

    • 主要耗時間的部分在JavaScript代碼上,JavaScript的下載和執行會阻塞用戶界面的繪製和其餘資源的下載,這裏有一個10000次的for循環,是由於10000次的for循環耗時致使頁面慢到出不來嗎?顯然不是,事實上就算是10000次的循環也能在1ms內進行完。
    • for循環裏的DOM操做,裏面有查找和修改DOM樹,這是個很是耗時的地方,操做DOM致使DOM樹結構或者幾何屬性(寬度,高度,間距等)發生了變化,就會觸發重排和重繪
    • DOM和JavaScript是2個獨立的功能,只經過API做爲橋樑鏈接,用JavaScript操做DOM時要兩頭跑一遍,這就很是耗時,再回頭看開頭代碼,在for循環裏查找了一萬次指定 ID 的對象,且還在DOM和JavaScript兩頭跑了一萬次,可想而知,最終頁面出現要花費多少時間!
    • 這裏得出,耗費時間的點在DOM的操做上,因此要在這方面進行優化。

      優化方案

      該怎麼優化呢?

      • DOM樹節點操做耗時,那就將其放出for循環,使其只進行一次。
    //查找元素,能夠先提出來,這樣就不用每次循環都查找一遍
    let oContainer=document.getElementById('container');
    for (var count = 0; count < 10000; count++) {
        oContainer.innerHTML += '<span>我是一個小測試</span>';
      }
    • span元素的寫入DOM樹也耗時間,在for循環裏要執行一萬次,那就將寫入DOM樹減小爲一次
    //查找元素,能夠先提出來,這樣就不用每次循環都查找一遍
    let oContainer=document.getElementById('container');
    let content='';
    for (var count = 0; count < 10000; count++) {
        content += '<span>我是一個小測試</span>';
      }
    //   寫入也放出來
    oContainer.innerHTML +=content;
    //這樣就秒出了,耗時間的DOM操做,從一萬次變到1次

    這時候,通過優化,輸出一萬個<span>我是一個小測試</span>的頁面就能快速的顯示了。

    擴展例子

    直接看代碼:

    <div id="container"></div>
        <script>
            //怎麼優化?這裏來回跑了4次
            let container=document.getElementById('container');
             container.style.width='100px';
             container.style.height='200px';
             container.style.border='10px solid red';
             container.style.color='red';
        </script>

    這該怎麼進行優化呢?
    將四次操做變爲一次
    知識點提示:cssText屬性批量操做樣式,classList 是一種更方便的訪問元素的類列表的方法

    • 解決方案一:
    // 方案一
         let container=document.getElementById('container');
        container.style.cssText = "width:100px; height: 200px;border:10px solid red;color:red";
    • 解決方案二:
    //方案二 
    <style>
            .reveal{
                width:100px; 
                height: 200px;
                border:10px solid red;
                color:red;
            }
        </style>
    </head>
    <body>
        <div id="container"></div>
        <script>
            let container=document.getElementById('container');
            //使用.reveal(把這一些個樣式先放到渲染樹上,而後直接啓用),只須要在js和DOM樹之間跑一遍就好了
            container.classList.add('reveal');//reveal只是個名字
            //使用classList.add
        </script>

    # 最後總結
    這裏只是淺談了前端性能的問題,具體的方面還有不少,須要多去了解學習,閱讀相關的書籍,例如高性能JavaScript,在進行開發時多注意本身的編碼方式,特別是前端新人們,編碼的同時注意性能。這是很是重要的。

    感謝閱讀,若有建議或不足的地方請在下面評論提出

    相關文章
    相關標籤/搜索