// 浏览器自带api // intersectionObjserver 懒加载 监听滚动条可以用这个 intersectionObserver // 创建实例 , 告诉浏览器要观察哪个元素 , 回调函数才会被触发 const observer = new IntersectionObserver(entries=> { entries.forEach(entry=> { console.log('元素可见性变化' , entry.target , entry.isIntersecting); // isIntersecting 是否在视口内 // intersectionRatio 交叉比例 // }) }) const ele = document.querySelector('.box') observer.observe(ele) // 调用observe会立即触发一次回调 // 可以知道元素的初始状态 const observer = new IntersectionObserver(entries=> { entries.forEach(entry=> { if(entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src observer.unobserve(img);///用完之后就取消观察 , 避免重复触发 } }) }) // document.querySelectorAll('img[data-src]').forEach(img=> { observer.observe(img) }) // 阈值 // 0-1 // 0 只要有1px进入视口就触发 , 默认0 // 0.5 50% // 0.25 ,0.5 , 0.75 , 1 每25%触发一次 const observer = new IntersectionObserver(entries=> { },{ threshold:0 }) // 设置根元素 , 边距 { root:document.querySelector('.container') , //根元素 rootMargin:'50px' ,//根元素的边距 , 扩大检测区域50px } // requestIdleCallback , 非关键任务放到浏览器空闲时做 , 重要但不急的事情 requestIdleCallback(()=> { sendAnalytics();//埋点上报 }) // requestAnimationFrame 动画容易掉帧 抖动 , 动画跟着屏幕刷新走 , 顺滑,页面切后台后还会自动降速、暂停 // 从0移动到200 let x = 0 ; function animate() { x+=2 ; element.style.transform = `translateX(${x}px)`; if(x<200) { // 请求下一帧 requestAnimationFrame(animate) } } // 启动动画 requestAnimationFrame(animate) // 监听元素尺寸变化 , 监听窗口 // resizeObserver // 可以监听任意元素的尺寸变化 // 容器变化就重绘图表 const ro = new ResizeObserver(entries=> { entries.forEach(entry=> { console.log('元素尺寸变化' , entry.target , entry.contentRect); const {width , height} = entry.contentRect ; console.log(width , height); //新的尺寸 chart.resize(width , height) }) }) ro.observe(document.getElementById('chart')) // 测试耗时 performance.now() // 高精度计时 // 适合测试函数耗时 const start = performance.now(); heavyCalculation(); const end = performance.now(); console.log(`耗时:${end - start} ms`); // 资源加载顺序 , 决定首屏速度 // preload , prefetch // preload 优先 , prefetch 之后可能会用 有空在下载 // vue cli 内置preload , prefetch // public/index.html 适合固定的首屏资源 <link href="/img/banner.png" ref='preload'></link> {/* 图片 , 字体 , 视频封面 */} {/* 所有异步的会自动prefetch */} { path:'/' , name:'home' , // 禁止自动预取 component:()=>import(/* webpackPrefetch:false, webpackChunkName:'home */,'./c.vue') } // cache api + service worker 二次访问很快 , 离线可用 // 第一次走网络 ,第二次缓存 service worker可以拦截请求,cacheapi负责存取缓存 // // web worker 算大数据/做重逻辑 , 可以把计算放到后台 , 主线程继续流畅相应点击/滚动 // 主线程发数据 , worker处理 , 传回结果 // mainjs 主线程 const worker = new Worker('worker.js') worker.postMessage(hugeData) ; worker.onmessage = e => { console.log('处理完成' , e.data); } // workerjs self.onmessage = e => { const res = heavyProcess(e.data) self.postMessage(res) } // document.visibilityState //判断是否在前台 // 如果切换页签 , 接口等就暂停 document.addEventListener('visibilitychange' , ()=>{ if(document.visibilityState === 'hidden') { stopPolling();//停止轮询 stopVideo();//停止动画 }else { //前台 resumePolling(); resumeVideo(); } })