web性能优化

285 阅读2分钟

性能优化

原则和方向

性能优化原则

多使用内存、缓存或其他方法
减少CPU计算量,减少网络加载耗时
(适用于所有编程的性能优化一空间换时间 )

让加载更快

减少资源体积:压缩代码
减少访问次数:合并代码, SSR服务器端渲染,缓存
使用更快的网络: CDN

让渲染更快

CSS放在head,JS放在body最下面
尽早开始执行JS ,用DOMContentLoaded触发
懒加载(图片懒加载,上滑加载更多)
对DOM查询进行缓存
频繁DOM操作,合并到一起插入DOM结构
节流throttle防抖debounce

示例

资源合并

缓存

静态资源加hash后缀,根据文件内容计算hash
文件内容不变,则hash不变,则url不变
url和文件不变,则会自动触发http缓存机制, 返回304

SSR

服务器端渲染:将网页和数据一起加载, 一起渲染
非SSR(前后端分离):先加载网页,再加载数据,再渲染数据
早先的JSP ASP PHP,现在的vue React SSR

懒加载

使用预览图 
到可视区在加载

多个DOM操作一起插入到DOM结构

const listNode = document.getElementById('list')
//创建一个文档片段,此时还没有插入到DOM树中
const frag = document.createDocumentFragment()
//执行插入
for (let X = 0; X < 10; X++) {
    const Li = document.CreateElement("1i")
    li.innerHTML = "List item" + X
    frag.appendChild(li)
    //都完成之后,再插入到DOM树中
    listNode.appendChild(frag)
}

尽早开始JS执行

 window.addEventListener('load', function () {
    //页面的全部资源加载完才会执行,包括图片、视频等
})

document.addEventListener('DOMContentLoaded', function () {
    // DOM渲染完即可执行,此时图片、视频还可能没有加载完
})

防抖debounce

监听一个输入框的,文字变化后触发change事件
直接用keyup事件,则会频发触发change事件
防抖:用户输入结束或暂停时,才会触发change事件

代码示例

const input1 = document.getELementById('input1')
let timer = null
input1.addEventListener('keyup', function () {
    if (timer) {
        clearTimeout(timer)
    }
    timer = setTimeout(() => {
        //模拟触发change 事件
        console.log(input1.value)
        //清空定时器
        timer = null
    },500)
})

//防抖
function debounce(fn, delay = 100) {
    let timer = null
    return function () {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}

节流throttle

拖拽一个元素时,要随时拿到该元素被拖拽的位置
直接用drag事件,则会频发触发,很容易导致卡顿
节流:无论拖拽速度多快,都会每隔100ms触发一次

代码示例

const div1 = document.getElementById('div1')
let timer = null

div1.addEventListener('drag', function (e) {
    if (ti
    
    mer) {
        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)
            timer = null
        }, delay)
    }
}

div1.addEventListener('drag', throttle(function (e) {
    console.log(e.offsetX, e.offsetY)
}))