前端開發性能優化方案

減小HTTP請求次數和請求大小

代碼優化
javascript

  • 有利於SEO
  • 有利於擴展維護
  • 有利於減小性能消耗
  • [JS代碼優化的108條建議] [雅虎CSS優化的36條建議] ...

DNS及HTTP通訊方式的優化

1.在JS中儘可能減小閉包的使用(緣由:閉包會產生不釋放的棧內存) A:循環給元素作事件綁定的時候,儘量的把後期須要的信息(例如索引)存儲到元素的自定義屬性上,而不是建立閉包存儲 B:能夠在最外層造成一個閉包,把一些後續須要的公共信息進行存儲,而不是每個方法都建立閉包(例如單例模式) C:儘量的手動釋放不被佔用的內存 ...css

2.儘可能合併CSS和JS文件(把須要引入的CSS合併爲一個,JS也是合併爲一個),原理是在減小HTTP請求次數,儘量的把合併後的代碼進行壓縮,減少HTTP請求資源的大小 A:webpack這種自動化構建工具,能夠幫咱們實現代碼的合併和壓縮(工程化開發) B:在移動開發(或者追求高性能的PC端開發[例如百度首頁]),若是CSS或者JS不是須要不少,咱們能夠選擇把css和js編程內嵌式(也就是代碼直接寫在HTML中)java

3.儘可能使用字體圖標或者SVG圖標,來代替傳統的PNG等格式的圖片(由於字體圖標等是矢量圖(基於代碼編寫出來的),放大不會變形,並且渲染速度快,相對比位圖要小一些)webpack

4.減小對DOM的操做(主要是減小DOM的重繪和迴流(重排))
A:關於重排的分離讀寫
B:使用文檔碎片或者字符串拼接作數據綁定(DOM的動態建立)ios

5.在JS中避免「嵌套循環」(這種會額外增長不少循環次數)和「死循環」(一旦遇到死循環瀏覽器就卡殼了)web

6.採用圖片的「懶加載」(延遲加載)
目的是爲了減小頁面「第一次加載」過程當中HTTP的請求次數,讓頁面打開速度變快
步驟:開始加載頁面的時候,全部的真實圖片都不去發送HTTP請求加載,而是給一張佔位的背景圖,當頁面加載完,而且圖片在可視區域內咱們再去作圖片加載express

7.利用瀏覽器和服務器端的緩存技術(304緩存),把一些不常常更新的靜態資源文件作緩存處理(例如:JS、CSS、靜態圖片等均可以作緩存) 原理是爲了減小HTTP請求大小,讓獲取速度更快編程

8.儘量使用事件委託(事件代理)來處理事件綁定的操做,減小DOM的頻繁操做,其中包括給每個DOM元素作事件綁定axios

9.儘可能減小CSS表達式的使用(expression)設計模式

#myDiv {
  position: absolute;
  width: 100px;
  height: 100px;
  left: expression(document.body.offsetWidth - 110 + "px");
  top: expression(document.body.offsetHeight - 110 + "px");
  background: red;
}
複製代碼

10.CSS選擇器解析規則是從右向左解析

.container .link a{
    先找到全部的A,再篩選是在.link樣式類中的,再次篩選是在.container樣式類中的... 先找到的是全部的A,操做起來是消耗性能的,咱們在使用CSS選擇器的時候儘量減小對標籤選擇器的使用
 }
複製代碼

11.CSS雪碧圖技術(css sprite / css 圖片精靈) 把全部相對較小資源圖片彙總到一張大圖上,後期咱們只須要把大圖加載下來,用背景定位的方式展現對應的小圖便可

.bg{
  background:url('xxx.png');
}
.box1{
   background-position:xx xx;
}
.box2{
   background-position:xx xx;
}

<div class='bg box1'></div>
複製代碼

13.減小對於COOKIE的使用(最主要的是減小本地COOKIE存儲內容的大小),由於客戶端操做COOKIE的時候,這些信息老是在客戶端和服務器端傳來傳去

