面试题总结

86 阅读3分钟
有做过前端加载优化工作吗?都做过哪些努力
  • 首屏时间
  • 首次可交互时间
  • 首次有意义内容渲染时间
  • 只请求当前需要的资源;

    • 异步加载/懒加载/polyfill
  • 缩减资源体积

    • 打包压缩/webpack/gzip(减少资源大小的方法)
    • 图片格式的优化,压缩,根据屏幕分辨率展示不同分辨率的图片
    • webp(怎么转为webp,怎么判断浏览器是否支持webp)
    • 尽量控制cookie的大小, request header, cookie
  • 时序优化

    • js / promise.all / ssr / prefetch / prerender / preload

      • 预解析dns
  • 合理利用缓存

    • cdn,cdn预热,cnd刷新
  • 如果一段js执行时间特别长,怎么去解析

    • 装饰器
  • webp

    • 阿里云oss支持通过链接后边拼接参数来做图片的格式转换,尝试写一下,把任意图片格式转成webp,需要注意什么

      • 考虑浏览器的适配

        function checkWebp(){
            try {
                return (
                    document.createElement('canvas') // 新建canvas元素,它可以很简单的将图片转为base64
                    .toDataURL('image/webp')
                    .indexof('data:image/webp') === 0; 支持webp
                );
            } catch (e) {
                return false;
            }
        }
        ​
        const supportWebp = checkWebp();
        export function getWebpImageUrl(url) {
            if(!url) {
                throw Error('url 不能为空');
            }
            if(url.startsWith('data:')) { // 判断是否是base64
                return url;
            }
            if(!supportWebp) {
                return url;
            }
            return url + '?x-oss-pro...'
        }
        
  • 如果有巨量的图片需要展示,除了懒加载的方式,有没有什么其他方法限制一下同时加载的图片数量?

    // 设置我们要执行的任务
    function loadImg(url) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resove();
            }, url.time)
        })
    }
    ​
    function limitLoad(urls, hander, limit) {
        const sequence = [].concat(urls); // 拷贝一次,防止改变原数组
        let promises = [];
        promises = sequence.splice(0, limit).map(url, index) => {
            return hander(url).then(() => {
                return index;
            })
        }
        
        let p = Promise.race(promises); // 竞速,选出最先执行完的
        for(let i=0; i<sequence.lenght; i++) {
            p = p.then((res) => {
                promises[res] = handler(sequence[i]).then(() => {
                    return res;
                })
                return Promise.race(promises)
            })
        }
        
    }
    
平时关注过内存处理吗
  • 内存的生命周期

    • 内存分配:声明变量、函数、对象的时候,js会自动分配内存
    • 内存使用:调用的时候,使用的时候
    • 内存回收
  • JS中的垃圾回收机制

    • 引用计数垃圾回收(判断不在使用的对象)

      • a对象对b对象有访问权限,那么成为a引用b对象
      • 判断对象有没有被引用
      • 缺陷:循环引用的无法回收,造成泄露
    • 标记清除算法(判断无法达到的对象,无法达到,说明可以回收了)

      • 在运行的时候给存储在内存的所有变量加上标记
      • 从根部触发,能触及的对象,把标记清除
      • 那些有标记的就被视为即将删除的变量
  • JS中有哪些常见的内存泄露

    • 全局变量
    • 未被清除的定时器和回调
    • 闭包
    • dom的引用
  • 如何避免内存泄漏

    • 减少不必要的全局变量
    • 使用完数据候,及时解除引用
  • 实现sizeOf函数,传入一个参数object,计算这个Object占用了多少bytes?

    number64位存储,占用8个字节
    string:每个长度2个字节
    boolean4个字节
    -----------------------------------------------
    const testData = {
        a: 111,
        b: 'ccc',
        222: false
    }
    ​
    function sizeOf(object) {
        const objectType = typeof object;  // Object.prototype.toString
        switch(objectType) {
            case 'string': {
                return object.length * 2;
            }
            case 'boolean': {
                return 4
            }
            case 'number': {
                return 8;
            }
            case 'object': {
                if(Array.isArray(object)) {
                    return object.map(sizeOf).reduce((res, current) => {
                        res + current, 0
                    });
                } else {
                    return sizeOfObject(object)
                }
            }
        }
    }
    ​
    function sizeOfObject(object) {
        if(object === null) {
            return 0;
        }
        let bytes = 0;
        // 对象里的key也是占用内存空间的
        
    }
    
  • polyfill.io/v3/polyfill… 只需要用script引入,就能自动解析,不需要配置webpack。 实现了对polyfill的按需加载
  • 页面性能检测工具:pagespeed/insights

111

11

22

22

\