靜態資源優化
圖片格式 和 應用場景介紹
JPEG
聯合圖像裝甲小組是一種針對彩色照片而廣泛使用的有損壓縮圖形格式
- 介紹:柵格圖形。常用文件擴展名爲
.jpg
,也有.jpeg
、.jpe
。JPEG
在互聯網上常被應用於存儲和傳輸照片 - 不合適:線條圖形和文字、圖標圖形,因爲它的壓縮算法不太這些類型的圖形;並且不支持透明度
- 非常合適:顏色豐富的照片、彩色圖、大焦點圖、通欄
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
- 跨平臺,有
Linux
、Mac
、Windows
得解決方案 - 官網:
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
- 優化級別設置爲不小於 2 , 1 得話 基本不壓縮
圖片尺寸隨網絡環境變化
- 不同網絡環境
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
鏈接上增加不同特殊參數,服務端自動化生成 - 不同格式、大小、質量得圖片
- 圖片服務器自動化優化是可以在圖片
- 處理方式
- 圖片裁剪:按長邊、短邊、填充、拉伸等縮放
- 圖片格式轉換:支持
JPG
、GIF
、WebP
等,支持不同得圖片壓縮率 - 圖片處理:添加圖片水印、高斯模糊、重心處理、裁剪邊框等
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
過程,同時也不利於記憶網站品牌,建議統一添加
- 網站如果不設置
-
增加首屏必要的
css
和js
- 頁面如果需要等待所依賴的
js
和css
加載完成才顯示,則在渲染過程中頁面會一致顯示空白,影響用戶體驗,建議增加首屏必要的css
和js
,比如頁面框架背景圖片或者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
動畫代替setTimeout
、setInterval
requestAnimationFrame
可以在正確的時間進行渲染,setTimeout(callback)
、setInterval(callback)
無法保證(callback)
回調函數的執行時機- 與
setTimeout
相比,requestAnimationFrame
最大的優勢是**由系統來決定回調函數的執行時機。**具體一點講,如果屏幕刷新率是60Hz,那麼回調函數就每16.7ms被執行一次,如果刷新率是75Hz,那麼這個時間間隔就變成了1000/75=13.3ms,換句話說就是,requestAnimationFrame
的步伐跟着系統的刷新步伐走。它能保證回調函數在屏幕每一次的刷新間隔中只被執行一次,這樣就不會引起丟幀現象,也不會導致動畫出現卡頓的問題。
- 與
合理使用緩存
- 合理緩存
DOM
對象 - 緩存列表長度
- 使用可緩存的
Ajax
Cookie
- 通常由瀏覽器存儲,然後將
Cookie
與每個後續請求一起發送到同意服務器。收到HTTP
請求時,服務器可以發送帶有Cookie
的header
頭。可以給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
佈局 - 圖片最好設置好
width
和height
- 儘量簡化瀏覽器不必要的任務,減少頁面重新佈局
- 使用
Viewport
設置屏幕縮放級別 - 避免頻繁設置樣式,最好把新的
style
屬性設置完成後,進行一次性更改 - 避免使用引起 迴流 / 重繪的屬性,最好把相應變量緩存起來
JS
- 最小化迴流和重排
- 爲了減少迴流發生次數,避免頻繁或操作
DOM
,可以合併多次對DOM
修改,然後一次性批量處理
- 爲了減少迴流發生次數,避免頻繁或操作
- 控制繪製過程和繪製區域
- 繪製過程開銷比較大的屬性設置應該儘量避免減少使用
- 減少繪製區域範圍
操作:在瀏覽器控制檯 x 邊上的 三個點點擊 ==> Main tool ==> Rendering ==> 勾選 Paint flashing ==> Performance
控制DOM
大小
- 頁面交互卡頓和流暢度很大一部分原因就是頁面有大量
DOM
元素。想象一下,從1w
節點的DOM
樹上,使用querySelectorAll
或getELementByTagName
方法查找某一個節點,是非常耗時的,另外元素綁定事件,事件冒泡和事件捕獲的執行也會相對耗時 - 通常控制
DOM
大小的技巧包括- 合理的業務邏輯
- 延遲加載即將呈現的內容,及暫時不需要展示的
dom節點
就隱藏等需要的時候在展示
簡化DOM
操作
- 對
DOM
節點的操作統一處理後,再統一插入到DOM Tree
中 - 可以使用
fragment
,儘量不在頁面DOM Tree
裏直接操作 React
、Vue
虛擬DOM
技術,通過diff
算法簡化和減少DOM
操作
靜態文件打包方案
- 公共組件拆分
- 壓縮:
js / css / 圖片
- 合併 :
JS / CSS
文件合併,CSS Sprite
Combo
:JS / CSS
文件Combo
http://cdn.com/??a.js,b.js
內容
靜態文件版本號更新策略
-
緩存更新
cdn
或ng
後臺刷新文件路徑,更新文件header
頭
-
文件
name-v100.js
- 大功能迭代每次新增一個大版本,比如由
v1
到v2
- 小功能迭代新增加
0.0.1
或者0.1.0
,比如從v1.0.0
至v1.0.1
- 年末
ng
統一配置所有版本302
至最新版
- 大功能迭代每次新增一個大版本,比如由
-
時間戳。文件
name.js
- 以每次上線時間點做差異
-
文件
hash.文件
name.js
- 以文件內容
hash
值 做key
- 每次上線,文件路徑不一致
- 以文件內容