事實上, 只有10%-20%
的最終用戶響應時間是發在從Web服務器獲取HTML文檔並傳送到瀏覽器中的。若是但願可以有效地減小頁面的響應時間,就必須關注剩餘80%-90%
的最終用戶體驗。
--Steve Souders在這篇博客中,我根據工做中的實際項目經驗和一些測試的經驗中總結出了前端頁面在性能上優化方案。其中一些經驗吸取自《高性能網站建設指南》Steve Souders 著 電子工業出版社。javascript
遵循HTML規範
,將樣式表放在頭部,能夠有效避免白屏
和無樣式內容的閃爍
。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title></title> <!-- 使用link標籤將樣式表放在文檔的HEAD中 --> <link rel="stylesheet" href="example.css"> </head> <body></body> </html>
腳本阻塞對其後面內容的顯示
; 腳本會阻塞對其後面組件的下載
;底部</body>
標籤以前, 相似於document.body.appendChild(yourScript), 不會阻塞頁面內容的呈現,並且頁面中的可視組件能夠儘早下載。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title></title> <link rel="stylesheet" href="example.css"> </head> <body> <!-- 將腳本放在底部 --> <script src="example.js"></script> </body> </html>
將多個圖片
合成一張圖片
,經過background-position來定位所須要的圖片。每次請求的話只須要請求一張圖片
減小http請求。(若是使用圖標的話建議使用svg,也可使用 iconfont)
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4SUJRXhpZgAATU>
多個小文件
中,會下降性能
,每一個文件都會致使一個額外的
HTTP請求Good
css
<link rel="stylesheet" href="example.css"> <script src="example.js"></script>
bad
html
<style> // code </style> <script> // code </script>
能夠配置緩存
有利於組件重用
CDN是構建在網絡之上的內容分發網絡,依靠部署在各地的邊緣服務器
,經過中心平臺的負載均衡
、內容分發
、調度
等功能模塊,使用戶就近獲取所需內容,下降網絡擁塞,提升用戶訪問響應速度和命中率。CDN的關鍵技術主要有內容存儲
和分發技術
。--摘自百度百科
HTTP2協議
,因此在性能上能夠作到極致優化,感謝CDN。
gzip壓縮能夠節省
50%-70%
的網絡開銷
瀏覽器支持的壓縮類型能夠經過network的Accept-Encoding:gzip
,deflate
來查看。支持deflate的瀏覽器也支持gzip,但不少瀏覽器支持gzip卻不支持deflate
,所以gzip是最理想的壓縮方法
webpack
項目能夠看下面的Vue首屏加載時間優化
方案裏的gzip壓縮// npm install compression --save-dev const compression = require('compression')
前端打包壓縮的有grunt,gulp,webpack,能夠對HTML,CSS,Javascript代碼壓縮前端
本文中使用nginx
服務器進行相關配置,使用apache
一樣能夠作到相關優化,具體操做請另 Google
gzip
壓縮gzip on; # 開啓Gzip gzip_static on; # 開啓靜態文件壓縮 gzip_min_length 1k; # 不壓縮臨界值,大於1K的才壓縮 gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss; # 進行壓縮的文件類型 gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_disable "MSIE [1-6]\.";
HTTP2在前端性能上主要表如今:請求和響應的多路複用、頭部壓縮vue
我的站點相關配置
java
nginx配置node
location ~.*\.(svg|woff|js|css){ root /yourFilePath; expires 1d; }
Expires
頭來告訴Web客戶端它可使用一個組件的當前副本,直到指定的時間爲止 HTTP規範中簡要地稱該頭爲「在這一日期時間以後,響應將被認爲是無效的」。它在HTTP響應中發送expires: Thu, 30 May 2019 20:51:42 GMT
強緩存cache-control: max-age
server { add_header Cache-Control max-age=72000; }
HTTP 1.1引入了Cache-Control頭來克服Expires頭的限制
要求服務器和客戶端的時鐘嚴格同步
。另外,過時日期須要常常檢查,而且一旦將來這天到來了,還須要在服務器配置中提供個新的日期。一個長久的max-age頭能夠將刷新窗設置爲將來10年
。Cache-Control: max-age=315360000
重寫Expires頭
。Cache-Control max-age
,若是使用expires你須要擔憂它帶來的時鐘同步
和配置維護
問題。Vue官方文檔的Expires相關配置
webpack
瀏覽器必須產生這個HTTP請求,執行有效性檢查, 但這仍比簡單地下載全部已過時的組件效率要高
(對比強緩存
)。若是瀏覽器緩存中的組件是有效的(即它可以和原始服務器上的組件相匹配),原始服務器不會返回整個內容,而是返回一個304 Not Modifed
狀態碼。
附:Vue首屏加載時間過長詳細優化方案
首屏加載時間
從原來的10s
到2s
,測試的我的站點 注:我在優化vue項目的時候使用的是vue@2.6.6
,vue-cli@3.4
。 若是是cli2的項目影響也不大,優化的方案是結合服務端和webpack的。
vue-cli腳手架默認配置已經大幅度優化了前端總體的性能,在此基礎上,我又使用了三個優化項增長了大幅度提高
服務器相關優化第一條:開啓gzip壓縮
vue.config.js
中的配置// 須要 npm install compression-webpack-plugin --save-dev const CompressionWebpackPlugin = require('compression-webpack-plugin') // 定義當前環境 const ENV = process.env.NODE_ENV || 'development' module.exports = { configureWebpack: config => { // 若是是開發環境的話,開啓壓縮 if (ENV === 'production') { // 參數配置文檔: https://www.webpackjs.com/plugins/compression-webpack-plugin/ config.plugins.push(new CompressionWebpackPlugin({ algorithm: 'gzip', test: /\.(js|css|html)$/, threshold: 10240, minRatio: 0.8 })) } } }
在index.html
文件中經過環境來判斷是否引入cdn文件,在vue.config.js
文件中webpack經過環境判斷是否使用cdn引入文件的全局變量
webpack
和index.html
進行相關配置第一步 配置vue.config.js
,只須要在剛纔配置Gzip壓縮的基礎上再加一段代碼
:ios
const CompressionWebpackPlugin = require('compression-webpack-plugin') const ENV = process.env.NODE_ENV || 'development' module.exports = { configureWebpack: config => { if (ENV === 'production') { config.plugins.push(new CompressionWebpackPlugin({ algorithm: 'gzip', test: /\.(js|css|html)$/, threshold: 10240, minRatio: 0.8 })) // 配置externals就是當使用CDN進入的js文件在當前項目中能夠引用 // 好比在開發環境引入的vue是import Vue from 'vue', 這個大寫的Vue就是對應的下面的大寫的Vue config.externals = { 'vue': 'Vue', 'vue-router': 'VueRouter', 'axios': 'axios' } } } }
第二步 配置index.html
,在body裏使用EJS語法判斷是否爲生產環境nginx
<body> <div id="app"></div> <% if (NODE_ENV === 'production') { %> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script> <script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script> <script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script> <% } %> </body>
productionSourceMap: false
幹掉生產環境的sourceMapconst CompressionWebpackPlugin = require('compression-webpack-plugin') const ENV = process.env.NODE_ENV || 'development' module.exports = { configureWebpack: config => { if (ENV === 'production') { config.plugins.push(new CompressionWebpackPlugin({ algorithm: 'gzip', test: /\.(js|css|html)$/, threshold: 10240, minRatio: 0.8 })) config.externals = { 'vue': 'Vue', 'vue-router': 'VueRouter', 'axios': 'axios' } } }, // 禁用生產環境的sourceMap productionSourceMap: false }
請參考服務端優化第二條
前端性能優化相當重要,文中說起的是我認爲比較重要的幾點,之後遇到更好的方案會補充進來。固然你也能夠在評論區留言咱們一塊兒探討,有錯誤的地方歡迎指出。