>
我們不僅保存了寬高比,還保存了圖片格式,是為了后期可以對gif做進一步的優化。
注意事項
避免圖片過早加載,把臨界值調低一點。在實際項目中,并不需要過早就把圖片請求過來,尤其是項目,過早請求不僅浪費流量,也會因為請求太多,導致頁面加載速度變慢。
為了最好的防抖效果,設置圖片高度的JS代碼內嵌到HTML中以便第一時間執行。
根據圖片寬度設置高度時,使用而不是width。這是因為中,第一時間執行的JS代碼獲取圖片的width失敗,所以使用解決這個問題。
4 JS/CSS按需打包
按需打包是獨特的優勢,如果有需要通過此種方式來管理模塊之間的依賴關系,強烈推薦引入!
好奇心日報是典型的多頁應用,為了緩存通用代碼,我們使用按需打包的同時,還利用的 插件抽離出公用的JS/CSS代碼,便于緩存,在請求數量和公用代碼的緩存之間做了一個很好的平衡。
5 延遲加載ga統計
async & defer屬性
html5中給標簽引入了async和defer屬性。
帶有async屬性的標簽,會在瀏覽器解析時立即下載腳本同時不阻塞后續的渲染和加載等事件,從而實現腳本的異步加載。
帶有defer屬性的標簽,和async擁有類似的功能。并且他們有可以附帶一個事件');,該方式也可以避免阻塞。
ga統計代碼
ga統計代碼采用就是動態創建標簽方案。該方法不阻塞頁面渲染,不阻塞后續請求,但會阻塞.事件,頁面的表現方式是進度條一直加載或菊花一直轉。
所以我們延遲執行ga初始化代碼,將其放到.函數中去執行,可以防止ga腳本阻塞.事件。從而讓用戶感受到更快的加載速度。
將ga加載綁定到事件上
? ? ? ? ? ? ? ?
如何減少請求大小
1 JS/CSS/HTML壓縮
這也是常規手段頁面加載時顯示進度條,就不介紹太多,主要的方式有:
通過構建工具實現,比如/gulp/fis/grunt等。
后臺預編譯。
利用第三方平臺,手動上傳壓縮。
無論是第二種還是第三種方式,都有其局限性,第一種方法是目前的主流方式,憑借良好的插件生態,可以實現豐富的構建任務。在好奇心日報的項目中,我們使用 & gulp作為構建系統的基礎。
簡單介紹一下JS/CSS/HTML壓縮方式和一些注意事項
JS壓縮
JS壓縮:使用的插件,同時做一些代碼檢測。
new ..({
: {
: ['$super', '$', '', '']
}
})
CSS壓縮
CSS壓縮:使用壓縮,同時使用做一些自動化操作,比如自動加前綴、屬性支持、語法檢測等。
var = [
({
: false,
: false,
: false,
: false,
: false
}),
({ : ['last 2 ', 'ie >= 9', '> 5% in CN'] }),
,
,
,
,
];
HTML壓縮
HTML壓縮:使用壓縮HTML,同時對不規范的HTML寫法糾正。
// 構建視圖文件-build版本
gulp.task('build:views', ['clean:views'], () {
({ : true },
gulp.src(, { base: 'src' }),
gulp.src(., { base: 'src' }),
gulp.src(., { base: 'src/pages' }),
gulp.src(, { base: 'src' })
)
.pipe(())
.pipe(({ : true }))
.pipe(({ : { : } }))
.pipe(((file) {
if (file.path.('.html') != -1) {
true;
} else {
false;
}
}, ({
: true,
: true,
: true,
: true,
s: [//,
//,
//]
})))
.pipe(gulp.dest(.dest));
});
某個第三方平臺要求必須寫成小數點格式,而默認會將小數格式化為整數,所以額外添加了排除項://。到現在都沒懂這個第三方平臺咋想的!
條件編譯
由于好奇心日報項目較多,我們費了很大的心思抽離出前端項目,實現了前后分離。但有些場景下,我們為了將相關代碼維護在一個文件中,同時又針對不同項目執行不同的邏輯,這時候,強烈推薦使用 gulp-插件 來實現條件編譯。
條件編譯
2 gzip壓縮
gzip壓縮也是比較常規的優化手段。前端并不需要做什么實際的工作,后臺配置下服務器就行,效果非常明顯。如果你發現你的網站還沒有配置gzip,那么趕緊行動起來吧。
gzip壓縮原理
如果瀏覽器支持gzip壓縮,在發送請求的時候,請求頭中會帶有-:gzip。然后服務器會將原始的進行gzip壓縮,并將gzip壓縮后的傳輸到瀏覽器,緊接著瀏覽器進行gzip解壓縮,并最終反饋到網頁上。
支持gzip壓縮的請求頭
gzip壓縮效果
那么gzip壓縮的效果有多明顯呢?保守估計,在已經完成JS/CSS/HTML壓縮的基礎上,還能降低60-80%左右的大小。
gzip壓縮效果
但需要注意,gzip壓縮會消耗服務器的性能,不能過度壓縮。
所以推薦只對JS/CSS/HTML等資源做gzip壓縮。圖片的話,托管到第三方的圖片建議開啟gzip壓縮,托管到自己應用服務器的圖片不建議開啟gzip壓縮。
3 JS/CSS按需加載
和前面提到的按需打包不同。
JS/CSS按需打包是預編譯發生的事情,保證只打包當前頁面相關的邏輯。
JS/CSS按需加載是運行時發生的事情,保證只加載當前頁面第一時間使用到的邏輯。
那么怎么實現按需加載呢?好奇心日報使用提供的及.方法來實現按需加載,值得一提的是,除了指定的按需加載文件列表,還會自動解析回調函數的依賴及指定列表的深層次依賴,并最終打包成一個文件。
按需加載
上訴代碼的實現效果是:只有當點擊登錄按鈕的時候,才會去加載登錄相關的JS/CSS資源。資源在加載成功后自動執行。
4 圖片壓縮,jpg優化
托管到應用服務器的圖片壓縮
可以手動處理,也可以通過gulp子任務來處理。
手動處理的話,推薦一個網站 ,雖然是有損壓縮,但壓縮效果極好。
gulp子任務處理的話,推薦使用gulp-插件,自動化處理,效果也還不錯。
// 圖片壓縮
gulp.task('', () {
gulp.src(.src)
.pipe(())
.pipe(newer(.dest))
.pipe(({ : true }))
.pipe(()) // 壓縮
.pipe(gulp.dest(.dest));
});
托管到第三方平臺的圖片壓縮
比如七牛云平臺,他們會有一套專門的方案來對圖片壓縮,格式轉換,裁剪等。只需要在url后面加上對應的參數即可,雖然偶爾會有一些小bug,但整體來說,托管方案比用自家應用服務器方案更優。
改變參數,實現不同程度的壓縮
jpg優化
除了對圖片進行壓縮之外,對透明圖床沒有要求的場景,強烈建議將png轉換為jpg,效果很明顯!如下圖,將png格式化為jpg格式,圖片相差差不多8倍!
png轉jpg,體積相差八倍
再次強調,可以轉換成jpg的圖片,強烈建議轉換成jpg!
5 webp優化 & 優化
webp優化
粗略看一眼,臥槽,兼容性這么差,也就安卓瀏覽器及瀏覽器對它的支持還算給力。
webp兼容性
另一方面,webp優化能在jpg的基礎上再降低近50%的大小。其優化效果明顯。此外頁面加載時顯示進度條,如果瀏覽器支持,還能對gif做壓縮!
普通圖片webp優化
gif圖片優化
兼容性差,但效果好!最終好奇心決定嘗試一下。
判斷瀏覽器對webp及的兼容性。
如果瀏覽器支持webp及,將其替換成webp格式的圖片。
鑒于瀏覽器對webp的支持比較局限,我們采用漸進升級的方式來優化:對于不支持webp的瀏覽器,不做處理;對于支持webp的瀏覽器,將圖片src替換成webp格式。
那么如何判斷webp兼容性呢?
// 檢測瀏覽器是否支持webp
// 之所以沒寫成回調,是因為即使=false也無大礙,但卻可以讓代碼更容易維護
(() {
(src, name) {
var img = new Image(),
= false,
, cls;
img. = () {
= !!(img. > 0 && img.width > 0);
cls = ? (' ' + name) : (' no-' + name);
= .('html').
+= cls;
.('html'). = .trim();
};
img. = () {
cls = (' no-' + name);
= .('html').
+= cls;
.('html'). = .trim();
};
img.src = src;
}
var = 'data:image/webp;,\
/=',
= 'data:image/webp;,\
AAAD/////AA\
/gcA';
(, 'webp');
(, '');
})();
借鑒,實現了檢測webp/兼容性的函數,從代碼中可以看出,檢測原理就是模擬下載對應格式的圖片,在異步函數中可以得到兼容性結果。
▼
接下來就是替換url為webp格式
// 獲取webp格式的src
(src) {
var dpr = Math.round(. || 1),
ratio = [1, 1, 1.5, 2, 2, 2],
= .('html'),
= (/(^|\s)webp(\s|$)/i).test(.),
on = (/(^|\s)(\s|$)/i).test(.),
= .,
= /img\.\.com\//.test(src),
= (src),
, , ;
if (!src || ! || ! || == 'webp') {
src;
}
= ( != 'gif' && );
= ( == 'gif' && on);
// 根據屏幕分辨率計算大小
src = src.(/\/(|crop)\/.*?(\d+)x(\d+)[^\/]*\//ig, (match, p0, p1, p2) {
if(dpr > 1){
p1 = Math.round(p1 * ratio[dpr]);
p2 = Math.round(p2 * ratio[dpr]);
match = match.(/\d+x\d+/, p1 + 'x' + p2)
}
match;
});
if( || ) {
// 替換webp格式,首頁/列表頁
src = src.(/\/\/([^\/]*)/ig, (match, p1) {
'//webp';
});
}
}
注意事項
的屏幕像素密度不一定是整數,mac瀏覽器縮放之后,屏幕像素密度也不是整數。所以獲取dpr一定要取整:dpr = Math.round(. || 1);。
ratio = [1, 1, 1.5, 2, 2, 2]表示:1倍屏使用1倍圖,2倍屏使用1.5倍圖,3倍屏以上都用2倍圖。這兒的規則可以按實際情況來設置。
webp優化更適合托管到第三方的圖片,簡單修改參數就可以獲取不同的圖片。
兼容性
兼容性
兼容性
如上所述,在對webp優化的時候,我們順道模擬實現了:根據屏幕像素密度來設置最適合的圖片寬高。
原本提供了選項,也可以借用的方案來實現,有興趣的可以去看看源碼。
? ? ? ? ? ? ? ?
總結
本文圍繞好奇心日報的具體實踐,在優化頁面加載速度方面的做了一系列思考。整體來說,涉及的知識面比較廣:包括 & gulp的構建系統、圖片的webp優化、服務器的gzip配置、瀏覽器的加載順序、圖片延遲加載方案等等。
文中提到的gulp子任務,后續也會有一系列好奇心日報項目的相關實踐,會覆蓋gulp子任務的設計思路,構建系統的架構,以及具體子任務的剖析和講解,敬請關注。
? ? ? ? ? ? ? ?