前端性能優化之靜態資源優化

靜態資源優化

圖片格式 和 應用場景介紹

JPEG

聯合圖像裝甲小組是一種針對彩色照片而廣泛使用的有損壓縮圖形格式

  • 介紹:柵格圖形。常用文件擴展名爲.jpg,也有.jpeg.jpeJPEG在互聯網上常被應用於存儲和傳輸照片
  • 不合適:線條圖形和文字、圖標圖形,因爲它的壓縮算法不太這些類型的圖形;並且不支持透明度
  • 非常合適:顏色豐富的照片、彩色圖、大焦點圖、通欄bnner圖‘(一般是放在導航下面的一張大圖)構不規則的圖形

PNG

便攜式網絡圖形是一種無損壓縮的位圖圖形格式,支持索引、灰度、RGB三種顏色方案以及Alpha通道等特性。

  • 介紹:柵格圖形。PNG最初是作爲替代GIF來設計的,能夠顯示256色,文件比JPEG 或者GIF大,但是PNG非常好的保留了圖像質量。支持Alpha通道的半透明和透明特性。 最高支持24位彩色圖像(PNG-24 )和8位灰度圖像(PNG-8 )。
  • 不適合:由於是無損存儲,彩色圖像體積太大,所以不太適合。
  • 非常適合:純色、透明、線條繪圖,圖標;邊緣清晰、有大塊相同顏色區域二顏色數較少但需要半透明。

GIF

圖像互換格式是一種位圖圖形文件格式,以8位色(即256種顏色)重現真彩色的
圖像,採用LZW壓縮算法進行編碼。

  • 柵格圖形。支持256色;僅支持完全透明和完全不透明;如果需要比較通用的動 畫,GIF是唯一選擇。
  • 不適合:每個像素只有8比特,不適合存儲彩色圖片。
  • 非常合適:動畫、圖標

Webp

Webp是一種現代圖像格式,可爲圖像提供無損壓縮和有損壓縮,這使得它非常靈 活。由Google在購買On2 Technologies後發展出來,以BSD授權條款發佈。

  • 介紹:優秀算法能同時保證一定程序上的圖像質量和比較小的體積;可以插入多幀,實現動畫效果;可以設置透明度;採用8位壓縮算法。無損的Webp比PNG小26%,有損的Webp比JPEG小25-34%,比GIF有更好的動畫。
  • 不合適:最多處理256色,不適合於彩色圖片。
  • 非常合適:適用於圖形和半透明圖像。

用工具進行圖片壓縮

壓縮 png
  • node-pngquant-native
  • 跨平臺,壓縮比高,壓縮 png24非常好
  • 說明文檔:https://www.npmjs.com/package/node-pngquant-native
  • 安裝:npm install -g node-pngquant-native

壓縮jpg

  • jpegtran
  • 跨平臺,有LinuxMacWindows得解決方案
  • 官網:http://jpegclub.org/jpegtran.exe
  • 安裝方法:npm install -g jpegtran
  • 使用方法:jpegtran -copy none -optimize -outfile out.jpg in.jpg
壓縮gif
  • Gifsicle:通過改變每幀比例,減少GIF文件大小,同時可以使用透明來達到更小得文件大小,是目前公認得解決方案
  • 安裝:http://www.lcdf.org/gifsicle/
  • 使用方法:
    • 優化級別設置爲不小於 2 , 1 得話 基本不壓縮 gifsicle --optimize=3 -o out.gif in .gif
    • 將透明部分截去 gifsicle --optimize=3 -crop-transparency -o out.gif in .gif

圖片尺寸隨網絡環境變化

  • 不同網絡環境 wifi / 4G / 3G,加載不同尺寸和像素的圖片,通過在圖片 URL後綴加不同參數改變

響應式圖片

  • JavaScript綁定事件檢測窗口大小

  • CSS媒體查詢

  • @media screen and (max-width:640px){
    	image{
    		width:640px
    	}
    }
    
  • img 標籤屬性

  • <img srcset="img-320w.jpg,img-640w.jpg 2x,img-960w.jpg 3x" src="img-960w.jpg" alt="img">
    //x 描述符:表示圖像得設備像素比
    

逐步加載圖像

  • 使用統一佔位符

  • 使用LQIP

    • 低質量圖像佔位符
    • 安裝 : npm i lqip
    • 源碼: http://www.github.com/zouhir/lqip-loader
  • 使用SQIP

    • 基於svg得圖像佔位符
    • 安裝:npm i sqip
    • 源碼:https://github.com/axe312ger/sqip
  • Web Font代替圖片

  • 使用Data URL代替圖片

  • 採用Image Spriting(雪碧圖)

圖片服務器自動優化解密

  • 名詞解釋
    • 圖片服務器自動化優化是可以在圖片URL鏈接上增加不同特殊參數,服務端自動化生成
    • 不同格式、大小、質量得圖片
  • 處理方式
    • 圖片裁剪:按長邊、短邊、填充、拉伸等縮放
    • 圖片格式轉換:支持JPGGIFWebP等,支持不同得圖片壓縮率
    • 圖片處理:添加圖片水印、高斯模糊、重心處理、裁剪邊框等
    • AI能力:鑑黃以及智能摳圖、智能排版、智能配色、智能合成等AI功能

