闭包&前端性能优化,你知多少?

8,547 阅读5分钟

这一篇开始总结2019年春季前端面试的高频题型。会以题型+问法/考点+参考答案的形式呈现,如有错漏,希望诸位大佬及时斧正,以正视听。

一.闭包

考点:

什么是闭包

闭包的作用(好处坏处,使用场景)

手写一个闭包

定义(我所认为的): 闭包是指在函数外却能够读取函数内部变量的一种函数现象,它是连接函数内外部的桥梁。

好处: 读取函数内部的变量,并且能让变量的值始终保持在内存中,函数执行完毕后不会被释放

坏处: 常驻内存中,会增大内存的使用量,使用不当会造成内存泄露;另外js对闭包的处理速度会低于普通函数,过度使用闭包也会降低脚本性能。

解决办法: 在退出函数之前,将不使用的局部变量全部删除

使用场景/手写闭包:

白话解释:

有一个函数fn,它有普通属性a(普通变量),也有函数类型的属性fn2。按照js的作用域规则,函数外部想直接获取a是无法获取的,而fn2可以轻松获取到a

因此我们可以通过fn2这个桥梁获取到目标a,这个时候fn2函数就称为闭包

这里有个需要注意的基础前提:fn必须将fn2函数return出来,否则闭包实现失败!\color{#FF3030}{这里有个需要注意的基础前提:fn必须将fn2函数return出来,否则闭包实现失败!}

双手端上来一个栗子:

function fn(){
    var status = '11';
    return {
        Arrive:function(){
            status = '快递已签收';
        },
        Lost:function(){
            status = '快递已丢件';
        },
        getStatus:function(){
            return status;
        },
    }
}
var shunfeng = fn();
console.log(shunfeng.getStatus());//11
shunfeng.Lost();
console.log(shunfeng.getStatus());//快递已丢件
console.log(shunfeng.getStatus());//快递已丢件

再一次调用fn,会发现快递的状态仍旧是'快递已丢件'而并没有被初始化为空字符串,这就是闭包的实际使用场景,即使函数执行完毕后仍然存在。

清除闭包:\color{#FF3030}{清除闭包:} status变量之所以还是“快递已丢件”,是因为当前的“shunfeng”仍有效且仍在引用它,将该引用打断就可以清除闭包。

shunfeng = null;
var shunfeng2 = fn();
console.log(shunfeng2.getStatus());// 11


闭包的使用智者见智,我举的例子比较初级,大家可以自己多动手试试。

好怕我误导你们,这里是阮一峰老师的闭包解读:学习Javascript闭包(Closure)

二.前端性能优化

这个问题出现频率最高,几乎每场面试都问。

问法:

  • 你所知道的前端性能优化有哪些
  • 你在工作中做过的性能优化
  • 你这样做不会影响性能吗
  • 这个有没有提高性能的写法
  • 请从性能方面回答这个问题
  • ……

显而易见,前端性能优化越来越受重视,目前各种流行技术的更新迭代也是围绕性能而进行。然而这个问题的范围太广了,我面试的时候回答得也不太好,我在网上查了很多资料,分别从以下几个方面给出参考答案:

1.减少HTTP请求(这个优化是最明显的)

1) 图片地图,允许在一个图片上关联多个URL,目标URL取决于用户单击的图片上的位置。
2) 雪碧图
3) 合并JS和CSS文件
4) 减少http请求头
5)配置多个域名和CDN加速
6)使用缓存(HTTP缓存、浏览器缓存、应用缓存)
7)优化cookie

参考:segmentfault.com/a/119000000…

2.HTML

1)减少DOM元素数量:页面中存在大量DOM元素,会导致javascript遍历DOM的效率变慢。尤其要尽量少用iframe,它是耗能最大的dom元素,而且会阻塞onload事件
2)使用css+div代替table布局,去掉格式化控制标签如:strongbi等,使用css控制
3)减少不必要的嵌套,尽量扁平化,因为当浏览器编译器遇到一个标签时就开始寻找它的结束标签,直到它匹配上才能显示它的内容,所以当嵌套很多时打开页面就会特别慢。

更多更全HTML性能优化参考:www.cnblogs.com/zzhui/p/504…

3.CSS

关键字: 选择器,高消耗的样式属性,继承,层级,压缩……

www.cnblogs.com/heroljy/p/9…

baijiahao.baidu.com/s?id=160325…

tips: 在回答这两个方面的时候势必会提到 重排和重绘,你的每个回答都有可能是面试官下一个问你的问题。如果当时真的想不起,那就避开,选几个在实际工作中常用的回答,如果你全篇背诵那就有点假了。

3.JS

1)减少全局变量的查找。因为全局变量在作用域链的最顶端,频繁查找很耗性能。
举个栗子:
var globalVar = 1; 
function myCallback(info){ 
    for( var i = 100000;i>0; i--;){ 
        globalVar += i; 
        //每次访问 globalVar 都需要查找到作用域链最顶端,本例中需要访问 100000 次 
    }
}
优化:
var globalVar = 1; 
function myCallback(info){
   var localVar = globalVar; 
   for( var i = 100000; i--;){ 
       localVar += i; 
       //访问局部变量是最快的
   } 
}
2)慎用 with,定时器
3)优化循环
4)少操作DOM
5)字符串拼接

更多更全(我就不做搬运工了):

www.cnblogs.com/cnblogs-jcy…

www.cnblogs.com/wxiaona/p/5…

blog.csdn.net/lululul123/…

www.cnblogs.com/MarcoHan/p/…

4.服务器优化

1)CDN:把网站内容分散到多个、处于不同地域位置的服务器上可以加快下载速度。
2)GZIP压缩
3)设置ETag:ETags(Entity tags,实体标签)是web服务器和浏览器用于判断浏览器缓存中的内容和服务器中的原始内容是否匹配的一种机制。
4)提前刷新缓冲区

5.用户体验

1)预加载,懒加载
2)浏览器缓存,应用缓存
3)细节设计(全选/反全选/自动补全……所有你能想到的)

说明:关于前端性能优化我这里查阅和搜集的资料远远不够,我这里提到的也不全,大家自行搜集吧(哪天我搜集全了更新后会通知大家,谢谢)

附上一位阿里前端的回答:当面试官问你如何进行性能优化时,你该这么回答(一)

最后:

好累啊,今天先写到这里,明天会继续更新,毕竟手里还有好多题目要分享呢~

新鲜出炉面试题,欢迎移步阅读:程序媛面试之高频题型汇总(二)

如果大佬们发现有错误的地方一定要及时指出来,我会在第一时间改正,以免误导他人,谢谢~