zhangzheng-zz / blog

1 stars 0 forks source link

性能优化 #19

Open zhangzheng-zz opened 3 years ago

zhangzheng-zz commented 3 years ago

预加载

prefetch、preload 也可以应用于首屏加载优化

prefetch: 链接预取,利用浏览器空闲时间下载资源并存储到浏览器缓存中。network中会显式 prefetch cache

 <link rel="prefetch" href="static/img/ticket_bg.a5bb7c33.png">

preload: 资源预加载,必须用 as 声明资源类型 font/image/style/script,使得资源被浏览器提前加载。network中会显式资源加载顺序。

 <link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Demi.otf') %>" crossorigin>

js 实现图片预加载,原理是利用浏览器缓存了加载过的图片资源

 function preload (img) {
   return new Promise ((resolve, reject) => {
       const image = new Image()
       image.src = img
       image.onload = function () {
           resolve(image)
       }
       image.onerror = function (e) {
           reject(e)
       }
   })
 }

 function preloadAll (imgs) {
    const arr = []
    imgs.forEach(i => {
        arr.push(preload(i))
    })
    return Promise.all(arr)
 }

js 实现图片懒加载,利用src空的img标签提前占位,等img进入可视界面动态添加src

let imgs = [...document.querySelectorAll('img')]
let length = imgs.length

const imgLazyLoad = (function () {
    let count = 0
    return function () {
        let isLoad = []
        imgs.forEach((image, index) => {
            const rect = image.getBoundingClientRect()
            if(rect.top < window.innerHeight) {
                // 设置 data-src = 'url'
                image.src = image.dataset.src
                isLoad.push(index)
                count ++
            }
            if (count === length) {
                document.removeEventListener('scroll', imgLazyLoad)
            }
        })
        // 过滤已经加载的图片
        imgs = imgs.filter((images, index) => !isLoad.includes(index))
    }
})()
// 防抖处理一下
document.addEventListener('scroll', imgLazyLoad)

DNS 预解析 第三方域名提前解析 DNS

<link rel="dns-prefetch" href="https://cdn.bootcss.com">