這份優化清單,你都做了嗎?

蘇南發表於2018-10-08

引言

大家好,這裡是@IT·平頭哥聯盟,我是首席填坑官——蘇南(South·Su),今天是國慶節的第二天,這個假期沒有外出(不要問我為什麼,自己腦補~?),前些天分享了一篇前端面試彙總的文章,有些同學在群裡問了其中的一些細節,其中大家最關心的效能優化這塊,今天整理了公司專案中的一些認為不錯的點,跟大家一起分享,如有理解錯誤,請糾正。

優化概括

1、 首先最基本的,CSS樣式表放在頁面頭部Head內且link鏈式引入,javascript放在底部body結束標籤前避免阻塞。

2、 js/html/css/圖片都做壓縮合並,圖片預載入、懶載入,也是老生常談了,在這裡推薦一個圖片無損極限壓縮的工具,能壓小60~80%左右,比較麻煩的是每次要手動操作——TinyPNG

3、 減少DOM元素數量,減少DOM的操作:

  • 減少 DOM 元素數量,合理利用:after、:before等偽類,避免頁面過深的層級巢狀;
  • 優化javascript效能,減少DOM操作次數(或集中操作),能有效規避頁面重繪/重排;
  • 如何才算少?抱歉,這個沒有辦法給出一個標準精確的答案,只能說盡可能去做優化,如資料分頁、首屏直出、按需載入等。

4、 靜態資源CDN分發:

  • CDN的意圖就是儘可能的減少資源在轉發、傳輸、鏈路抖動等情況下順利保障資訊的連貫性;
  • 通俗的講就是CDN系統能夠實時地根據網路流量和各節點的連線、負載狀況以及到使用者的距離和響應時間等綜合資訊將使用者的請求重新導向離使用者最近的服務節點上———曾經人們都說距離產生美,後來變了都說距離產生小三,在這裡距離產生的是使用者跑路了,所以足以說明CDN的重要性
  • CDN採用各節點快取的機制快取很嚴重,當我們專案的靜態資源(只是之前存放在cdn上的資源)修改後,如果CDN快取沒有做相應更新,則看到的還是舊的網頁,解決的辦法是重新整理快取,七牛雲、騰訊雲都可單獨針對某個檔案/目錄進行重新整理;
  • 廣告常說:XX酒雖好,可不要貪杯哦,CDN託管也是如此,合理使用:圖片、常用js元件、css重置樣式等,即不常改動的檔案即可走CDN,包括專案內的一些介紹頁;
  • img標籤要設定高寬,同樣這麼做它也能減少頁面重繪/重排,使用 WebP 格式圖片,它能對原圖(png)做到近98%壓縮,當然它也不是完美的:

WebP最初在2010年釋出,目標是減少檔案大小,支援無損、有失真壓縮,動態、靜態圖片,壓縮比率優於 GIF、JPEG、JPEG2000、PNG 等格式,非常適合用於網路等圖片傳輸,現在開始已經被越來越多的瀏覽器支援,當然 WebP 格式也有它的缺點,演算法相對其他格式更加複雜,會在節省流量資源的同時會佔用計算資源,對計算機造成更大的負擔,WebP支援的畫素最大數量是16383x16383。有失真壓縮的WebP僅支援8-bit的YUV4:2:0格式。而無失真壓縮(可逆壓縮)的WebP支援VP8L編碼與8-bit之ARGB色彩空間。又無論是有損或無失真壓縮皆支援Alpha透明通道、ICC色彩配置、XMP詮釋資料,更詳細支援說明:caniuse.com

優勢

  • 體積小幾乎可以毫不誇張的說,已經小的不能再小了;
  • 小而美的同時,還質量好,幾乎看不出來與原圖差別;
  • 曾經的動態圖gif、jpeg壓縮都會不清晰,但現在對它來說都是so easy~。

