400% 的飛躍-web 頁面加載速度優化實戰
前言
一個網站的加載速度有多重要? 反正我相信之前來 博主網站 的人至少有 50% 在加載完成前關閉了本站。 為啥捏? 看圖
首頁完整加載時間 8.18s,看來能進來看博主網站的人都是真愛呀,哈哈。 正常來講一個網頁 4s 加載不完就會流失很大一部分用戶,而博主的網站加載時間竟然達到了 8s 還是在電腦端,如果在移動端,加載時間會更久,體驗會更差。 這樣的話網站做得再難看批判者進不來不是白搭嘛,于是針對 web 頁面加載速度的優化迫在眉睫。
基于博主以前優化過其他網站,于是博主準備把這次的優化過程記錄下來分享給大家借鑒。
1. 頁面分析
先來看優化前的頁面:
加載時間 8.18s ,一共 33 個 請求,加載 1.38MB 。 可以看到對于網速較慢的瀏覽者光加載資源就需要 5s 以上,再加上 33 個請求切換開銷,簡直不能愉快的玩耍。 所以接下來的優化手段就要從加載流量和請求數量入手:
2. 優化圖片
圖片在網絡流量中占有很大的比重,因此優化圖片對于減少流量有著至關重要的作用。
合并小圖片:
很多頁面有很多小圖標,一個一個加載就相當于一個一個請求,將這些小圖片合并成一個大圖片,用css 控制顯示范圍,這樣就只需要一個請求即可加載完所有小圖片,瞬間就會減少很多網絡請求。
優化圖片格式:
很多圖片沒有經過優化直接上傳到網頁中會占用很多額外的流量,比如一張屏幕大小的截圖,用截圖工具直接截圖后的大小大概有 1MB ,此時直接上傳到網頁中就直接占用了 1MB 流量,但其實我們完全可以只犧牲它 40% 的質量換取縮小 10 倍的大小,網上有很多轉化 web 圖片的網站,當然如果你有 photoshop 的話完全可以自己導出:
將圖片在 ps 中打開,然后點擊菜單欄 “文件” 菜單,選擇 “儲存為 web 所用格式”,出現如下對話框:
一般情況下 jpg 圖片選擇品質中即可,png 格式圖片選擇 png8 即可,但注意有透明背景的 png 圖片要選擇 png24 ,否則透明背景中會出現白邊,gif 圖片選擇 gif64 無仿色即可。
一般經過優化的圖片大小至少會有 3倍 之差,圖片原大小越大優化的結果會越好。
博主的網站最顯眼的圖片就是頁眉上那個幽鬼的圖片啦,所以就先拿它開刀,經過以上步驟優化:
瞬間減小 4 倍, 實際效果 可以看看,代表著博主門面的圖片經過優化后和優化前顯示效果并沒有明顯區別,而文件大小卻相差了 4 倍。
3. 使用免費 cdn 加載第三方資源
所有網站都會用到第三方資源,對于第三方資源,如果選擇讓自己的服務器提供,那么對于小型站點,本就不大的帶寬相當一部分還要被公共資源占用,無形之中壓縮了服務器帶寬,如果把這部分資源讓第三方 cdn 提供,那么對于網站加載速度會有不小的提升。
博主選用的是 bootstrap 中文站提供的 cdn 靜態庫 ,博主看過不少國內 cdn 靜態庫,可以說 bootstrap 家的還是很良心的,更新及時,資源現在也很豐富,基本博主用的三方資源都能在上面找到,于是接下來就是搜索靜態資源 + 替換靜態資源:
<script src="/s/js/jquery.min.js"></script> 改為 <script src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
這里不要寫協議頭,讓網頁自動判斷使用 http 還是 https ( 關于 https 網站的部署可以看博主之前的文章: 給你的網站穿上外衣- HTTPS 免費部署指南 )
4. 使用 cdn 儲存靜態資源
一般網站 90% 的流量都用于靜態資源的加載,除了用免費 cdn 加載第三方資源,還可以自己申請云空間儲存自己的靜態資源,進一步減小服務器的開銷,讓服務器只專注于提供數據或者網頁渲染服務。 比如博主使用的是 X牛 ,將自己的圖片什么都存在 x牛上,每個月都有免費流量,對于個人網站來說應該夠用。
5. 合并壓縮 js css
除去引用公共庫,網頁中還有許多自己寫的 js 與 css,如果我們直接把開發環境的文件拿來用無疑很浪費流量,因此在編寫好網頁測試完畢后,我們應該將 css 和 js 壓縮合并成一個或者幾個文件,這樣既減少了請求次數又減少了流量消耗,一箭雙雕。 當然還有 html 壓縮,不過 ms 現階段還有一些坑,就先不用了。 說到合并壓縮,第一時間播追就想到了 webpack ,前端工程化神器,簡單配置一下就可以完全搞定任務:
博主網站自己的 js 工程文件放在 /webroot/static/src/js/ 中,假如我們要將壓縮合并后的文件放在 /webroot/static/dist/js/ 中:
在 /webroot/ 下新建文件夾 webpack , 進入文件夾,新建文件 package.json:
{ "name": "RaPo3", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "rapospectre", "license": "ISC", "devDependencies": { "css-loader": "^0.24.0", "style-loader": "^0.13.1", "webpack": "^1.13.2", "webpack-dev-server": "^1.15.1" } }
保存后執行:
npm install //或 cnpm install //如果你有的話
然后新建 webpack 配置文件 webpack.config.js:
var webpack = require('webpack'); module.exports = { entry: { base: ['../static/js/src/http.js', '../static/js/stickUp.min.js', '../static/js/src/base.js'], index: ['../static/js/src/index.js'], detail: ['../static/js/editormd.js', '../static/js/src/article.js'], know: ['../static/js/editormd.js', '../static/js/src/know.js'], list: ['../static/js/src/list.js']}, output: { path: '../static/js/dist/', filename: '[name].js' }, plugins: [ new webpack.optimize.UglifyJsPlugin({ output: { comments: false }, compress: { warnings: true } }), ]
}</pre>
這里要注意的是如果你的 js 文件間的引用是傳統的 html 引入后引用那么在這里合并時記得把你被引用的方法對象等等設置為全局,比如 b.js 要引用 a.js 中的函數 c,合并前要在 a.js 中加上( 當然如果你一直用 es6/node 寫 js 就不用看這里了 ):
window.c = c; 或 this.c = c;不然 c 就會被當作局部函數封裝起來。
改完后運行 webpack 提示成功后看到 dist 目錄里已經輸出了合并壓縮好的文件,之前 12kb 的文件經過壓縮合并后只有 6kb 大小,然后我們將其替換到網頁中即可。
6. 代碼優化
頁面代碼的優化對于頁面加載速度也有不小的影響,最廣為人知的:
HTML頭部的JavaScript和寫在HTML標簽中的Style會阻塞頁面的渲染,因此CSS放在頁面頭部并使用Link方式引入,JavaScript的引入放在頁面尾
其次還有:
按需加載,把統計、分享等 js 在頁面 onload 后再進行加載,可以提高訪問速度;
優化 cookie ,減少 cookie 體積;
避免 <img> 的 src 為空;
盡量避免設置圖片大小,多次重設圖片大小會引發圖片的多次重繪,影響性能;
合理使用display屬性:
a.display:inline后不應該再使用width、height、margin、padding以及float b.display:inline-block后不應該再使用float c.display:block后不應該再使用vertical-align d.display:table-*后不應該再使用margin或者float
不濫用Float 和 web 字體;
盡量使用CSS3動畫;
使用 ajax 異步加載部分請求;
7. HTTP2 與 gzip
HTTP2 是以 SPDY 為基礎開發的。 SPDY 系列協議由谷歌開發,于 2009 年公開。它的設計目標就是降低 50% 的頁面加載時間,所以 HTTP2 在很大程度也是為了優化頁面加載時間,同時 HTTP2 支持多路復用,簡單說就是所有的請求都通過一個 TCP 連接并發完成。 而 gzip 大家都不陌生,就是一種壓縮網頁的技術,當然壓縮網頁進行傳輸的代價就是給服務器增加一些壓縮的負擔,當然這種犧牲是值得的。
如何開啟 HTTP2 與 gzip? 博主的網站基于 nginx + uWSGI 進行服務,因此只要在 nginx 開啟 HTTP2 與 gzip 就好:
開啟 HTTP2
nginx 1.9.5 之后才支持 HTTP2 ,而且需要配置編譯參數。
開啟 gzip
直接打開 nginx 配置文件, 比如博主的在 /etc/nginx/nginx.conf , 然后加上:
server{ gzip on; gzip_comp_level 6; gzip_proxied any; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript application/x-font-woff; }然后重啟 nginx 即可
最后,讓我們清除緩存,再次打開網站:
總加載流量 527kb ,頁面完成加載時間 1.84s,對比之前加載時間 8.18s ,1.38MB 流量,整體時間提升了 4 倍多!用手機端訪問測試,簡直快的飛起,不信你也來[訪問] 1 試試呀~
來自:https://segmentfault.com/a/1190000007035107