14.頁面中的數據獲取採用異步編程和延遲分批加載
使用異步獲取數據,是爲了下降HTTP通道的堵塞,不會由於數據沒有請求回來耽誤下面信息的渲染,提升頁面的打開速度(咱們能夠這樣處理:須要動態綁定數據的區域先隱藏,等數據返回而且綁定完成後在讓其顯示)
延遲分批加載相似於圖片懶加載,是爲了減小第一次頁面加載時候的HTTP請求次數

15.頁面中出現音視頻標籤,咱們不讓頁面加載的時候就去加載這些資源(要否則頁面加載速度會變慢)(方案:只須要設置 preload='none' 便可),等待頁面加載完成,音視頻播放的時候咱們在去加載音視頻資源

16.在客戶端和服務器端進行信息交互的時候,對於多項數據咱們儘量基於JSON格式來進行傳送(JSON格式的數據處理方便,資源偏小)
==>相對於XML格式的傳輸纔會有這個優點

17.儘量實現JS的封裝(低耦合高內聚),減小頁面中的冗餘代碼(減小HTTP請求資源的大小)

20.CSS中設置定位後,最好使用Z-INDEX改變盒子的層級,讓全部的盒子不在相同的平面上,這樣後續處理的時候,性能有那麼一丟丟的提升

21.在基於AJAX的GET請求進行數據交互的時候,根據需求可讓其產生緩存(這個緩存不是304緩存),這樣下一次從相同地址獲取的數據是上一次緩存的數據(可是不多用,項目中通常刻意清除這個緩存的時候偏多)

22.儘可能減小對於filter濾鏡屬性的使用(這個屬性消耗性能較大一些)

23.在CSS導入的時候儘可能減小使用@import導入式,由於@import是同步操做,只有把這個對應的CSS導入,纔會向下加載,而link是異步操做

24.配置ETag(有點相似於304緩存)

25.使用window.requestAnimationFrame(JS中的幀動畫)代替傳統的定時器動畫

26.減小遞歸的使用,避免死遞歸,避免因爲遞歸致使的棧內存嵌套(建議使用尾遞歸)

27.避免使用iframe(不只很差管控樣式,並且至關於在A頁面中加載了其它頁面,消耗較大)

28.利用H5中提供的localstorage本地存儲或者是manifest離線緩存,作一些信息的本地存儲,下一次加載頁面的時候直接從本地獲取,減小HTTP請求次數

29.基於SCRIPT調取JS的時候,可已使用 defer或者async 來異步加載

重量級優化:作CDN加速(燒錢機器)

===額外技巧===

1.咱們通常都把CSS放到BODY上,把JS放到BODY下面(緣由:讓其先加載CSS在加載JS,先加載CSS是爲了保證頁面渲染的過程當中,元素是帶着樣式渲染的,而JS通常都是用來操做DOM元素的,須要等到元素加載完再操做)

2.能用CSS搞定的絕對不用JS,能用原生JS搞定的絕對不用插件,絕對不使用FLASH(除了音視頻的低版本瀏覽器播放)
=>CSS處理動畫等功能的性能優於JS,並且CSS中的transform變形還開起了硬件加速

3.JS中儘可能減小對EVAL的使用,由於JS合併壓縮的時候,可能出現因爲符號不完善,致使的代碼執行優先級錯亂問題,EVAL處理起來消耗的性能也是偏大一點的

4.使用keep-alive實現客戶端和服務器端的長鏈接

5.儘可能使用設計模式來管理咱們的代碼(單例、構造、Promise、發佈訂閱),方便後期的升級和維護

6.開啓服務器端的gzip壓縮(這個壓縮能夠有效減小請求資源文件的大小),其實客戶端的圖片等資源也是能夠進行壓縮的(可是對於24位的位圖,壓縮後可能會變模糊)

7.頁面中不要出現無效的連接(利於SEO優化),還有其它技巧:提升關鍵字曝光率、img須要加alt、設置meta標籤、標籤語義化...

8.避免使用with語句(很是耗性能)

============================================

知識點:AJAX

1.async javascript and xml 異步的JS和XML
在AJAX中的異步不是咱們理解的同步異步編程,而是泛指「局部刷新」,可是咱們在之後的AJAX請求中儘量使用異步獲取數據(由於異步數據獲取不會阻塞下面代碼的執行)

