web前端優化-溫故知新系列(1)

来源:http://www.cnblogs.com/shouce/archive/2016/02/15/5189871.html
-Advertisement-
Play Games

出處:http://www.cnblogs.com/_popc 外話: 有關web前端優化的博文,博客園中有許多網友的博客中都有介紹,而且詳細、精準。樓主打算寫這個博客,算是對自己一年工作來的一個總結和積累有些知識從別的地方拷貝過來的,但是都審查過。 引言: 1. 慢的頁面可能會網站失去更多的用戶.


出處:http://www.cnblogs.com/_popc

外話:

有關web前端優化的博文,博客園中有許多網友的博客中都有介紹,而且詳細、精準。樓主打算寫這個博客,算是對自己一年工作來的一個總結和積累有些知識從別的地方拷貝過來的,但是都審查過。

引言:

1. 慢的頁面可能會網站失去更多的用戶.
2. 慢500ms意味著20%的用戶將放棄訪問(google)
3. 慢100ms意味著1%的用戶將放棄交易(amazon)

通過上面列舉的三個數據,可以看到web前端優化的重要性,而作為程式員,總有一股矯情勁,希望將自己開發出來的東西能更加的完美。:)

一.減少Http請求

一般來說,我們從變化性上把數據分成兩種類型,變和不變.那麼不變的數據可以緩存,變化的數據不能緩存,這是一個常識,也就是說要減少我們的http請求次數這個目標可以轉換成把數據分為變化和不變化兩個部分.不變化的數據不需要再次請求,這樣http請求的次數就減少了,下麵我們分點來描述將數據分類的途徑.

1,合併文件

包括腳本、樣式文件和圖片,可以有選擇的把一些Js和css可以合併成一個文件,一些圖片可以使用css sprites技術。這樣做的原因是什麼?做過web開發的人都知道,js和css基本是不變的,是靜態文件,圖片亦然。那麼不變的文件如果適當的合併在一起,會有什麼效果呢?請求的次數從多次變成了一次,這樣http請求的次數就減少了。其實對於js的合併更是尤為重要,我們知道瀏覽器對js的載入是阻塞式的。什麼意思呢,對於css和圖片之類的,瀏覽器大多支持並行載入,因為瀏覽器載入DOM樹時,檢測到會先預留一個節點,進而進行下麵的載入,而js中存在創建DOM節點的可能,所以載入js存在一個解析的過程。

2. 指定Expires或者Cache-Control

對於靜態內容:設置文件頭過期時間Expires的值為“Never expire”(永不過期) 

動態頁面,在代碼中添加cache-control,表示多少時間之後過期,如:
response.setHeader("Cache-Control", "max-age=3600");
如果使用了Expires文件頭,當頁面內容改變時就必須改變內容的文件名。通常是在文件內容後加版本號
這一點是大多數人都忽略得,之前很多人在罈子上發佈自己得小系統,還有demo,ahuaxuan跑過去一看,my god,一堆又一堆得js,css,既沒有恰當得合併,也沒有設置過期時間.每次刷新頁面都要重新下載這一堆又一堆的js,css.http請求那叫一個多啊.無謂了流量就這樣產生了.
這一點在企業應用的系統中也時有發生.比如我們使用extjs作為前端的技術,400多k啊,每打開一個頁面都導入,下載這個js,夠無聊的.那麼童子們可能就要問了,靜態文件為啥不用apache,lighttpd等呢,答,用了又怎麼樣,不設expire或者max-age不是一樣要下載,最好的方法是寫一個filter,再filter中判斷,如果url滿足一定的條件(比如符合配置文件中的正則表達式),那麼就設置一個max-age,這樣就ok,太簡單了,幾行代碼就可以搞定.快哉.

3. 緩存Ajax請求

緩存的方法同動態頁面,ajax請求需要使用get方式,url長度為2k(ie)限制(post請求有兩個過程,1發送請求headers,2發送請求數據,根據http規範,get請求只會發送一個tcp包).--------這一段話來自yahoo,先不管其真假,我們從另外一個方面來考慮一下為什麼最好使用get方式,講一個ahuaxuan經歷過的事情,之前有一個項目的ajax請求使用了post方式,後來發現經常出錯,而且拋出了squid的錯誤,因為我們的網站使用了squid,問題就出在這裡了,從http協議上可以瞭解到,method=post是指把數據提交到伺服器上去,那麼squid的一個特性是不會緩存post請求(事實上它確實不應該緩存,因為這樣會違反http協議中的語義),把ajax請求改成get方式之後,一切恢復如常.

4. 移除重覆的js

重覆的js導入也有可能導致ie重新載入該腳本 。

5. 避免重定向