缺點/困難

  • 目前並不是所有瀏覽器都支援WebP,因此需要解決瀏覽器適配問題;
  • 對於已上線的專案,採用WebP需要替換大量圖片,工作量太大(不確定後臺程式是否能搞定)。

5、 域名拆分:

  • 什麼叫拆分域名?很多公司初始專案搭建,都只申請了一個域名,站點的所有內容(html/php/jsp、js、css、img等都放在一個域名下),域名拆分主要為了增加瀏覽器資源請求的並行度即併發問題,讓瀏覽器能同時發起更多的請求,也解決了請求預設攜帶的cookie問題,減少了資料傳輸位元組;
  • 如何拆分?以現在前後端分離式開發為例,建議分為三大類:
  • 前端類 - 專案業務本身的htm、css、js、圖示/片等;
  • 靜態類 - 即上述提到的CDN資源類;
  • 動態類 - 可歸為後端API介面類;

以下為各瀏覽器請求併發數,資料來源於chorme搜尋,珍愛生命,遠離某……?:

瀏覽器 HTTP/1.1 HTTP/1.0
Chrome 6 6
火狐 6 6
Safari 4 4
IE11 6 6
IE9 10 10
…… …… ……

6、 減少http請求次數

  • 是的,你沒有看錯,就是減少http請求次數,節省網路請求時間,但你可能又會問,前面不是讓拆分域名嗎??一個是部署拆分,一個是請求減少,沒毛病哦;
  • 首先我們來了解一下http的請求過程(簡單通俗的闡述一下):
  • DNS 域名解析 - 1. 拿出電話,找到某個接頭人的號碼;
  • 發起 TCP 的 3 次握手 - 2. 接通後暗號:A)、你好,你好,我是長江一號,請問能聽到嗎?B),你好,我是長江二號,能聽到你講話,你能聽到我說什麼嗎?A)、能聽到,我們開始講正事吧……;
  • 正常資料傳輸中…… - 3. 聊的很嗨;
  • 結束傳輸斷鏈的 4 次揮手 - 4. 聊完了,準備告別:A)、(可以是服務端,也可以是客戶端)該說的我都說完了,你自己看著辦吧;B)、好的我也說完了;B)、(B緊接著又跟A發了條資訊),再見;A)、然後A收到B的話,而B那邊已經放下手機掛了,A等了一下聽B沒有再說啥,也就掛了(掛個毛啊,婊子無情,戲子無義,陪你嘮嗑這麼久,都不給個好評~?);
  • 當然,現在的HTTP/2.0的處理有所不同,2.0過程還有TLS/SSL的處理,HTTP是超文字傳輸協議,資訊是明文傳輸,HTTPS則是具有安全性的SSL(Certificate Authority,申請證照)加密傳輸協議,HTTPS加密傳輸、身份認證的網路協議,內容傳輸經過完整性校驗、內容經過對稱加密,每個連線生成一個唯一的加密金鑰、第三方無法偽造服務端(客戶端)身份等眾多優勢,同時也有劣勢因為做的事情多了中間對接的次數同樣需要時間,這也是HTTPS更慢的根本原因。
  • 上兩圖吧,這樣大家看著清晰一些,但暫時只列了HTTP/1.0的,HTTP/2.0的圖下次有時間再補,是有一個大佬指點我的哦,說這樣看起來更騷氣,大家會更喜歡,哈哈~:

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享 - 三次握手

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享 - 四次揮手

