VB.net 2010 視頻教程 VB.net 2010 視頻教程 VB.net 2010 視頻教程
SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
當前位置:
魔兽世界wow > 網站開發 > JQuery >
  • JavaScript教程之前端性能優化的七大手段

  • 2019-04-27 14:59 來源:未知

前面的話

魔兽世界wow www.geyjm.icu   本文將詳細介紹前端性能優化的七大手段,包括減少請求數量、減小資源大小、優化網絡連接、優化資源加載、減少重繪回流、使用性能更好的API和構建優化

 

減少請求數量

【合并】

  如果不進行文件合并,有如下3個隱患

  1、文件與文件之間有插入的上行請求,增加了N-1個網絡延遲

  2、受丟包問題影響更嚴重

  3、經過代理服務器時可能會被斷開

  但是,文件合并本身也有自己的問題

  1、首屏渲染問題

  2、緩存失效問題

  所以,對于文件合并,有如下改進建議

  1、公共庫合并

  2、不同頁面單獨合并

【圖片處理】

  1、雪碧圖

  CSS雪碧圖是以前非常流行的技術,把網站上的一些圖片整合到一張單獨的圖片中,可以減少網站的HTTP請求數量,但是當整合圖片比較大時,一次加載比較慢。隨著字體圖片、SVG圖片的流行,該技術漸漸退出了歷史舞臺

  2、Base64

  將圖片的內容以Base64格式內嵌到HTML中,可以減少HTTP請求數量。但是,由于Base64編碼用8位字符表示信息中的6個位,所以編碼后大小大約比原始值擴大了 33%

  3、使用字體圖標來代替圖片

【減少重定向】

  盡量避免使用重定向,當頁面發生了重定向,就會延遲整個HTML文檔的傳輸。在HTML文檔到達之前,頁面中不會呈現任何東西,也沒有任何組件會被下載,降低了用戶體驗

  如果一定要使用重定向,如http重定向到https,要使用301永久重定向,而不是302臨時重定向。因為,如果使用302,則每一次訪問http,都會被重定向到https的頁面。而永久重定向,在第一次從http重定向到https之后 ,每次訪問http,會直接返回https的頁面

【使用緩存】

  使用cach-control或expires這類強緩存時,緩存不過期的情況下,不向服務器發送請求。強緩存過期時,會使用last-modified或etag這類協商緩存,向服務器發送請求,如果資源沒有變化,則服務器返回304響應,瀏覽器繼續從本地緩存加載資源;如果資源更新了,則服務器將更新后的資源發送到瀏覽器,并返回200響應

【不使用CSS @import】

  CSS的@import會造成額外的請求

【避免使用空的src和href】

  a標簽設置空的href,會重定向到當前的頁面地址

  form設置空的method,會提交表單到當前的頁面地址

 

減小資源大小

【壓縮】

  1、HTML壓縮

  HTML代碼壓縮就是壓縮在文本文件中有意義,但是在HTML中不顯示的字符,包括空格,制表符,換行符等

  2、CSS壓縮

  CSS壓縮包括無效代碼刪除與CSS語義合并

  3、JS壓縮與混亂

  JS壓縮與混亂包括無效字符及注釋的刪除、代碼語義的縮減和優化、降低代碼可讀性,實現代碼?;?/p>

  4、圖片壓縮

  針對真實圖片情況,舍棄一些相對無關緊要的色彩信息

【webp】

  在安卓下可以使用webp格式的圖片,它具有更優的圖像數據壓縮算法,能帶來更小的圖片體積,同等畫面質量下,體積比jpg、png少了25%以上,而且同時具備了無損和有損的壓縮模式、Alpha 透明以及動畫的特性

【開啟gzip】

  HTTP協議上的GZIP編碼是一種用來改進WEB應用程序性能的技術。大流量的WEB站點常常使用GZIP壓縮技術來讓用戶感受更快的速度。這一般是指WWW服務器中安裝的一個功能,當有人來訪問這個服務器中的網站時,服務器中的這個功能就將網頁內容壓縮后傳輸到來訪的電腦瀏覽器中顯示出來。一般對純文本內容可壓縮到原大小的40%

 

優化網絡連接

【使用CDN】

  CDN全稱是Content Delivery Network,即內容分發網絡,它能夠實時地根據網絡流量和各節點的連接、負載狀況以及到用戶的距離和響應時間等綜合信息將用戶的請求重新導向離用戶最近的服務節點上。其目的是使用戶可就近取得所需內容,解決 Internet網絡擁擠的狀況,提高用戶訪問網站的響應速度

【使用DNS預解析】

  當瀏覽器訪問一個域名的時候,需要解析一次DNS,獲得對應域名的ip地址。在解析過程中,按照瀏覽器緩存、系統緩存、路由器緩存、ISP(運營商)DNS緩存、根域名服務器、頂級域名服務器、主域名服務器的順序,逐步讀取緩存,直到拿到IP地址

  DNS Prefetch,即DNS預解析就是根據瀏覽器定義的規則,提前解析之后可能會用到的域名,使解析結果緩存到系統緩存中,縮短DNS解析時間,來提高網站的訪問速度

  方法是在 head 標簽里面寫上幾個 link 標簽