有一種經常被網頁開發者忽略卻往往十分浪費響應時間的跳轉現象。這種現象發生在當URL本該有斜杠(/)卻被忽略掉時。這時候會返回一個301的狀態碼,然後瀏覽器重新發起一次請求.在企業應用里,重定向是我們在企業應用中常用的技術,不過用在網站項目上,您可要小心了,因為普通的重定向其實是server在response header中設置http status=302,瀏覽器收到之後,判斷出是302,會重新發送一個請求,目標地址是前一次返回中指定的地址.在網站項目中如果可以不用重定向就別用吧.如果您做企業應用項目,ok,關係不大,您就放心的”定”吧.
小節,減少http請求次數分為了以上5個小點,每個小點之後附加一些實例,大家可以根據這些點來判斷自己的項目是否可以有優化的地方.
使用cdn
讓內容更靠近用戶,這有啥好說呢,原理很簡單,就是根據用戶瀏覽器所在機器的ip來判斷哪些伺服器離用戶最近,瀏覽器會再次去請求這些最近的機器.一般的cdn服務商是通過開發自己的dns server來達到這個目的的.不過這個是通常情況哦,技術實力比較高,或者場景比較特殊的公司會開發自己的cdn.當然不管怎麼說,使用cdn肯定可以使頁面響應更快(也包括音頻,視頻,圖片,文本文件,等等等等)


二.減小返回數據的體積


1. 使用gzip壓縮返回數據

Gzip壓縮所有可能的文件類型是減少文件體積增加用戶體驗的簡單方法。比如本來400k的文件,壓縮一下之後只有50k-100k,那麼網路的流量就立刻下來了,壓縮的代價是伺服器端要壓縮文件,需要消耗cpu,瀏覽器需要解壓文件,也需要消耗cpu,不過對於現代這麼nb的pc,來說,瀏覽器解壓一下數據帶來的cpu消耗簡直不值一提.所以您就壓吧.不過壓的時候要小心哦,有的瀏覽器在特定場景下會出去一些小bug,導致頁面不正常.比如ie6在跨域的時候可能會有些小麻煩,把這部分數據的gzip去掉就可以了.

2. 最小化js文件和css文件

壓縮js可以使用JSMin或者YUICompressor,後者同時可以壓縮css,這個也沒啥好說的,照做吧.有關YUI Compressor 這個,可以瞭解下,樓主試用過,不錯。


3. 將css和js獨立成外部文件

其實這一點也可以看成是區分不變數據和變化數據.很多人喜歡在頁面上寫很多很多的js和css,這些數據其實都是不會變化的數據,也就是說這些數據也是可以緩存在瀏覽器上的,通過把它們獨立成外部文件,可以把這些數據緩存起來.這樣做看上去是增加的請求的次數,但是由於第一次請求之後該部分數據已經被緩存,所以第二次就無需再請求後端,減少了網路帶寬的開銷.

三.優化Cookie

1. 減小cookie體積

cookie是用於身份認證尤其是個性化等操作,它是在http的請求頭中進行交換的,它體積越大,則響應越慢;
每3000位元組的cookie在DSL的帶寬中會增加80毫秒的響應;所以除去不必要的cookie,已經使用短小的文件名和儘可能小的減少cookie的大小都有利於改善響應時間。

2. 合理設置Cookie域

由於二級功能變數名稱可以拿到一級功能變數名稱得cookie,那麼如果,而二級功能變數名稱之間確不能相互共用cookie,所以合理得設置cookie得功能變數名稱也可以避免無必要得帶寬浪費和響應速度得增加.

3. 設置合理的cookie過期時間

該過期就過期,不要讓不必要的數據一直帶在身上走來走去.

4. 使用域分離

為圖片或者其他靜態資源文件使用子域或者建立新的獨立功能變數名稱(申請新的功能變數名稱),避免無必要的cookie傳輸,當然也是要在有必要得情況下,圖片類網站肯定有必要,javaeye上得圖片並沒有使用域分離,所以我們得cookie其實會帶到罈子得圖片伺服器上去,每次請求圖片都是如此(不過還好,罈子里沒有什麼圖片,所以這方面的浪費不大).
小結,其實cookie上的問題,單次請求看上去也不是什麼大問題,好像是無所謂得事情,就那麼幾十個byte,至於嗎,不過大家都聽說過水滴石穿,繩鋸木斷的故事.所以該做的,我們還是要做,正所謂,勿以善小而不為,勿以惡小而為之.

四.優化瀏覽器載入

1. 將css放在頁面頂部載入

把樣式表放在文檔底部的問題是在包括Internet Explorer在內的很多瀏覽器中這會中止內容的有序呈現。瀏覽器中止呈現是為了避免樣式改變引起的頁面元素重繪。用戶不得不面對一個空白頁面。
HTML規範清 楚指出樣式表要放包含在頁面的<head />區域內:“和<a />不同,<link />只能出現在文檔的<head />區域內,儘管它可以多次使用它”。無論是引起白屏還是出現沒有樣式化的內容都不值得去嘗試。最好的方案就是按照HTML規範在文 檔<head />內載入你的樣式表。

2. 將js放在頁面底部載入

腳本帶來的問題就是它阻止了頁面的平行下載。HTTP/1.1 規範建議,瀏覽器每個主機名的並行下載內容不超過兩個。如果你的圖片放在多個主機名上,你可以在每個並行下載中同時下載2個以上的文件。但是當下載腳本時,瀏覽器就不會同時下載其它文件了,即便是主機名不相同。
Js放在底部載入其實並不影響瀏覽器展示頁面,除非用戶會在js載入完成之前就調用某個js方法,比如說頁面剛展現到一半,但是恰好這一半里有一部分是調用了還未下載的js,這個時候就會出問題了,如果童子們遇到這種情況,可以把這部分js先載入.