精簡HTML代碼

  • 減少html得嵌套
  • 減少dom節點數
  • 減少無語義代碼【比如:<div class="clear"></div> 清除浮動】
  • 刪除https 或者http,如果url得協議頭和當前得協議頭是一致得,或者此URL在多個協議頭都是可用得,可以考慮刪除協議頭
  • 刪除多餘得空格、換行符、縮進和不必要得註釋
  • 省略冗餘標籤和屬性
  • 使用相對路徑得URL

文件放在合適位置

  • css樣式文件鏈接儘量放在頁面頭部
    • css加載不會阻塞DOM tree解析,但是會阻塞DOM Tree渲染,也會阻塞後面js執行。任何body元素之前,可確保在文檔部分中解析了所有css樣式(內聯和外聯),從而減少瀏覽器必須重排文檔得次數。如果放置頁面底部,就要等待最後一個css文件下載完成,此時會出現“白屏”,影響用戶體驗
  • JS引用放在HTML底部
    • 防止JS的加載、解析、執行對阻塞頁面後續元素的正常渲染

增強用戶體驗

  • 設置favicon.ico

    • 網站如果不設置favicon.ico,控制檯會報錯,另外頁面加載過程中也沒有圖標loading過程,同時也不利於記憶網站品牌,建議統一添加
  • 增加首屏必要的cssjs

    • 頁面如果需要等待所依賴的jscss加載完成才顯示,則在渲染過程中頁面會一致顯示空白,影響用戶體驗,建議增加首屏必要的cssjs,比如頁面框架背景圖片或者loading圖標,內斂在html頁面中。這樣做,首屏能快速顯示出來,相對減少用戶對頁面加載等待過程。

提升css渲染性能

  • 謹慎使用expensive屬性

    • 如:nth-child僞類;position:fixed定位
  • 儘量減少樣式層級數

    • div ul li span i {color:blue}
  • 儘量避免使用佔用過多cpu 和內存的屬性

  • text-indent:-999px text-indent 屬性規定文本塊中首行文本的縮進。

  • 儘量避免使用耗電量大的屬性

    • css3 3D transforms 、 css3 transitions Opacity
    • transforms 會開啓硬件加速

    Tips:爲什麼CSS選擇器是從右向左匹配的?

    CSS中更多的選擇器是不會匹配的,所以在考慮性能問題時,需要考慮的是如何在選擇器不匹配時提升效率。從右向左匹配就是爲了達成這一目的的,通過這一策略能夠使得CSS選擇器在不匹配的時候效率更高。這樣想來,在匹配時多耗費一些性能也能夠想的通了。

合適使用css選擇器

  • 儘量避免使用css表達式
    • 比如隔行變色
  • 儘量避免使用通配選擇器
    • body > a {font-weight:blod}
  • 儘量避免類正則的屬性選擇器
    • *= |= ^= $=

提升css文件加載性能

  • 使用外鏈的css
  • 儘量避免使用 @import

精簡css代碼

  • 使用縮寫語句
  • 刪除不必要的 0
  • 刪除不必要的單位
  • 刪除過多分號
  • 刪除空格和註釋
  • 儘量減少樣式表的大小

合理使用Web Fonts

  • 將字體部署到cdn
  • 將字體以base64性時保存在css中並通過localStorage進行緩存
  • Google字體庫因爲一些原因,應該使用國內託管服務

css動畫優化

  • 儘量避免同時動畫
  • 延遲動畫初始化
  • 結合SVG

JS優化總體原則

  • 當需要時才優化
  • 考慮可維護性

提升js文件加載性能

  • 加載元素的順序css文件放在<head>裏,js文件放在<body>裏或者之後

js變量和函數優化

  • 儘量使用id選擇器,因爲這樣最快
  • 儘量避免使用eval
  • js函數儘可能保持簡潔
  • 使用事件節流函數
  • 使用事件委託

JS動畫優化

  • 避免添加大量JS動畫
  • 儘量使用CSS3動畫
  • 儘量使用Canvas動畫
  • 合理使用requestAnimationFrame動畫代替setTimeoutsetInterval
    • requestAnimationFrame可以在正確的時間進行渲染,setTimeout(callback)setInterval(callback)無法保證(callback)回調函數的執行時機
      • setTimeout相比,requestAnimationFrame最大的優勢是**由系統來決定回調函數的執行時機。**具體一點講,如果屏幕刷新率是60Hz,那麼回調函數就每16.7ms被執行一次,如果刷新率是75Hz,那麼這個時間間隔就變成了1000/75=13.3ms,換句話說就是,requestAnimationFrame的步伐跟着系統的刷新步伐走。它能保證回調函數在屏幕每一次的刷新間隔中只被執行一次,這樣就不會引起丟幀現象,也不會導致動畫出現卡頓的問題。

合理使用緩存

  • 合理緩存DOM對象
  • 緩存列表長度
  • 使用可緩存的Ajax

