社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
来自慕课课程:前端跳槽面试必备技巧
前端面试更多可以查看系列文章:https://blog.csdn.net/lxcao/article/category/6423968/5
1.面试技巧
知识面要广、理解要深刻、内心要诚实、态度要谦虚、回答要灵活、要学会赞美
二面/三面:渲染机制、JS运行机制(JS引擎、JS和浏览器交互和配合)、页面性能、错误监控(代码提交控制、线上环境错误收集也就是错误监控)
2.渲染机制
什么是DOCTYPE及作用?
DTD(document type definition,文档定义类型)是一系列的语法规则,用来定义XML或(X)HTML的文件类型。浏览器会使用它来判断文档类型,决定使用何种协议来解析,以及切换浏览器模式。
DOCTYPE是用来声明文档类型和DTD规范的,一个主要用途便是文件的合法性验证。如果文件代码不合法,那么浏览器解析时便会出一些差错。
常见DOCTYPE声明:
1.HTML 5
<!DOCTYPE html>
2.HTML 4.01 Strict //该DTD包含所有HTML元素和属性,但不包含展示性的和弃用的元素(比如font)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
3.HTML 4.01 Transitional //该DTD包含所有HTML元素和属性,包括展示性的和弃用的元素(比如font)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
浏览器渲染过程?
浏览器工作原理系列文章:https://blog.csdn.net/lxcao/article/category/6472061
还可以查看该文章:https://www.cnblogs.com/aaronjs/archive/2013/06/27/3159789.html
Layout主要是告诉Render Tree(渲染树)每个元素的位置,渲染树的每个元素包含的内容都是计算过的,它被称之为布局layout。
浏览器渲染的过程主要包括一下五步:
需要注意的是,以上五个步骤并不一定一次性顺序完成,比如DOM或CSSOM被修改时,亦或是哪个过程会重复执行,这样才能计算出哪些像素需要在屏幕上进行重新渲染。而在实际情况中,JavaScript和CSS的某些操作往往会多次修改DOM或者CSSOM。
浏览器渲染过程更多可以参考:https://www.imooc.com/article/40004
实例代码和DOM树:
<html>
<head>
<meta name="viewport" content="width=device-width">
<link href="style.css" rel="stylesheet">
</head>
<body>
<p>
Hello <span>web performance</span>
students!
</p>
<div><img src="awesome-photo.jpg"></div>
</body>
</html>
实例代码和CSSOM树:
CSSOM树是显示最后的结果,因为一个元素可能会有两处或多处设置样式。
body{font-size:16px};
p{font-size:bold};
span{color:red}
p span{display:none}
img{float:right}
Render Tree:
DOM+CSSOM+Layout计算最后生成Render Tree。
Layout:
Layout就是计算每个元素的位置、宽高
重排Reflow:
定义
DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow。
触发Reflow
当你增加、删除、修改DOM结点时,会导致Reflow或Repaint
当你移动DOM的位置,或是搞个动画的时候
当你修改CSS样式的时候
当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候
当你修改网页的默认字体时
面试时候可能会问如何尽量减少Reflow。
重绘Repaint:
定义
当各种盒子的位置、大小以及其他属性,例如颜色、字体大小都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。
触发Repaint
DOM改动
CSS改动
面试时候可能会问如何减少Repaint的频率。
布局Layout:
浏览器渲染和浏览器重排和重绘更多可以参考:
https://www.imooc.com/article/40004
https://www.imooc.com/article/45936
https://www.cnblogs.com/cencenyue/p/7646718.html
3.JS运行机制
可以参考文章:
https://segmentfault.com/a/1190000012806637?utm_source=tag-newest
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
https://www.cnblogs.com/MasterYao/p/5563725.html
console.log(1);
setTimeout(function(){
console.log(2);
},0);
console.log(3);
上面的打印顺序是什么? 1 3 2
设计知识点:JavaScript是单线程、任务队列(同步任务队列、异步任务队列)、
console.log('A');
while(true){
}
console.log('B');
//输出结果
A(B执行不到)
console.log('A');
setTime(function(){
console.log("B");
},0);
while(1){
}
//输出结果
A
//这题涉及异步队列被放入时候和执行时间
for(var i = 0;i<4;i++){
aetTimeout(function(){
console.log(i);
},1000);
}
//输出结果
4 4 4 4
for循环是同步任务,上面涉及异步队列执行的时候的概念,setTimeout是异步操作,同步执行完之前是被挂起的,并不执行。而且被没有被放入到异步队列中,直到设定的时间1000ms过后才被放入异步队列,此时i的值并不放入异步队列中去,i到4的时候,同步执行完,且过了设定时间,才执行事件循环中的异步队列。
如何理解JS的单线程
一个时间之内只能干一件事。
什么是任务队列
分同步任务和异步任务
什么是Event Loop
就是事件循环
同步任务放入运行栈中,异步任务不会放入,过了设定时间放入异步任务队列中,同步任务执行完,异步任务队列中任务放入运行栈中,此时异步任务变成了运行栈中的同步任务来执行,栈中空了之后再去监听异步任务队列中有没有,有再去执行,如此循环,这个循环就是Event Loop(事件循环)。
关键点:
1.运行栈执行的是同步任务
2.什么时候去取异步任务队列中任务
3.什么时候去异步队列中放入任务
可以参考文章:
https://www.cnblogs.com/xiaohuochai/p/8527618.html
https://www.cnblogs.com/cangqinglang/p/8967268.html
https://www.cnblogs.com/yugege/p/9598265.html
什么时候执行异步任务?
1.setTimeout和setInterval
2.DOM事件(addEventListener)
3.ES6中的Promise
总结:
理解JS的单线程的概念
理解任务队列(同步任务队列、异步任务队列)
理解Event Loop
理解哪些语句会放入异步任务队列
理解语句放入异步队列的时机(过了设定时间)
4.页面性能
前端性能优化因为涉及到计算机网络、数据算法、图形图像处理、浏览器渲染等多方面计算机知识。
题目:提升页面性能的方法有哪些?
1.资源压缩合并,减少HTTP请求
2.非核心代码异步加载—异步加载的方式—异步加载的区别
3.利用浏览器缓存—缓存的分类—缓存的原理
4.使用CDN
5.预解析DNS
<meta http-equiv="x-dns-prefetch-control" control="on"> //一般浏览器a标签是默认打开DNS预解析,但是使用HTTPS时DNS预解析关闭的,所以添加这一条语句强制开启
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">
异步加载的方式:
1.动态脚本加载
2.defer
3.async
异步加载的区别:
1.defer是在HTML解析完之后才会执行的,如果是多个,按照加载的顺序依次执行
2.async是在加载完之后立即执行,如果是多个,执行顺序和加载顺序无关
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>性能优化</title>
<!-- <script src="./defer1.js" charset="utf-8" defer></script>
<script src="./defer2.js" charset="utf-8" defer></script> -->
<script src="./async1.js" charset="utf-8" async></script>
<script src="./async2.js" charset="utf-8" async></script>
</head>
<body>
<div class="">
test
<script type="text/javascript">
console.log('write');
document.write('<span>write</span>');
</script>
<script type="text/javascript">
for (var i = 0; i < 200000; i++) {
if (i % 20000 === 0) {
console.log(i);
}
}
</script>
</div>
</body>
</html>
浏览器缓存:
1.缓存的分类:
强缓存:(不询问服务端是否过期,直接把缓存拿来用)
Expiress Expires:Thu,21 Jan 2017 23:39:02 GMT(服务端发送的绝对时间)
Cache-Control Cache-Control:max-age=3600(相对时间)
协商缓存:(和服务器问一下,是否过期了)
Last-Modified If-Modified-Since Last-Modified:Wed, 26 Jan 2017 00:35:11 GMT
Etag If-None-Match
, 。
5.错误监控
面试询问如何保证产品质量,就是询问如何错误监控。
前端错误的分类、错误的捕获方式、上报错误的基本原理
前端错误的分类:
1.即时运行错误:代码错误
2.资源加载错误
错误的捕获方式:
1.及时运行错误的捕获方式:try…catch、window.onerrr
2.资源加载错误:object.onerror、performance.getEntries、Error事件捕获
资源加载错误不会触发冒泡,也就是只会触发本身的onerror事件(object.onerror),不会向上触发到window.onerror了。但是可以捕获,所以可以用Error事件捕获。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>错误监控</title>
<script type="text/javascript">
window.addEventListener('error', function (e) {
console.log('捕获', e);
}, false);
</script>
</head>
<body>
<script src="//badu.com/test.js" charset="utf-8"></script>
<script type="text/javascript">
(new Image()).src = 'http://baidu.com/tesjk?r=tksjk';
</script>
</body>
</html>
延伸:跨域的js运行错误可以捕获吗,错误提示什么,应该怎么处理?
报错提示:
解决方法:
1.在script标签增加crossorigin属性(客户端)。
2.设置js资源响应头Access-Control-Allow-Origin:*(服务端)。
上报错误的基本原理:
1.利用Ajax通信的方式上报
2.利用Image对象上报
<script type="text/javascript">
(new Image()).src = 'http://baidu.com/tesjk?r=tksjk';
</script>
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!