<link rel="dns-prefecth" href="https://www.google.com">
<link rel="dns-prefecth" href="https://www.google-analytics.com">

  對以上幾個網站提前解析 DNS,由于它是并行的,不會堵塞頁面渲染,這樣可以縮短資源加載的時間

【并行連接】

  由于在HTTP1.1協議下,chrome每個域名的最大并發數是6個。使用多個域名,可以增加并發數

【持久連接】

  使用keep-alive或presistent來建立持久連接,持久連接降低了時延和連接建立的開銷,將連接保持在已調諧狀態,而且減少了打開連接的潛在數量

【管道化連接】

  在HTTP2協議中,可以開啟管道化連接,即單條連接的多路復用,每條連接中并發傳輸多個資源,這里就不需要添加域名來增加并發數了

 

優化資源加載

【資源加載位置】

  通過優化資源加載位置,更改資源加載時機,使盡可能快地展示出頁面內容,盡可能快地使功能可用

  1、CSS文件放在head中,先外鏈,后本頁

  2、JS文件放在body底部,先外鏈,后本頁

  3、處理頁面、處理頁面布局的JS文件放在head中,如babel-polyfill.js文件、flexible.js文件

  4、body中間盡量不寫style標簽和script標簽

【資源加載時機】

  1、異步script標簽

  defer:  異步加載,在HTML解析完成后執行。defer的實際效果與將代碼放在body底部類似

  async: 異步加載,加載完成后立即執行

  2、??榘蔥杓釉?/p>

  在SPA等業務邏輯比較復雜的系統中,需要根據路由來加載當前頁面需要的業務???/p>

  按需加載,是一種很好的優化網頁或應用的方式。這種方式實際上是先把代碼在一些邏輯斷點處分離開,然后在一些代碼塊中完成某些操作后,立即引用或即將引用另外一些新的代碼塊。這樣加快了應用的初始加載速度,減輕了它的總體體積,因為某些代碼塊可能永遠不會被加載

  webpack 提供了兩個類似的技術,優先選擇的方式是使用符合 ECMAScript 提案 的 import() 語法。第二種則是使用 webpack 特定的 require.ensure

  3、使用資源預加載preload和資源預讀取prefetch

  preload讓瀏覽器提前加載指定資源,需要執行時再執行,可以加速本頁面的加載速度

  prefetch告訴瀏覽器加載下一頁面可能會用到的資源,可以加速下一個頁面的加載速度

  4、資源懶加載與資源預加載

  資源延遲加載也稱為懶加載,延遲加載資源或符合某些條件時才加載某些資源

  資源預加載是提前加載用戶所需的資源,保證良好的用戶體驗

  資源懶加載和資源預加載都是一種錯峰操作,在瀏覽器忙碌的時候不做操作,瀏覽器空間時,再加載資源,優化了網絡性能

  

減少重繪回流

【樣式設置】

  1、避免使用層級較深的選擇器,或其他一些復雜的選擇器,以提高CSS渲染效率

  2、避免使用CSS表達式,CSS表達式是動態設置CSS屬性的強大但危險方法,它的問題就在于計算頻率很快。不僅僅是在頁面顯示和縮放時,就是在頁面滾動、乃至移動鼠標時都會要重新計算一次

  3、元素適當地定義高度或最小高度,否則元素的動態內容載入時,會出現頁面元素的晃動或位置,造成回流

  4、給圖片設置尺寸。如果圖片不設置尺寸,首次載入時,占據空間會從0到完全出現,上下左右都可能位移,發生回流

  5、不要使用table布局,因為一個小改動可能會造成整個table重新布局。而且table渲染通常要3倍于同等元素時間

  6、能夠使用CSS實現的效果,盡量使用CSS而不使用JS實現

【渲染層】

  1、此外,將需要多次重繪的元素獨立為render layer渲染層,如設置absolute,可以減少重繪范圍

  2、對于一些進行動畫的元素,使用硬件渲染,從而避免重繪和回流

【DOM優化】

  1、緩存DOM

