網站性能優化你需知道的東西

来源:http://www.cnblogs.com/jiaoyu121/archive/2017/06/18/7045829.html
-Advertisement-
Play Games

本文提到的網站性能指網站的響應速度,這也符合絕大部分人對於網站性能的理解:訪問快速的網站性能好,反之,訪問速度越慢,則網站性能越差。本文總結的優化方法是巨集觀的工程層面的方法,並不包含微觀的語言語法層面的方法,例如,JS、CSS的語法優化,這一部分同樣影響網站的性能,但語言語法層面的優化更多的是取決於 ...


本文提到的網站性能指網站的響應速度,這也符合絕大部分人對於網站性能的理解:訪問快速的網站性能好,反之,訪問速度越慢,則網站性能越差。本文總結的優化方法是巨集觀的工程層面的方法,並不包含微觀的語言語法層面的方法,例如,JS、CSS的語法優化,這一部分同樣影響網站的性能,但語言語法層面的優化更多的是取決於開發人員的編程水平。

什麼樣的網站響應速度快呢?其實很容易想到,網站載入資源的速度越快,網站響應速度越快;網站需要載入的資源越少,網站響應速度越快。這就分別對應網站性能優化的兩大方向:資源緩存、資源合併壓縮。當瀏覽器完成資源的載入後,需要進一步解析資源,才能渲染出最終的網頁,所以,瀏覽器的解析機制也是網站性能優化的一個方向。各種優化方法都可以歸類到這三個大方向中。

1.資源緩存

1.1 使用CDN

將網站的靜態資源分離,如靜態HTML、圖片Image、樣式CSS、腳本JS等,把靜態資源部署到CDN中,可以明顯加快這部分資源的載入速度。

1.2 利用HTTP緩存機制

HTTP緩存會把瀏覽器載入過的資源緩存到本地,下次載入時,只要緩存的資源沒有過期,就可以直接使用本地的資源,減少了HTTP請求次數,加快了資源載入速度。具體做法是設置HTTP Header 中的Cache-Control參數。HTTP 1.0 中使用Pragma和Expires兩個參數進行緩存,不過早已不推薦使用。

2. 資源的合併壓縮

2.1 減少HTTP請求

用一個HTTP請求去載入一個10M的文件,和把這個文件拆分成1M的10個文件,用10個HTTP請求並行去載入,哪一種方式能更快完成載入?既然提到減少HTTP請求可以提高網站響應速度,那麼結論貌似應該是用一個HTTP請求的方式更快。其實正確的答案是:不一定!

我做了一個小實驗:有兩個html文件,index1.html和index2.html,index1.html中用1個<script>標簽載入一個2M的js文件bundle.js,index2.html中用6個<script>標簽分別載入bundle1.js, bundle2.js …… bundle6.js,這6個js文件由bundle.js平均拆分得到。分別請求index1.html和index2.html 10次,得到載入bundle.js的時間和載入bundle1.js 到 bundle6.js的時間(以最後一個js文件載入完成為結束時間),計算平均載入時間分別為:1.07s 和 1.87s。

實驗結論證明瞭,一個HTTTP請求載入一個合併後的資源文件,比多個HTTTP請求併發載入多個資源文件效率高。但結論只是針對平均載入時間而言,對於單次的比較,完全可能出現相反的結論,例如我的實驗過程中,單一HTTTP請求載入時間的最大值為2.36s,超過了第二種載入方式的平均時間1.87s。可能有些人會比較疑惑,為什麼並行的效率反而比串列的要低呢?其實,HTTP請求載入資源的瓶頸在帶寬,而不是請求的數量,在一個請求已經利用帶寬很充分的情況下,增加新的請求並不能減少整體的資源載入時間。

其實,減少HTTP請求來提高網站性能主要是基於以下2個原因:

1) HTTP連接的建立是比較耗時的,一般需要上百ms,每個HTTP請求還有一定的網路延時,需要的HTTP請求越多,這兩部分產生的耗時也就越多。當然,HTTP 1.1 對keep-alive的預設支持,可以實現連接的復用,很大程度上優化了這個問題。

2)每個HTTP請求都需要附帶額外的數據,比如請求和響應中的頭信息,Cookie信息。當請求的資源很小時,附帶的額外數據可能比實際的資源還大。

2.2 JS文件