Cookie

  • 通常由瀏覽器存儲,然後將Cookie與每個後續請求一起發送到同意服務器。收到HTTP請求時,服務器可以發送帶有Cookieheader頭。可以給Cookie設置有效時間
  • 應用於:
    • 會話管理:登錄名,購物車商品,遊戲得分或服務器應要記錄的其他任何內容
    • 個性化:用戶首選項,主題或其他設置
    • 跟蹤:記錄和分析用戶行爲,比如埋點,【谷歌分析】

sessionStorage

  • 創建一個本地存儲的鍵 / 值對
  • 應用於:
    • 頁面應用之間傳值

IndexedDB

  • 索引數據庫
  • 應用於:
    • 客戶端存儲大量結構化數據
    • 沒有網絡連接的情況下使用(比如Google Doc、石墨文檔等在線文檔)
    • 將冗餘、很少修改、但經常訪問得數據,以避免隨時從服務器獲取數據

LocalStorage

  • 本地存儲
  • 應用於:
    • 緩存靜態內容js / CSS(比如百度M站首頁)
    • 緩存不常變更得API接口數據
    • 儲存地理位置信息
    • 瀏覽在頁面得具體位置

JS模塊化加載方案和選型

  • CommonJS

    • 旨在Web瀏覽器之外爲JavaScript建立模塊生態系統
    • Node.js模塊化方案受CommonJS,同步加載得方式
  • AMD(Asynchronous Module Definition)(異步模塊定義規範)

    • 主要用於瀏覽器上
    • RequireJS 模塊化加載器:基於 AMD API實現
  • CMD (Common Module Definition)(通用模塊定義)規範

    • SeaJS模塊加載器:遵循 CMD API編寫
  • ES6 import

CommonJS
//CommonJS
//引入依賴
var store = require('store')
// exports
exports = function(){
	return store.get('customers')
}
NodeJS module
//引入依賴
var store = require('store')
function customerStore(){
	return store.get('customers')
}

// exports
modules.exports = customerStore
RequireJS AMD
<script data-main="scripts/main" src="scripts/require.js"></script>
SeaJS CMD
//方式一
define(function(require,exports,module){
	//模塊代碼
})
//方式二
define('module',['module1','module2'],function(require,exports,module){
	//模塊代碼
})
ES6 import
// square.js
export function square(x){
	return x*x
}

//main.js
import { square } from 'square'
console.log(square(10))	//100

減少瀏覽器的迴流和重繪

CSS

  • 避免過多樣式嵌套
  • 避免使用CSS 表達式
  • 使用 絕對定位,可以讓動畫元素脫離文檔流
  • 避免使用table佈局
  • 儘量不使用float佈局
  • 圖片最好設置好 widthheight
  • 儘量簡化瀏覽器不必要的任務,減少頁面重新佈局
  • 使用Viewport設置屏幕縮放級別
  • 避免頻繁設置樣式,最好把新的style屬性設置完成後,進行一次性更改
  • 避免使用引起 迴流 / 重繪的屬性,最好把相應變量緩存起來

JS

  • 最小化迴流和重排
    • 爲了減少迴流發生次數,避免頻繁或操作DOM,可以合併多次對DOM修改,然後一次性批量處理
  • 控制繪製過程和繪製區域
    • 繪製過程開銷比較大的屬性設置應該儘量避免減少使用
    • 減少繪製區域範圍

操作:在瀏覽器控制檯 x 邊上的 三個點點擊 ==> Main tool ==> Rendering ==> 勾選 Paint flashing ==> Performance

控制DOM大小

  • 頁面交互卡頓和流暢度很大一部分原因就是頁面有大量DOM元素。想象一下,從1w節點的DOM樹上,使用querySelectorAllgetELementByTagName方法查找某一個節點,是非常耗時的,另外元素綁定事件,事件冒泡和事件捕獲的執行也會相對耗時
  • 通常控制DOM大小的技巧包括
    • 合理的業務邏輯
    • 延遲加載即將呈現的內容,及暫時不需要展示的dom節點就隱藏等需要的時候在展示

簡化DOM操作

  • DOM節點的操作統一處理後,再統一插入到DOM Tree
  • 可以使用fragment,儘量不在頁面DOM Tree裏直接操作
  • ReactVue 虛擬DOM技術,通過diff算法簡化和減少DOM操作

靜態文件打包方案

  • 公共組件拆分
  • 壓縮:js / css / 圖片
  • 合併 : JS / CSS文件合併,CSS Sprite
  • Combo:JS / CSS 文件 Combo http://cdn.com/??a.js,b.js內容

靜態文件版本號更新策略

  • 緩存更新

    • cdnng後臺刷新文件路徑,更新文件header
  • 文件name-v100.js

    • 大功能迭代每次新增一個大版本,比如由v1v2
    • 小功能迭代新增加0.0.1或者0.1.0,比如從v1.0.0v1.0.1
    • 年末ng統一配置所有版本302至最新版
  • 時間戳。文件 name.js

    • 以每次上線時間點做差異
  • 文件hash.文件 name.js

    • 以文件內容 hash值 做 key
    • 每次上線,文件路徑不一致
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章