XML是一種文件格式(咱們能夠把HTML理解爲XML的一種):可擴展的標記語言,它的做用是用本身擴展的一些語義標籤來存儲一些數據和內容,這樣存儲的好處是清晰的展現出數據的結構

好久之前,AJAX剛剛興起的時候,客戶端從服務器端獲取數據,服務器爲了清晰的表達數據結構,都是返回XML格式的內容,當下,咱們獲取的數據通常都是JSON格式的內容,JSON相對於XML來講,也能清晰表達數據結構,並且訪問裏面數據的時候操做起來比XML更簡便(可是如今某些項目中,服務器返回給客戶端的數據不單純是數據,而是數據和須要展現的結構拼接好的結果(相似於咱們本身作的字符串拼接),換句話說,是服務器端把數據和結構拼接好返回給咱們,此時返回的數據格式通常都是XML格式的字符串)

2.AJAX操做

//=>建立AJAX實例:IE6中是不兼容的,使用的是new ActiveXObject來實現的
let xhr = new XMLHttpRequest();

//=>打開請求:發送請求以前的一些配置項
//1.HTTP METHOD 請求方式
// GET/DELETE/HEAD/OPTIONS/TRACE/CONNECT
// POST/PUT
//2.URL 向服務器端發送請求的API(Application Programming Interface)接口地址
//3.ASYNC 設置AJAX請求的同步異步,默認是異步(寫TRUE也是異步),FALSE是同步,項目中都使用異步編程,防止阻塞後續代碼執行
//4.USER-NAME/USER-PASS:用戶名密碼,通常不用
xhr.open([HTTP METHOD],[URL],[ASYNC],[USER-NAME],[USER-PASS]);

//=>3.事件監聽:通常監聽的都是 READY-STATE-CHANGE 事件(AJAX狀態改變事件),基於這個事件能夠獲取服務器返回的響應頭響應主體內容
xhr.onreadystatechange=()=>{
    if(xhr.readyState===4 && xhr.status===200){
       xhr.responseText;
    }
};

//=>4.發送AJAX請求:從這步開始,當前AJAX任務開始,若是AJAX是同步的,後續代碼不會執行,要等到AJAX狀態成功後在執行,反之異步不會
xhr.send([請求主體內容]);
複製代碼

3.關於HTTP請求方式的一點學習

全部的請求均可以給服務器端傳遞內容,也均可以從服務器端獲取內容
GET:從服務器端獲取數據(給的少拿的多)
POST:向服務器端推送數據(給的多拿的少)
DELETE:刪除服務器端的某些內容(通常是刪除一些文件)
PUT:向服務器上存放一些內容(通常也是存放文件)
HEAD:只想獲取服務器返回的響應頭信息,不要響應主體中的內容
OPTIONS:通常使用它向服務器發送一個探測性請求,若是服務器端返回的信息了,說明當前客戶端和服務器端創建了鏈接,咱們能夠繼續執行其它請求了(TRACE是幹這件事的,可是axios這個AJAX類庫在基於cross domain進行跨域請求的時候,就是先發送OPTIONS請求進行探測嘗試,若是能連通服務器,纔會繼續發送其它的請求)

4.GET VS POST

[傳遞給服務器信息的方式不同]
GET是基於URL地址「問號傳參」的方式把信息傳遞給服務器,POST是基於「請求主體」把信息傳遞給服務器

[GET]
  xhr.open('GET','/temp/list?xxx=xxx&xxx=xxx')

  [POST]
  xhr.send('xxx=xxx&xxx=xxx')
複製代碼

GET通常應用於拿(給服務器的會少一些),而POST給服務器的不少,若是POST是基於問號傳參方式來搞會出現一些問題:URL會拼接很長,瀏覽器對於URL的長度有有最大限度(谷歌8KB 火狐7KB IE2KB ...),超過的部分瀏覽器就把它截掉了
=>因此GET請求能夠基於URL傳參,而POST都是使用請求主體傳遞(請求主體理論上是沒有限制的,真實項目中咱們會本身作大小限制,防止上傳過大信息致使請求遲遲完不成)

[GET不安全,POST相對安全]

