JavaScript 總結幾個提高性能知識點

来源:http://www.cnblogs.com/ys-ys/archive/2016/01/14/5132013.html
-Advertisement-
Play Games

前段時間花時間看了大半的《High Performance JavaScript》這本書啊,然後就開始忙項目了,慶幸最忙的一周已經熬過去了。由於空不出時間,這個月寫的學習筆記也不多,忙完最苦X的一周,這兩天晚上也算是挑燈夜讀了...終於是在殘血之際將這本書shut down了...既然讀完了,總歸是...


前段時間花時間看了大半的《High Performance JavaScript》這本書啊,然後就開始忙項目了,慶幸最忙的一周已經熬過去了。由於空不出時間,這個月寫的學習筆記也不多,忙完最苦X的一周,這兩天晚上也算是挑燈夜讀了...終於是在殘血之際將這本書shut down了...

既然讀完了,總歸是要學到些什麼的。說說對這本書的看法先吧,整體的來說,內容還是不錯的,就是感覺有點老了(作為前端小白,也可能是自身水平有限,未能體會到其中真意)。看這本書的過程中也是寫了挺多代碼用以測試的,並且對本書提倡的寫法和原先大眾的寫法的執行分別進行了斷點跟蹤,對於能實際測出的問題進行理解,當然,下斷點跟著執行也看不出的那也沒辦法咯。對於書中的知識點,這裡只是簡單的整理出個人所推崇的一部分,當然~ 不喜勿噴。

針對js文件的載入位置

在HTML文件中,<script>標簽是可以加在<head>區域和<body>區域的。這裡鑒於JavaScript執行和UI渲染的單線程原因,如果js文件載入會阻塞後面對於頁面的解析過程,頁面會等到js文件完全載入並運行後才繼續執行該做的操作。那麼問題就來了,這樣可能會出現頁面空白or卡頓現象。作為一名前端開發,重要的不僅僅止於實現了需求,應該還有優質的用戶體驗。那麼我們就需要消除用戶枯燥的等待,針對這個問題,這裡有本獸想到的兩種解決方案:

1.  如果js文件沒有特殊要求指明需要在頁面渲染之前載入及編譯完成的,那麼選擇將js文件放到</body>標簽前(既所有的頁面所呈現內容的後面),css文件還是放到<head>區域(誰也不願意看一個佈局雜亂無章的頁面)。這樣做就能先讓用戶看到有佈局的頁面而不是空白頁了,那麼也會有人指出:那數據得通過js請求載入進來啊,怎麼辦呢?可以對數據的載入做排序,急需呈現的介面放前面執行,不是那麼需要的可以延後執行,同時做個簡單的載入動畫or提示。

2.  如果這些js文件有指明需要先執行了,才能更好的展示頁面內容,那麼就在第一個js或者頁面上先放個載入小動畫,可以一些有趣的或者萌萌的動畫場景。這樣也是能較好的避免用戶等待的無聊,說不定人家還對這個載入動畫更感興趣呢,這樣可提升項目的用戶體驗感。

最終推薦:將<script>標簽儘可能的放到</body>標簽前面載入,以提升用戶體驗。

針對js文件的合併
在很多團隊開發中,我們可能會將不同功能的代碼塊分別放置在不同的js文件中,以便於開發過程中眾人合作寫代碼會更加方便,畢竟只需要找對應文件夾或文件而不是在一個很長的文件中找一個方法。這確實是會提高團隊開發效率及新人加入後的更容易進行二次開發及維護。那麼將這個問題放到頁面性能里呢?這正是問題所在,在這本書中指出:Each HTTP request brings with it additional performance overhead,so downloading one single 100 KB file will be faster than downloading four 25 KB files.

下載1個100KB的文件比下載4個25KB的文件要快,而開發過程中區分開各個文件又有很大的好處,那麼合併這個問題也就放在開發完後再處理咯,相信這個操作大家都不會陌生吧,現在的前端工具這麼豐富,各位習慣用什麼壓縮就用什麼壓縮吧~
這裡簡單提出下,在載入文件方面還可以用到defer和async屬性,用於延遲載入和非同步載入,在現代瀏覽器中,大多數是已經支持defer屬性了,還沒習慣用這個額,也不知道具體會不會存在什麼問題。有興趣的朋友可自行google該知識點,這裡件簡單提下吧。

現在的框架也大多配合懶載入和按需載入了。

更快速的數據訪問

對於瀏覽器來說,一個標識符所處的位置越深,去讀寫他的速度也就越慢(對於這點,原型鏈亦是如此)。這個應該不難理解,簡單比喻就是:雜貨店離你家越遠,你去打醬油所花的時間就越長... 熊孩子,打個醬油那麼久,菜早燒焦了 -.-~

如果我們需要在當前函數內多次用到一個變數值,那麼我們可以用一個局部變數先將其存儲起來,案例如下:

  //修改前
  function showLi(){
      var i = 0;
      for(;i<document.getElementsByTagName("li").length;i++){    //一次訪問document
          console.log(i,document.getElementsByTagName("li")[i]);  //三次訪問document
      };
  };
  //修改後
  function showLi(){
      var li_s = document.getElementsByTagName("li");  //一次訪問document
      var i = 0;
      for(;i<li_s.length;i++){
          console.log(i,li_s[i]);  //三次訪問局部變數li_s
      };
  };

DOM操作的優化

眾所周知的,DOM操作遠比javascript的執行耗性能,雖然我們避免不了對DOM進行操作,但我們可以儘量去減少該操作對性能的消耗。

