HTTP 优化
gzip 压缩
资源的压缩与合并
HTTP 协定上的 gzip 编码是一种用来改良 web 应用程序性能的技术,web 服务器和客户端(浏览器)必须独特反对 gzip。
浏览器申请 url,并在 request header 中设置属性 accept-encoding:gzip。表明浏览器反对 gzip。
该不该用 Gzip
压缩 Gzip,服务端要花工夫;解压 Gzip,浏览器要花工夫。两头节俭进去的传输工夫,真的那么可观吗?倡议较大文件进行 gizp
webpack4 中启动 gzip 压缩
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, // 是否删除原资源
}),
];
具体配置 CompressionWebpackPlugin
CDN 减速
当初大部分云服务商都是提供 cdn 服务
简略的来说: 原服务器上数据复制到其余服务器上,用户拜访时,那台服务器近拜访到的就是那台服务器上的数据。
CDN 减速长处 是成本低,速度快。能够用 CDN best 的 CDN 进行减速,收费,可部署公有,私有 CDN 零碎。能够实现宕机检测,主动切换 ip,分线路,分组解析。也就是 CDN 减速的次要作用就是保障网站的失常拜访,及放慢网站访问速度和响应速度,避免网站因黑客攻击,DNS 解析劫持故障等导致的网站服务器的宕机情况的呈现。
图片(图标)方面
应用字体图标
举荐:Iconfont- 阿里巴巴矢量图标库
雪碧图
将多个图标集成在一起
雪碧图制作起来麻烦,我还是举荐 Iconfont 的字体图标啦
图片应用 Base64 编码缩小页面申请数(倡议小图片)
Base64 编码图片能够在浏览器本人显示进去
采纳 Base64 的编码方式将图片间接嵌入到网页中,而不是从内部载入,如<img src="data:image/gif;base64,/9j/2SDFG... >
,这样下载 HTML 文档的工夫就会增长了。在 CSS 背景图中也是能够这么做的
应用 webpack 解决图片成 base64
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 配置 JPG、PNG、GIF 和 SVG 图像的压缩
// 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,},
},
},
],
},
};
html,css 优化
<script> 标签和 <style> 标签(看正文)
<!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>
回流和重绘
须要浏览器渲染机制,该文章就不开展讲了
回流(重排)
回流又名重排,指几何属性需扭转的渲染。触发浏览器回流并从新生成渲染树。
重绘
重绘指更改外观属性而不影响几何属性的渲染。渲染树的节点产生扭转,然而不影响该节点的几何属性。
- 几何属性:包含布局、尺寸等可用数学几何掂量的属性
布局: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
js 优化
缩小 DOM 操作
- 缩小 DOM 更改等操作
// 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 // 一次性插入
- DocumentFragment
不是实在 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
节流: 肯定工夫内,只有最初一次操作,再过 wait 毫秒后才执行函数
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
webpack4 优化(打包过大等优化)
webpack 设置 cdn 优化
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>
splitChunks(打包宰割)
运行 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,
}
},
},
},
},
};
相干博文
玩转 CSS 的艺术之美