資源的壓縮與合併
HTTP協議上的gzip編碼是一種用來改進web應用程序性能的技術,web服務器和客戶端(瀏覽器)必須共同支持gzip。css
瀏覽器請求url,並在request header中設置屬性accept-encoding:gzip。代表瀏覽器支持gzip。html
壓縮 Gzip,服務端要花時間;解壓 Gzip,瀏覽器要花時間。中間節省出來的傳輸時間,真的那麼可觀嗎?建議較大文件進行gizpvue
npm i -D compression-webpack-plugin plugins: [ new CompressionPlugin({ filename: "[path].gz[query]", algorithm: "gzip", test: /\.js$|\.html$|\.css/, threshold: 10240, // 只處理比這個值大的資源。按字節計算 minRatio: 0.8 // 只有壓縮率比這個值小的資源纔會被處理 deleteOriginalAssets: false, //是否刪除原資源 }), ];
詳細配置 CompressionWebpackPluginnode
如今大部分雲服務商都是提供cdn服務
簡單的來講: 原服務器上數據複製到其餘服務器上,用戶訪問時,那臺服務器近訪問到的就是那臺服務器上的數據。
CDN加速優勢是成本低,速度快。能夠用CDN best的CDN進行加速,免費,可部署私有,公有CDN系統。能夠實現宕機檢測,自動切換ip,分線路,分組解析。也就是CDN加速的主要做用就是保證網站的正常訪問,及加快網站訪問速度和響應速度,防止網站因黑客攻擊,DNS解析劫持故障等致使的網站服務器的宕機情況的出現。webpack
推薦: Iconfont-阿里巴巴矢量圖標庫web
將多個圖標集成在一塊兒
雪碧圖製做起來麻煩,我仍是推薦Iconfont的字體圖標啦ajax
Base64編碼圖片能夠在瀏覽器本身顯示出來vue-router
採用Base64的編碼方式將圖片直接嵌入到網頁中,而不是從外部載入,如<img src="data:image/gif;base64,/9j/2SDFG... >
,這樣下載HTML文檔的時間就會增加了。在CSS背景圖中也是能夠這麼作的vuex
npm install --save-dev url-loader // webpack.config.js module.exports = { module: { rules: [{ test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/, use: [{ loader: "url-loader", // 根據圖片大小,把圖片優化成base64 options: { limit: 10000, //小於10000字節的圖片都進行base64操做 } } ] }] } };
// webpack.config.js module.exports = { module: { rules: [ { loader: "image-webpack-loader", // 先進行圖片優化 options: { mozjpeg: { progressive: true, quality: 65, }, optipng: { enabled: false, }, pngquant: { quality: "65-90", speed: 4, }, gifsicle: { interlaced: false, }, webp: { quality: 75, }, }, }, ], }, };
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> /** * 放頭部: 頁面先解析<style>後獲得css後解析html */ <style>...<style> /** * 放頭部: 頁面的解析在遇到js的時候須要運行完js以後才能繼續 * 缺點:js一旦加載或者運算好久,會致使用戶白屏 */ <script> for (let i=0; i < 1000000000000000; i++) { console.log("年輕人不講碼德! 你就慢慢等吧") } </script> </head> <body> <div id="container"></div> /** * 放尾部: 頁面的解析完畢開始加載js * 優勢:用戶無需等待js加載就能夠看到界面 */ <script> var container = document.getElementById("container") console.log('container', container) // '<div id="container"></div>' </script> </body> /** * 放尾部: 頁面先解析html後獲得解析css * 缺點:致使html節點出來沒樣式後纔有 */ <style>...<style> </html>
須要瀏覽器渲染機制,該文章就不展開講了
迴流又名重排,指幾何屬性需改變的渲染。觸發瀏覽器迴流並從新生成渲染樹。npm
重繪指更改外觀屬性而不影響幾何屬性的渲染。渲染樹的節點發生改變,可是不影響該節點的幾何屬性。
佈局:display、float、position、list、table、flex、columns、grid 尺寸:margin、padding、border、width、height
界面:appearance、outline、background、mask、box-shadow、box-reflect、filter、opacity、clip 文字:text、font、word
// bad let box = document.getElementById('box') box.innerHTML = '1' box.innerHTML += '2' box.innerHTML += '3' ... // good let content = '' content = '1' content += '2' content += '3' box.innerHTML = content // 一次性插入
不是真實 DOM 樹,它的變化不會引發 DOM 樹的從新渲染
let box = document.getElementById('box') let content = document.createDocumentFragment() let Fdiv = document.createElement('div') Fdiv.innerHTML = '1' Fdiv.innerHTML += '2' Fdiv.innerHTML += '3' content.appendChild(Fdiv) // 只產生一次dom操做 box.appendChild(content)
<li><img src="img/loading.gif" data-src="img/1.jpg"></li>
最開始每個圖片使用loading.gif,首屏加載的時候能夠節省多張圖片請求
原理:滾動條設置到圖片的時候加載data-src內的正常圖片
具體實現能夠看我以前發的文章實現圖片懶加載
/** * @param {Function} func 要執行的回調函數 * @param {Number} wait 延時的時間 * @param {Boolean} immediate 是否當即執行 * @return null */ let timer, flag; function throttle(func, wait = 500, immediate = true) { if (immediate) { if (!flag) { flag = true; // 若是是當即執行,則在wait毫秒內開始時執行 typeof func === 'function' && func(); timer = setTimeout(() => { flag = false; }, wait); } } else { if (!flag) { flag = true // 若是是非當即執行,則在wait毫秒內的結束處執行 timer = setTimeout(() => { flag = false typeof func === 'function' && func(); }, wait); } } }; export default throttle
let timeout = null; /** * @param {Function} func 要執行的回調函數 * @param {Number} wait 延時的時間 * @param {Boolean} immediate 是否當即執行 * @return null */ function debounce(func, wait = 500, immediate = false) { // 清除定時器 if (timeout !== null) clearTimeout(timeout); // 當即執行,此類狀況通常用不到 if (immediate) { var callNow = !timeout; timeout = setTimeout(function() { timeout = null; }, wait); if (callNow) typeof func === 'function' && func(); } else { // 設置定時器,當最後一次操做後,timeout不會再被清除,因此在延時wait毫秒後執行func回調方法 timeout = setTimeout(function() { typeof func === 'function' && func(); }, wait); } } export default debounce
vuecli生成的項目進行配置
運行yarn build 發現vendors.js之中包含vue,vuex, vue-router
如今咱們能夠經過webpack的externals進行vue,vuex抽離掉使用cdn
# vue.config.js module.exports = { configureWebpack:{ externals: { 'vue': 'Vue', 'vuex': 'Vuex' } } } # store/index.js import Vuex from "vuex"; // Vue.use(Vuex); 註釋掉
// index.html <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.1.3/vuex.min.js"></script> </body>
運行yarn build 發現vendors.js之中還有vue-router須要分離
能夠利用webpack中的splitChunks分割出來
splitChunks的配置挺複雜的,須要你們本身學習,我只是提供一個方案
# vue.config.js module.exports = { configureWebpack: { optimization: { splitChunks: { cacheGroups: { vendors: { test: /node_modules/, chunks: "initial", minChunks: 1, priority: -10, }, router: { name: 'chunk-router', test: /[\\/]node_modules[\\/]vue-router[\\/]/, chunks: "all", minChunks: 1, priority: -5, } }, }, }, }, };