讓我們通過代碼解釋這個問題:

  function innerLi_s(){
      var i = 0;
      for(;i<20;i++){
          document.getElementById("Num").innerHTML="A"; //進行了20次迴圈,每次又有2次DOM元素訪問:一次讀取innerHTML的值,一次寫入值
      };
  };

針對以上方法進行一次改寫:

  function innerLi_s(){
      var content ="";
      var i = 0;
      for(;i<20;i++){
          content += "A";  //這裡只對js的變數迴圈了20次
      };
      document.getElementById("Num").innerHTML += content;  //這裡值進行了一次DOM操作,又分2次DOM訪問:一次讀取innerHTML的值,一次寫入值
  };

減少Dom的重繪重排版

元素佈局的改變或內容的增刪改或者瀏覽器視窗尺寸改變都將會導致重排,而字體顏色或者背景色的修改則將導致重繪。
對於類似以下代碼的操作,據說現代瀏覽器大多進行了優化(將其優化成1次重排版):

  //修改前
  var el = document.getElementById("div");
  el.style.borderLeft = "1px"; //1次重排版
  el.style.borderRight = "2px"; //又1次重排版
  el.style.padding = "5px"; //還有1次重排版
  //修改後
  var el = document.getElementById("div");
  el.style.cssText = "border-left:1px;border-right:2px;padding:5px"; //1次重排版

針對多重操作,以下三種方法也可以減少重排版和重繪的次數:

1.Dom先隱藏,操作後再顯示 2次重排 (臨時的display:none)

2.document.createDocumentFragment() 創建文檔片段處理,操作後追加到頁面 1次重排

3.var newDOM = oldDOM.cloneNode(true)創建Dom副本,修改副本後oldDOM.parentNode.replaceChild(newDOM,oldDOM)覆蓋原DOM 2次重排

迴圈的優化

這應該是較多人都知道的寫法了,簡單帶過即可(後面還是用代碼+註釋形式說明)~

  //修改前
  var i = 0;
  for(;i<arr.lengthli++){  //每次迴圈都需要獲取數組arr的length
      console.log(arr[i]);
  }
  //修改後
  var i = 0;
  var len = arr.length;  //獲取一次數組arr的length 
  for(;i<len;i++){
      console.log(arr[i]);
  }
  //or
  var i = arr.length;;
  for(;i;i--){
      console.log(arr[i]);
  }

合理利用二進位

如:對2取模,則偶數最低位是0,奇數最低位是0,與1進行位與操作的結果是0,奇數的最低位是1,與1進行位與操作的結果是1。

代碼如下:

  .odd{color:red}
  .even{color:yellow}
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>
  var i = 0;
  var lis = document.getElementsByTagName("li");
  var len = lis.length;
  for(;i<len;i++){
      if(i&1){
          lis[i].className = "even";
      } else{
          lis[i].className = "odd";
      }
  };

雖說現代瀏覽器都已經做的很好了,但是本獸覺得這是自己對代碼質量的一個追求。並且可能一個點或者兩個點不註意是不會產生多大性能影響,但是從多個點進行優化後,可能產生的就會是質的飛躍了~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文翻譯自modern effective C++,由於水平有限,故無法保證翻譯完全正確,歡迎指出錯誤。謝謝!矛盾的是,我們很容易就能創造出一個和std::shared_ptr類似的智能指針,但是,它們不參加被指向資源的共用所有權管理。換句話說,這是一個行為像std::shared_ptr,但卻不....
  • 轉載自:http://www.infoq.com/cn/articles/rethinking-mvc-mvvm 原文作者:唐巧被誤解的 MVCMVC 的歷史MVC,全稱是 Model View Controller,是模...
  • 摘要: 對於前端開發我們最重要的工作就是相容性,系統的相容性,瀏覽器的相容性等等。今天分享一個我在項目中封裝的判斷操作系統與瀏覽器的方法。操作系統:var os = (function() { var UserAgent = navigator.userAgent.toLowerCase()...
  • 設置頁面載入時滾動條自動滾到底的方法:jQuery:$(function(){ var h = $(document).height()-$(window).height(); $(document).scrollTop(h);});JavaScript:window.onload = func.....
  • 本文將教你一個很有用的技巧——如何使用 CSS 做到完全的垂直居中。我們都知道margin:0 auto;的樣式能讓元素水平居中,而margin: auto;卻不能做到垂直居中……直到現在。但是,請註意!想讓元素絕對居中,只需要聲明元素高度,並且附加以下樣式,就可以做到:12345.Absolute...
  • 現代Web設計技術允許開發者快速實現大多數瀏覽器支持的動畫。我想警告消息是很常見的,因為預設的JavaScript警告框的樣式往往(與你自己設計的漂亮樣式)很不協調很囧。這使開發者步入找出哪種解決方案能更好地實現更友好的用戶界面的道路。 在這個教程中我想解釋一下我們如何能把幾個將要出現在網頁上方.....
  • “我有一個好創意,就差一個CTO……” ,這是今年炒的比較火的一句話。“原生APP開發難度大,周期長,成本高,還沒上線市場已經被占領了。這個有沒有解決方案?”“APP版本迭代更新,都是企業的一道難關,沒有一個一勞永逸的解決方式嗎?”“一個Web開發者如何能快速適應移動互聯網時代,用HTML5開發出一...
  • 數字:JS只有一種數字類型,相當於double。(不知道為什麼,我每次打double輸入法都會出現逗比了三個字)NaN是一個數值,可以用isNaN(number)檢測NaNInfinity表示所有大於一個非常大的數值的值JS有一個對象Math,它包含一套作用於數字的方法。字元串:Js中所有字元都是U...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...