由於GET是基於「問號傳參」把信息傳遞給服務器的,容易被駭客進行URL劫持,POST是基於請求主體傳遞的,相對來講很差被劫持;因此登陸、註冊等涉及安全性的交互操做,咱們都應該用POST請求;

[GET會產生不可控制的緩存,POST不會]

不可控:不是想要就要,想不要就不要的,這是瀏覽器自主記憶的緩存,咱們沒法基於JS控制,真實項目中咱們都會把這個緩存幹掉 GET請求產生緩存是由於:連續屢次向相同的地址(而且傳遞的參數信息也是相同的)發送請求,瀏覽器會把以前獲取的數據從緩存中拿到返回,致使沒法獲取服務器最新的數據(POST不會)

解決方案:

xhr.open('GET',`/temp/list?lx=1000&_=${Math.random()}`); //=>保證每次請求的地址不徹底一致:在每一次請求的末尾追加一個隨機數便可(使用_做爲屬性名就是不想和其它的屬性名衝突)
複製代碼

5.AJAX狀態(READY-STATE)

  • 0 =>UNSENT 剛開始建立XHR,尚未發送
  • 1 =>OPENED 已經執行了OPEN這個操做
  • 2 =>HEADERS_RECEIVED 已經發送AJAX請求(AJAX任務開始),響應頭信息已經被客戶端接收了(響應頭中包含了:服務器的時間、返回的HTTP狀態碼...)
  • 3 =>LOADING 響應主體內容正在返回
  • 4 =>DONE 響應主體內容已經被客戶端接收

6.HTTP網絡狀態碼(STATUS)

根據狀態碼可以清楚的反映出當前交互的結果及緣由

  • 200 OK 成功(只能證實服務器成功返回信息了,可是信息不必定是你業務須要的)

  • 301 Moved Permanently 永久轉移(永久重定向) =>域名更改,訪問原始域名重定向到新的域名

  • 302 Move temporarily 臨時轉移(臨時重定向 =>307) =>網站如今是基於HTTPS協議運做的,若是訪問的是HTTP協議,會基於307重定向到HTTPS協議上 =>302通常用做服務器負載均衡:當一臺服務器達到最大併發數的時候,會把後續訪問的用戶臨時轉移到其它的服務器機組上處理 =>偶爾真實項目中會把全部的圖片放到單獨的服務器上「圖片處理服務器」,這樣減小主服務器的壓力,當用戶向主服務器訪問圖片的時候,主服務器都把它轉移到圖片服務器上處理

  • 304 Not Modified 設置緩存 =>對於不常常更新的資源文件,例如:CSS/JS/HTML/IMG等,服務器會結合客戶端設置304緩存,第一次加載過這些資源就緩存到客戶端了,下次再獲取的時候,是從緩存中獲取;若是資源更新了,服務器端會經過最後修改時間來強制讓客戶端從服務器從新拉取;基於CTRL+F5強制刷新頁面,304作的緩存就沒有用了。

  • 400 Bad Request 請求參數錯誤

  • 401 Unauthorized 無權限訪問

  • 404 Not Found 找不到資源(地址不存在)

  • 413 Request Entity Too Large 和服務器交互的內容資源超過服務器最大限制

  • 500 Internal Server Error 未知的服務器錯誤

  • 503 Service Unavailable 服務器超負荷

7.關於XHR的屬性和方法

xhr.response 響應主體內容

xhr.responseText

響應主體的內容是字符串(JSON或者XML格式字符串均可以) xhr.responseXML 響應主體的內容是XML文檔

xhr.status 返回的HTTP狀態碼
xhr.statusText 狀態碼的描述

xhr.timeout 設置請求超時的時間
xhr.withCredentials 是否容許跨域(FALSE)

xhr.abort() 強制中斷AJAX請求
xhr.getAllResponseHeaders() 獲取全部響應頭信息
xhr.getResponseHeader([key])
獲取KEY對應的響應頭信息,例如:xhr.getResponseHeader('date')就是在獲取響應有中的服務器時間

xhr.open() 打開URL請求 xhr.overrideMimeType() 重寫MIME類型 xhr.send() 發送AJAX請求 xhr.setRequestHeader() 設置請求頭

相關文章
相關標籤/搜索