合併壓縮JS文件,一方面JS文件數量減少,需要的HTTP請求數也就減少了;另一方面,壓縮JS文件可以極大地減小文件體積。可以使用webpack等Web構建工具對JS文件進行壓縮合併。

要註意,壓縮合併JS文件並不是要把所有的JS文件都打包到一個JS文件中。一般的做法是按照“基礎代碼”+“頁面代碼”分別打包。“基礎代碼”指各個頁面或路由(對單頁面而言)都要用到的通用代碼,“頁面代碼”是只在某個具體頁面或路由中才會用到的代碼。這樣就可以實現JS代碼按需載入,避免頁面首屏載入時,因為單一JS文件過大,而影響首屏顯示時間。對單頁面應用來說,還可以有一個vendor.js的文件,這個文件中的內容是一些用到頻率比較高的第三方庫(如ECharts等),但這些庫並不是每個路由都會用到的,所以並不會被打包到“基礎代碼”中。將這樣的第三方庫從各個路由頁面對應的JS文件中拆分,一是可以減少所有JS文件的整體大小,因為本來可能是A、B等多個文件都會包含的代碼,現在則只需要一份;二是vendor.js只需要被載入一次,後續打開其他路由時,就可以不需要再次載入這部分代碼了,起到了資源預載入的作用。

2.3 CSS文件

對CSS文件進行合併壓縮,基本原理和做法同JS文件。

2.4 圖片

1) 使用WebP格式的圖片。WebP是一種支持有損壓縮和無損壓縮的圖片文件格式,派生自圖像編碼格式 VP8。根據 Google 的測試,無損壓縮後的 WebP 比 PNG 文件少了 45% 的文件大小,即使這些 PNG 文件經過其他壓縮工具壓縮之後,WebP 還是可以減少 28% 的文件大小。

2)使用字體圖標IconFont。可以任意設置Icon圖形的大小和顏色(只能是單色,因為本質上是給字體設置顏色)。

3)使用CSS Sprites將多張圖片合併成一張,從而減少HTTP請求數量。

4)使用Base64直接把圖片編碼成字元串寫入CSS文件,也是從減少HTTP請求數量考慮。但需要註意,Base64編碼的圖片最好是小圖片(最好幾十位元組級別的),因為圖片經過Base64編碼後,一般會比原文件更大些。而且太長的Base64編碼字元串也會影響CSS的整體可讀性。

5)對於需要大量圖片的網站,應該把圖片資源單獨部署,並使用不同的功能變數名稱來訪問。因為圖片資源占帶寬很大,如果把圖片和其他資源部署到一臺伺服器或一個集群中,伺服器端的出口帶寬會受到很大影響。使用不同的功能變數名稱載入圖片資源,可以更好的利用瀏覽器並行下載的特性,因為瀏覽器對於一個功能變數名稱下的最大並行請求數是有限制的。

2.5 伺服器端開啟gzip

服務端開啟gzip壓縮,可以減少資源文件在網路傳輸過程中的體積大小。

3.瀏覽器載入、解析、渲染機制

瀏覽器的工作原理非常繁瑣和複雜,要想仔細瞭解,可以參考這篇經典的文章How browers work

結合文章和我自己實驗驗證,簡單來說的話,當瀏覽器載入一個HTML文件後,

1)會先將載入HTML中引用的所有外部資源(JS、CSS文件等)的請求放到一個隊列中,然後瀏覽器通過多個線程(具體由瀏覽器設置決定)併發載入這些資源。

2)緊接著對HTML進行自上而下的解析。

3)當解析到<script>標簽時,如果標簽內是內嵌到HTML中的JS代碼,會直接執行這部分代碼;如果標簽引用了外部的JS文件,且這個文件此時還沒有下載完成,解析過程會被阻塞,直到JS文件下載完成,然後解析執行JS代碼,之後才會繼續HTML的解析過程;如果標簽引用了外部的JS文件,但此時這個JS文件已經下載完成,則會直接執行這部分JS代碼,並不會阻塞HTML的解析(可以理解成此時JS代碼的執行本就屬於HTML解析這個<script>標簽的過程)。

4) 當解析到<link>標簽時,不管<link>中引用的外部CSS資源是否載入完成,都不會阻塞HTML繼續向下解析。

這裡有2個需要註意的地方:

