性能优化
bridge 2022/9/11
# 图片优化
使用svg、webP、base64编码、雪碧图
# 加载优化
- 图片懒加载
HTML 代码
<body>
<img src="empty.jpg" data-src="city.png" alt="city" class="lazy">
<img src="empty.jpg" data-src="moon.png" alt="moon" class="lazy">
<img src="empty.jpg" data-src="room.png" alt="room" class="lazy">
<img src="empty.jpg" data-src="two.png" alt="two" class="lazy">
</body>
JS 代码
document.addEventListener("DOMContentLoaded", function(){
// 获取需要懒加载的图片列表
let lazyImges = [].concat(...document.querySelectorAll('.lazy'))
console.log(lazyImges)
let sign = false
const lazyload = function(){
if(sign == false){
sign = true
setTimeout(() => {
lazyImges.forEach(img => {
// 获取图片的相对位置和视图大小进行对比,判断图片是否出现在视图中
if(img.getBoundingClientRect().top <= window.innerHeight && img.getBoundingClientRect().bottom >=0 && img.style.display !== 'none'){
img.src = img.dataset.src
img.classList.remove('lazy')
lazyImges.filter(v => v !== img)
// 如果没有需要懒加载的图片了,移除监听
if(lazyImges.length === 0){
document.removeEventListener('scroll', lazyload)
window.removeEventListener('resize', lazyload)
window.removeEventListener('orientationchange', lazyload)
}
}
})
sign = false
}, 200);
}
}
lazyload()
document.addEventListener('scroll', lazyload) // 监听滚动
window.addEventListener('resize', lazyload) // 监听缩放
window.addEventListener('orientationchange', lazyload) // 监听方向翻转
})
# 书写高性能代码
# 构建优化
使用 webpack 等打包工具,对文件进行混淆压缩
# 渲染优化
- js 执行优化
- 恰当使用 web worker
- 节流
固定时间端内只会执行一次,常用场景:搜索框联想、滚动加载等
function throttle(fn, delay){
let flag = true
return (...args) => {
if(flag){
flag = false
setTimeout(() => {
flag = true
// console.log(new Date())
fn.apply(this, args)
}, delay);
}
}
}
- 防抖
连续触发只会执行一次,常用场景:窗口缩放(resize)、登录等按钮避免用户重复触发、输入验证(输入完成后再进行检查,避免keyup等事件重复触发)等
延时防抖,第一次执行也会延迟
function debounce(fn, delay){
let setId = undefined
let that = this
return function(...args){
if(setId !== undefined) clearTimeout(setId)
setId = setTimeout(() => {
fn.apply(that, args)
setId = undefined
}, delay);
}
}
立即防抖
function QuickDebounce(fn, delay){
setId = undefined
return (...agrs) => {
if(setId !== undefined) clearTimeout(setId)
let now = !setId
setId = setTimeout(() => {
setId = undefined
}, delay);
if(now) fn.apply(this, agrs)
}
}
- 计算样式优化
- 减少要计算的元素数量
css 引擎查找样式表时,对每条规则的匹配顺序时从右向左 - 降低选择器的复杂性
- 减少页面重排和重绘
- 避免对样式的频繁改动
一条条修改 dom 元素的样式会多次对渲染树的修改,应改为element.classList.add()
添加类名的方式更改样式
offsetTop
、scrollLeft
等属性值赋值、取值时会触发页面的重新计算,使用时应先将值缓存起来,再将最后的结果统一赋值
# 服务器端优化
# 数据存储
# 缓存技术
选择合适的缓存方式