const div = document.getElementById('div')

  由于查詢DOM比較耗時,在同一個節點無需多次查詢的情況下,可以緩存DOM

  2、減少DOM深度及DOM數量

  HTML 中標簽元素越多,標簽的層級越深,瀏覽器解析DOM并繪制到瀏覽器中所花的時間就越長,所以應盡可能保持 DOM 元素簡潔和層級較少。

  3、批量操作DOM

  由于DOM操作比較耗時,且可能會造成回流,因此要避免頻繁操作DOM,可以批量操作DOM,先用字符串拼接完畢,再用innerHTML更新DOM

  4、批量操作CSS樣式

  通過切換class或者使用元素的style.csstext屬性去批量操作元素樣式

  5、在內存中操作DOM

  使用DocumentFragment對象,讓DOM操作發生在內存中,而不是頁面上

  6、DOM元素離線更新

  對DOM進行相關操作時,例、appendChild等都可以使用Document Fragment對象進行離線操作,帶元素“組裝”完成后再一次插入頁面,或者使用display:none 對元素隱藏,在元素“消失”后進行相關操作

  7、DOM讀寫分離

  瀏覽器具有惰性渲染機制,連接多次修改DOM可能只觸發瀏覽器的一次渲染。而如果修改DOM后,立即讀取DOM。為了保證讀取到正確的DOM值,會觸發瀏覽器的一次渲染。因此,修改DOM的操作要與訪問DOM分開進行

  8、事件代理

  事件代理是指將事件監聽器注冊在父級元素上,由于子元素的事件會通過事件冒泡的方式向上傳播到父節點,因此,可以由父節點的監聽函數統一處理多個子元素的事件

  利用事件代理,可以減少內存使用,提高性能及降低代碼復雜度

  9、防抖和節流

  使用函數節流(throttle)或函數去抖(debounce),限制某一個方法的頻繁觸發

  10、及時清理環境

  及時消除對象引用,清除定時器,清除事件監聽器,創建最小作用域變量,可以及時回收內存

 

性能更好的API

  1、用對選擇器

  選擇器的性能排序如下所示,盡量選擇性能更好的選擇器

復制代碼
id選擇器(#myid)
類選擇器(.myclassname)
標簽選擇器(div,h1,p)
相鄰選擇器(h1+p)
子選擇器(ul > li)
后代選擇器(li a)
通配符選擇器(*)
屬性選擇器(a[rel="external"])
偽類選擇器(a:hover,li:nth-child)
復制代碼

  2、使用requestAnimationFrame來替代setTimeout和setInterval

  希望在每一幀剛開始的時候對頁面進行更改,目前只有使用 requestAnimationFrame 能夠保證這一點。使用 setTimeout 或者 setInterval 來觸發更新頁面的函數,該函數可能在一幀的中間或者結束的時間點上調用,進而導致該幀后面需要進行的事情沒有完成,引發丟幀

  3、使用IntersectionObserver來實現圖片可視區域的懶加載

  傳統的做法中,需要使用scroll事件,并調用getBoundingClientRect方法,來實現可視區域的判斷,即使使用了函數節流,也會造成頁面回流。使用IntersectionObserver,則沒有上述問題

  4、使用web worker

  客戶端javascript一個基本的特性是單線程:比如,瀏覽器無法同時運行兩個事件處理程序,它也無法在一個事件處理程序運行的時候觸發一個計時器。Web Worker是HTML5提供的一個javascript多線程解決方案,可以將一些大計算量的代碼交由web Worker運行,從而避免阻塞用戶界面,在執行復雜計算和數據處理時,這個API非常有用

  但是,使用一些新的API的同時,也要注意其瀏覽器兼容性

 

webpack優化

【打包公共代碼】

  使用CommonsChunkPlugin插件,將公共??椴鴣隼?,最終合成的文件能夠在最開始的時候加載一次,便存到緩存中供后續使用。這會帶來速度上的提升,因為瀏覽器會迅速將公共的代碼從緩存中取出來,而不是每次訪問一個新頁面時,再去加載一個更大的文件

  webpack 4 將移除 CommonsChunkPlugin, 取而代之的是兩個新的配置項 optimization.splitChunks 和 optimization.runtimeChunk

  通過設置 optimization.splitChunks.chunks: "all" 來啟動默認的代碼分割配置項

【動態導入和按需加載】

  webpack提供了兩種技術通過??櫚哪諏饔美捶擲氪?,優先選擇的方式是,使用符合 ECMAScript 提案 的 import() 語法。第二種,則是使用 webpack 特定的 require.ensure

【剔除無用代碼】

  tree shaking 是一個術語,通常用于描述移除 JavaScript 上下文中的未引用代碼(dead-code)。它依賴于 ES2015 ??橄低持械木蔡峁固匭?,例如 import 和 export。這個術語和概念實際上是興起于 ES2015 ??櫬虬ぞ?rollup

  JS的tree shaking主要通過uglifyjs插件來完成,CSS的tree shaking主要通過purify CSS來實現的

【長緩存優化】

  1、將hash替換為chunkhash,這樣當chunk不變時,緩存依然有效

  2、使用Name而不是id

  每個 module.id 會基于默認的解析順序(resolve order)進行增量。也就是說,當解析順序發生變化,ID 也會隨之改變

  下面來使用兩個插件解決這個問題。第一個插件是 NamedModulesPlugin,將使用??櫚穆肪?,而不是數字標識符。雖然此插件有助于在開發過程中輸出結果的可讀性,然而執行時間會長一些。第二個選擇是使用 HashedModuleIdsPlugin,推薦用于生產環境構建

【公用代碼內聯】

  使用html-webpack-inline-chunk-plugin插件將mainfest.js內聯到html文件中

相關教程