1)因為JS的載入會阻塞HTML向下解析,所以多個JS文件中代碼的執行順序,是和他們在HTML中的位置順序保持一致的。例如HTML中,從上向下依次引入a.js, b.js, a.js的文件大小遠大於b.js,這樣b.js文件很可能先完成載入,但是並不會先於a.js中的代碼執行,因為在a.js載入、解析、並執行完成前,HTML的解析是處於阻塞的,b.js所在的<script>標簽自然也不會被解析執行。如果不希望載入外部JS文件阻塞HTML的解析,可以使用script標簽的defer或async屬性,這裡就不再展開。

2)所有引用的外部腳本或樣式文件,在HTML開始解析前,就已經加入到瀏覽器的請求隊列中,所以多個外部資源開始載入的起始時間一般不會相差很大,除非請求的外部資源數量很多,超過了瀏覽器的併發請求數。

基於瀏覽器工作原理的常用優化性能的方法有2個:

1)引用外部CSS文件的link標簽,一般會寫在<head>內,這是為了能儘早的使<body>內的元素獲取樣式,優化視覺顯示效果。

2)引用外部JS文件的script標簽,一般會寫在<body>底部,這是為了避免HTML的解析被阻塞,從而使頁面元素更快的顯示出來。需要註意,雖然script寫在<body>底部,但這不意味著<body>內的其他元素都解析完成後才開始載入這些JS文件,這些JS文件依然會在HTML開始解析前,就被加入到請求隊列中。

以上就是從資源緩存、資源合併壓縮和瀏覽器解析原理三個維度出發,常用的優化網站性能的實踐方法

 學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入學習交流群

343599877,我們一起學前端!


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

-Advertisement-
Play Games
更多相關文章
  • 題目背景 戰爭已經進入到緊要時間。你是運輸小隊長,正在率領運輸部隊向前線運送物資。運輸任務像做題一樣的無聊。你希望找些刺激,於是命令你計程車兵們到前方的一座獨木橋上欣賞風景,而你留在橋下欣賞士兵們。士兵們十分憤怒,因為這座獨木橋十分狹窄,只能容納一個人通過。假如有兩個人相向而行在橋上相遇,那麼他們兩個 ...
  • 把下麵的配置複製到 .m2/settings.xml配置文件中。 github地址:https://github.com/ae6623/Zebra/blob/master/maven-repo-settings-ali.xml 阿裡maven倉庫地址:http://maven.aliyun.com/ ...
  • 『設計模式』中有一個模式可以解釋特定的語法規則,它就是解釋器模式(Interpreter Pattern)。不同於常見的策略模式或者是工廠模式,解釋器模式在.NET或者JDK中並不常見,而且在業務上也很少會去解釋特定的語法,所以它並不被廣泛使用。一個解釋器可大可小,大可以是複雜的編譯器,小也可以是一 ...
  • 隊列 定義 :隊列是一種特殊的線性表,特殊之處在於它只允許在表的前端(head)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,隊列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。 按照隊列的定義,結合記憶體地址的理解,初始化隊列的時候,準備 和`rear ...
  • A 調用攝像頭拍照,自定義裁剪編輯頭像,頭像圖片色度調節B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速開發利器)+快速表單構建器 freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳本,處理類,service等完整模塊C 集成阿裡巴巴資料庫連接池 ...
  • css選擇器一個可以選擇樣式的工具, 這裡適用於無論是內部代碼還是外部引用 abc.css 這類型的文件. 基本選擇器*{ }就是一個簡單的*, 代表應用於全部. 不適合於個性化細緻化處理的頁面, 副作用是它會覆蓋原有的style, 不管好壞 *和繼承無關, 無論是否一級標簽,是否子標簽, 一律收到... ...
  • ES 2015/6 新增內容還是比較多的,這裡僅大綱性的列舉一下(不一定全面)這些特性。其實,每個點挖進去都會有很多學問在裡頭,本文旨在彙總,所以不對這些特性進行深層次的討論及研究。隨後有時間的話,在單獨寫幾篇博客對常用的點進行深挖,與大家進行深度交流。 ...
  • ::before與::after兩個偽元素其實是CSS3中的內容,然而實際上在CSS2中就已經有了這兩者的身影,只不過CSS2中是前面加一個冒號來表示(:before和:after)。今天主要講講這兩個偽元素該如何使用。 一、與普通元素一樣可以給其添加樣式 比如說我想在文字前面添加一個圖標,如果我用 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...