原则 -- 用空间换时间
- 多使用内存,缓存
- 减少CPU计算量,减少网络的加载耗时
目标
- 加载更快
减少资源体积:压缩代码,图片:利用打包工具
减少网络访问次数:合并代码,SSR服务器端渲染,缓存
a.js b.js c.js => abc.js
服务器端渲染:将网页和数据一起加载,一起渲染
非SSR:先加载网页,再加载数据,再渲染数据
静态资源加hash后缀,根据文件内容计算hash
文件内容不变,hash不变,则url不变
url和文件不变,则会出发http缓存机制,返回304
使用更快的网络:CDN
- 渲染更快
CSS放在header,JS放在body最下面
尽早开始执行JS,用DOMContentLoaded触发
懒加载(图片懒加载,分页)
// 开始建在较小的预览图片,真实图片地址放在data-realsrc中
<img id="img1" src="preview.png" data-realsrc="abc.png"/>
<script>
// DOM加载完成后,再把真实图片加载出来
var img1 = document.getElementById('img1')
img1.src = img1.getAttribute('data-realsrc')
</script>
对DOM查询进行缓存
频繁的DOM操作,合并到一起插入DOM结构
防抖(debounce)
场景:监听一个输入框change事件,如果用keyup会频发出发change事件
用户输入结束或暂停时,才会触发change事件,就是防抖
const input1 = document.getElementById('input1')
let timer = null
input1.addEventListener('keyup', function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
console.log(input1.value) // 模拟触发change事件
timer = null // 清空定时器
}, 500)
})
封装为debounce函数:
function debounce(fn, delay = 500){
let timer = null // 自由变量
return function(){
if(timer)
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, arguments)
time = null
}, delay)
}
}
input1.addEventListener('keyup', debounce(()=>{
console.log(input1.value) // 箭头函数中,使用input1可以正确获取input1对象
// 如果现在箭头函数中,使用this.value打印的并不是input1的value,而是window.value
// 如果想动态指定this的值,此时就需要把箭头函数改为function,并在debounce函数中绑定事件触发时,this的值
}, 500))
节流(throttle)
场景:拖拽一个元素时,要随时拿到该元素被拖拽的位置;
直接用drag事件,则会频繁触发,很容易造成卡顿
节流:无论拖拽速度多快,都会每个100ms触发一次
<div id="div1" draggable="true">
可拖拽
</div>
<script>
const div1 = document.getElementById('div1')
div1.addEventListener('drag', (e)=>{
console.log(e.offsetX, e.offsetY) //频繁打印位置
})
</script>
改良 ==> 节流
const div1 = document.getElementById('div1')
let timer = null
div1.addEventListener('drag', (e)=>{
if(timer)
return
timer = setTimeout(() => {
console.log(e.offsetX, e.offsetY)
timer = null
}, 100)
})
改良 函数 ==> 节流
function throttle(fn, delay = 100){
let timer = null
return function(){
if(timer)
return
timer = setTimeout(() => {
fn.apply(this, arguments) // arguments把div1注册的函数参数传入入
timer = null
}, delay)
}
}
div1.addEventListener('drag', throttle(function(e){
console.log(e.offsetX, e.offsetY)
}, 200))