結論:從上面的這個過程可以看出,每一次請求都這麼複雜,減少http的請求次數是不是很有必要呢??答案是肯定的,我們會以以下幾個維度來進行優化:

  • 合併 JS、CSS 檔案;
  • 圖片/圖示 sprites 合併,或使用iconfont字型圖示,或者SVG Sprites什麼是Svg Sprites?
  • 資源按需載入,即當前頁面用到什麼,就載入什麼,避免載入與當前頁面無關的事情,這一點現在的React/Vue/Angular等MVVM框架,基於webpack編譯打包工具,做的很好;
  • 前端資料的快取(如:一個列表頁,進入詳情,再返回,這個使用者的互動行為是很頻繁的,可以對列表的資料進度一個快取,不用每次返回都進行載入,比如5分鐘更新一次。

7、 資料設定快取,好累寫不動了,http快取的設定,之前的面試彙總?如何設定http快取?吧; 8、 站點服務端開啟Gzip壓縮,當然還可以瞭解一下Brotli 或 Zopfli ,據說 Brotli 比 Gzip 和 Deflate更有效,有興趣的同學可以瞭解一下;

9、 避免重定向,儘量減少 iframe 使用,它會阻塞主頁面的渲染;

10、 避免使用CSS Expression(css表示式)又稱Dynamic properties(動態屬性);

11、 合理使用dns-prefetch、prefetch、 preload、 defer、async:

  • dns-prefetch:使用dns-prefetch對專案中用到的域名進行 DNS 預解析,減少 DNS 查詢,如: ;BAT各大巨頭都是這麼幹的,請看下圖,dns的詳細解析過程今天先不講了,碼字碼不動了,寫分享比加班做專案還累,望體諒~;
  • prefetch: 它是一個優先順序非常低的資源載入標識,瀏覽器會在空閒時(即主程式資源載入完成後)下載帶有 prefetch標識的資源並快取到disk,在後續模組使用到這個檔案的時候,會直接從快取讀取;該功能webpack有個外掛,配置後編譯能自動插入到頁面上;
  • preload:沒錯,它就是一個可以預載入資源的屬性,詳細說明請看官方API,一般情況下我們可能會對接下來的業務需要的audio、img、font、script等資源進行預先載入(甚至是下一個路由頁面哦),這樣能達到0秒開啟頁面的效果!
  • 暫時就想到這麼多了,歡迎補充……

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享 - 阿里巴巴的天貓首頁
本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享 - 京東首頁
本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享

總結:

  • 推薦幾個工具:WebPagetestLighthouseSpeedCurveNew Relic 等主動/被動監測工具,都能高效幫助我們分析發現問題的所在,從而對症下藥;
  • DNS預解析的是非重要的,它是一個url到解析IP,到查詢根伺服器的一個過程,可能會在下一次單獨總結出來分享,有興趣的同學也可以自行先了解一下,
  • 要把一個專案做好,每一個細節都很重要,希望今天的分享能給大家的工作帶來些許幫助,謝謝!

本文由@IT·平頭哥聯盟-首席填坑官∙蘇南 分享,曾想仗劍天涯 後來BUG太多沒去

文章分享計劃:

  最近一直在思考,如何有規化的分享工作中的積累,國慶這些天也一直看了很多大神寫的部落格,最後綜合自身的能力及時間,決定先嚐試寫一個# 動畫 #系列文章,動畫可能主要包含(CSS/Canvas)兩部分,歡迎大家持續關注!
  以上就是今天的分享,新手上路中,我會努力讓自己變得更優秀、寫出更好的文章,文章中有不對之處,煩請各位大神斧正。如果你覺得這篇文章對你有所幫助,請記得點贊或關注我們公眾號哦~。

寶劍鋒從磨礪出,梅花香自苦寒來,做有溫度的攻城獅!本文由@IT·平頭哥聯盟-首席填坑官∙蘇南分享,@IT·平頭哥聯盟 主要分享前端、測試 等領域的積累,文章來源於(自己/群友)工作中積累的經驗、填過的坑,希望能盡綿薄之力 助其他同學少走一些彎路,梅斌的專欄,首席填坑官∙蘇南的專欄,公眾號:honeyBadger8

作者:蘇南 - 首席填坑官

交流群:912594095,公眾號:honeyBadger8

本文原創,著作權歸作者所有。商業轉載請聯絡@IT·平頭哥聯盟獲得授權,非商業轉載請註明原連結及出處。

相關文章