运行环境
--浏览器可以通过访问链接来得到页面的内容;(上线的代码产生的内容)
--浏览器通过绘制和渲染,显示出页面的最终的样子;
--整个过程中,我们需要考虑什么问题?(浏览器内核情况)
1.页面加载过程
1.1.从输入url到得到html的详细过程
1.浏览器根据DNS服务器(解析出)得到域名的IP地址
2.向这个IP的机器发送http请求
3.服务器收到、处理并返回http请求
4.浏览器得到返回内容
1.2.window.onload 和 DOMContentLoaded 的区别
都是页面加载之后要触发什么事件;
window.addEventListener('load',function(){
//页面的全部资源加载完才会执行,包括图片、视频等
});
document.addEventListener('DOMContentLoaded',function(){
//DOM 渲染完即可执行,此时图片、视频还可能没有加载完
});
2.1.加载资源的形式
1.-输入url(或跳转页面)加载html
http://coding.m.imooc.com
2.-加载html中的静态资源
<script src="/static/js/jquery.js"></script>
2.2.加载一个资源的过程
都符合1.浏览器根据DNS服务器(解析出)得到域名的IP地址
2.向这个IP的机器发送http请求
3.服务器收到、处理并返回http请求
4.浏览器得到返回内容
2.3.浏览器渲染页面的过程
1.根据HTML结构生成DOM Tree(只有结构)
2.根据css生成CSSOM(样式)
3.将DOM 和 CSSOM 整合形成RenderTree(渲染树)
4.根据RenderTree 开始渲染和展示
5.遇到<script>时,会执行并阻塞渲染
(浏览器渲染一个DOM树,script中js有权利改变DOM结构和内容,我们不得不让浏览器
去做出一个妥协性的让步,js在加载执行中,渲染先结束先阻塞先不要管它)
*页面加载--几种示例
1.<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p>test</p>
</body>
</html>
2.div{
width:100%;
height:100px;
font-size:50px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="styleSheet" type="text/css" href="test.css">
</head>
<body>
<div>test</div>
</body>
</html>
3. document.getElementById('container').innerHTML == 'update by js';
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="container">default</div>
<script src="index.js"></script>
<p>test</p>
</body>
</html>
*首先你输入url(或跳转页面)把html代码加载出来,浏览器要解析,到body里面
开始渲染了,body里第一行渲染出一个div内容是default,到body里第二行发现一
个script,停下来加载script,(第三行代码就一直等着)加载完并执行完之后,最后
一行才正式渲染出来。
4.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<p>test</p>
<p>![](test.png)</p>
<p>test</p>
</body>
</html>
加载完html结构之后就开始渲染,body中第一行图片是异步请求的,比如这个test.png
很大,请求的很慢,这个时候并不会阻碍整个dom树的一个渲染,渲染body第一行ok结束
,渲染第二行结束,img标签已经有了,只不过图片还没有加载出来而已,这个img标签
已经可以用了,这个时候图片是异步加载,我们在渲染第三行。
1.为什么要把css放在head中?
加载css之后,浏览器直接知道规则,在渲染下面的DOM结构的时候就会把这些结构考虑
进去去渲染;(css一定要在body里面的东西出来之前就加载完,而且这个规则要告诉
浏览器,加载完之后浏览器就自己知道了,然后再body渲染的时候,一次就把这个事干好)
2.为什么要把js放在body最下面?
1.不会阻塞之前的body内容,因为内容(没有script执行,先把html结构基本的一些
标签渲染出来,最后在执行script,这个时候就不会阻塞了,能让页面更快的出来,
这是性能的问题)已经渲染;
2.把script放在最后能拿到所有的标签
2.性能优化(本身是一个综合性的问题)
原则:
1.多实用内存(内存的存储)、缓存或者其他方法
2.减少CPU计算、减少网络请求
从哪里入手:
1.加载页面和静态资源
--静态资源的压缩合并;
--静态资源缓存;(本地有缓存就没有必要在请求一次)
--使用CDN让资源加载更快(CDN是一个不同区域的网络优化,如果我在北京访问一个
地址的时候,同样的一个地址CDN会给我转到北京就近的一个机房中加载下来;如果
没有CDN,你的服务器就在杭州,我从任何一个地方的请求都需要走杭州的一个机房,
距离比较远,经过的路由器就比较多,也就比较慢一些)
--使用SSR(server side rander 服务端渲染)后端渲染,数据直接输出到HTML中
2.页面渲染(渲染优化)
--css放前面,js放后面
--懒加载(图片懒加载、下拉加载更多);
图片先不加载,什么时候用什么加载;
--减少DOM查询,对DOM查询做缓存;
--减少DOM操作,多个操作尽量合并在一起执行;
--事件节流(很频繁的操作合到一个操作);
--尽早执行操作(如 DOMContentLoaded)
DOM渲染完就立即执行,不管前端资源像图片有没有加载完
性能优化--几个示例:
1.--资源合并
<scirpt src="a.js"></script>
<scirpt src="b.js"></script>
<scirpt src="c.js"></script>
代码合并成(构建工具来合并):
<script src="abc.js"></script>
2.--缓存
1.通过连接名称控制缓存
<script src="abc_1.js"></script>
2.只有内容改变的时候,链接名称才会改变
<script src="abc_2.js"></script>
3.--使用CDN (比在服务器上做zepto连接要快很多)
<link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="styleSheet">
<script src="https://cdn.bootcss.com/zepto/10rc1/zepto.min.js"></script>
4.--使用SSR后端渲染
(好处:把数据直接输出到html中,浏览器能直接拿到,直接渲染,没必要ajax把数据在获取一遍)
1.现在Vue React(这两个默认没有后端渲染的) 提出了这样的概念:
先把模板拿下来之后通过ajax获取数据
2.jsp php asp都属于后端渲染(动态页面--我们的数据可以直接输出到浏览器,不用再通过ajax获取)
**5.--懒加载 **
![](preview.png)
<script type="text/javascript">
var img1 = document.getElementById('img1');
img1.src = img1.getAttribute('date-realsrc');
</script>
一开始的图片是显示很小的图,很快就加载出来,但这个图片真正用的时候在把这个真正的图片赋值过来让它显示就行;
加快页面渲染速度;
6.--缓存DOM查询
//未缓存DOM查询(每次循环都需要执行DOm查询)
//执行每一次循环,document.getElementsByTagName('p')都要做一次查询
var i;
for(i=0;i<document.getElementsByTagName('p').length;i++){
//todo
};
//缓存了DOM查询(一次DOM查询把东西存到一个变量中,下次循环就没有必要在挨个做DOM查询了,
只是获取这个变量的属性就可以了)
//直接把东西查询出来缓存到pList中,就查询一次,下面在执行10遍循环的时候
,就不会在去执行查询了,只需从缓存的pList去取就行了,这就快了。
var pList = document.getElementsByTagName('p');
var i ;
for(i=0;i<pList.length;i++){
//todo
}
7.--合并DOM插入(本来有10次dom查询,现在只剩一次了)
var listNode = document.getElementById('list');
//要插入10个li标签
(定义一个临时片段,10次循环只用对片段中去加,不会触发DOM操作)
var frag = document.createDocumentFragment();
var x,li;
for(x=0;x<10;x++){
//定义一个片段,10个li依次插入片段中
li = document.createElement("li");
li.innerHTML = "List item"+x;
frag.appendChild(li);
}
//把片段插入listNode
listNode.appendChild(frag);
8.--事件节流(性能优化的原则,减少cpu的计算
var textarea = document.getElementById('text');
var timeoutId;
textarea.addEventListener('keyup',function(){
//每次看看timeoutId有没有,有了就先清掉
if(timeoutId){
clearTimeout(timeoutId);
}
//当输入完停下来这个时候触发change事件;
//重新赋值timeoutId,设个100毫秒的延迟;如果一旦停大于100毫秒以上就触发change事件;
timeoutId = setTimeout(function(){
//触发change事件
},100);
});
9.--尽早执行操作
window.addEventListener('load',function(){
//页面的全部资源加载完才会执行,包括图片、视频等
});
document.addEventListener('DOMContentLoaded',function(){
//DOM 渲染完即可执行,此时图片、视频还可能没有加载完
});
3.安全性
1.--场景的前端安全问题有哪些?
1.1.XSS跨站请求攻击
eg:1.新浪博客写一篇文章,同时偷偷插入一段<script>
(一旦看这篇文章,代码就会执行;获取cookie,发送自己的服务器,多少人看了这篇文章,就能获取多少用户信息)
----攻击代码中,获取cookie,发送自己的服务器;
----发布博客,有人查看博客内容;
----会把查看着的cookie发送到攻击者的服务器;
*怎么预防:
--前端替换关键字,例如替换 < 为 < > w为 >(会影响性能,js执行效率比较低,前端只有浏览器)
--后端替换(依赖于服务器的能力)
1.2.XSRF跨站请求伪造
eg:你已登录一个购物网站,正在浏览商品
----该网站付费接口是 xxx.com/pay?id=100 但是没有任何验证;
----然后你收到一封邮件,隐藏这<img src=xxx.com/pay?id=100>;
----你查看邮件的时候,就已经悄悄的付费购买了。
*解决方案:
--1.增加验证流程,如输入指纹、密码、短信验证码(后端来做验证,前端配合)
****************面试技巧****************
1.简历
1.1简洁明了,重点突出项目经历和解决方案;
(项目经历:做过什么东西要写明白,可以通过你做的东西了解到你,这个项目真实的技术等级、技术复杂度)
(解决方案:在项目中做了什么贡献,遇到什么样的问题,用什么解决的(用的什么框架来做,技术栈、解决方案))
1.2.把个人博客放在简历中,并且定期维护更新博客
1.3.把个人的开源项目放在简历中,并维护开源项目
1.4.简历千万不要造假,要保持能力和经历上的真实性
2.面试过程中。。。
2.1.如何看待加班?加班就像借钱,救急不救穷
(加班作为常态那就不行了,加班会很累,压力会比较大,睡不好;
根本没有业余时间去提高自己的能力)
2.2.千万不要挑战面试官,不要反考面试官
2.3.学会给面试官惊喜,但不要太多
2.4.遇到不会回答的问题,说出你知道的也可以
比如:性能优化 知道多少说出来多少
2.5.谈谈你的缺点——————说一下你最近正在学什么就可以了
比如:最近在学react
可能对react还不是很了解,现在正在学,大约一个月之后就能做出来一个react网站;