3.將js和CSS緩存瀏覽器中

如果可以的話,將這些CSS和js都緩存在本地瀏覽器中,因為這些都可以考慮為靜態文件。

 

五.優化js書寫

 1.字元串的拼接(使用join&push)

我們在很多地方用js輸出一段html片段時通常會使用如下代碼:

var _html = "";
    _html = "<div style='padding-bottom: 5px'>";
    _html += "<span class='icon_favorite' style='padding-top: 2px; padding-bottom: 2px'>這是js列印出來的</span>";    
     document.write(_html);

下麵看看用join如何書寫:

var _html = [];
var i = 0;
_html[i++] = "<div style='padding-bottom: 5px'>";
_html[i++] = "<span class='icon_favorite' style='padding-top: 2px; padding-bottom: 2px'>這是js列印出來的</span>";
document.write(_html.join(""));

 或者使用push:

 var _html = [];

_html.push("<div style='padding-bottom: 5px'>");
_html.push("<span class='icon_favorite' style='padding-top: 2px; padding-bottom: 2px'>這是js列印出來的</span>");
document.write(_html.join(""));

 樓主看web性能指南中有提到,這種寫法更高效。

 

2.for迴圈

低效率:

複製代碼
//效率低的
    function GetDivNum() {
        var divs = document.getElementsByTagName("div");
        var start = new Date().getTime();
        for (var i = 0; i < divs.length; i++) {
            //"效率低"
        }
        var end = new Date().getTime();
        alert("用時:" + (end - start) + "毫秒");
    } 
複製代碼

高效率:

複製代碼
 //效率高的
    function GetDivLen() {
        var divs = document.getElementsByTagName("div");
        var start = new Date().getTime();
        for (var i = 0, len = divs.length; i < len; i++) {
            //"效率高"
        }
        var end = new Date().getTime();
        alert("用時:" + (end - start) + "毫秒");
    }
複製代碼

原因:

     主要是因為for迴圈在執行中,第一種情況會每次都計算一下長度,而第二種情況卻是在開始的時候計算長度,並把其保存到一個變數中,所以其執行效率要高點,所以在我們使用for迴圈的時候,特別是需要計算長度的情況,我們應該開始將其保存到一個變數中。但是並不是只要是取長度都會出現如此明顯的差別,如果我們僅僅是操作一個數組,取得的是一個數組的長度,那麼其實兩種方式的寫法都差不多。這裡不再測試了。

 OK,先總結道這裡,下篇介紹前端優化結合後臺的一些操作,主要簡介如何實現js的合併以及壓縮輸出。


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

-Advertisement-
Play Games
更多相關文章
  • 最近在開發一個PHP程式時遇到了下麵的錯誤: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 錯誤信息顯示允許的最大記憶體已經耗盡。遇到這樣的錯誤起初讓我很詫異,但轉眼一想,也不奇怪,因為我正在開發的這個程式是要用
  • 1、varchar與char兩個數據類型用於存儲字元串長度小於255的字元,MySQL5.0之前是varchar支持最大255。比如向一個長度為40個字元的欄位中輸入一個為10個字元的數據。使用varchar取為10個字元;使用char取為40個字元。 2、varchar占用更少的存儲空間,擁有額外
  • 1、auto_increment用於主鍵自動增長。比如從1開始增長,當把第一條數據刪除,再插入第二條數據時,主鍵值為2,不是1。
  • 環境 硬體:Macbook pro Retina 13 系統:10.11.3 EI Capitan Xcode:7.0 Ps:配置剛剛夠用。 安裝包 官網地址:https://developer.xamarin.com Xamarin studio: https://developer.xamari...
  • ScriptManager和UpdatePanel控制項聯合使用可以實現頁面非同步局部更新的效果。其中的UpdatePanel就是設置頁面中異 步局部更新區域,它必須依賴於ScriptManager存在,因為ScriptManger控制項提供了客戶端腳本生成與管理UpdatePanel的功 能。幾個重要的
  • C#使用HWQPlayer類播放wav文件類的代碼: 1 using System.IO; 2 using System.Runtime.InteropServices; 3 4 namespace HoverTreeSound.HewenqiFrame 5 { 6 internal class H
  • 我總結了一下出現證書無法載入的原因有以下三個 1.證書密碼不正確,微信證書密碼就是商戶號 解決辦法:請檢查證書密碼是不是和商戶號一致 2.IIS設置錯誤,未載入用戶配置文件 解決辦法:找到網站使用的應用程式池-->右擊-->高級設置-->打開如下圖-->在載入用戶配置文件選擇true 3.如果以上兩
  • 自己寫的記錄日誌,定期刪除日誌的方法。 方法比較簡單,記錄一下吧。 /// <summary> /// 寫日誌 /// </summary> /// <param name="strMsg">內容</param> /// <param name="strPath">路徑(相對hycom下的文件夾路徑
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...