## 运行环境(浏览器)
1. 浏览器可以通过访问链接来得到 页面的内容
2. 通过绘制和渲染,显示出页面的最终的样子
3. 过程中的问题?
### 知识点
1. 页面加载过程
2. 性能优化
3. 安全性
#### 页面加载
1. 从输入url到得到html的详细过程
2. window.onload和DOMContentLoaded的区别
#### 知识点
1. 加载资源的形式
2. 加载一个资源的过程
3. 浏览器渲染页面的过程
##### 加载资源的形式
* 输入url(或跳转页面)加载html
* 输入链接
* 加载html中的静态资源
* script css 媒体资源(img video)
#### 加载一个资源的过程
1. 浏览器根据DNS服务器得到域名的IP地址
* baidu.com ==> ip地址 (ip地址相当于服务器)
2. 向这个ip的机器发送http请求
3. 服务器收到,处理并返回http请求
4. 浏览器得到返回内容
#### 浏览器渲染页面的过程
1. 根据HTML结构生成DOM Tree(dom树是什么?)
2. 根据css生成 CSSOM(将css静态代码进行结构化处理 object model)
3. 将DOM和CSSOM整合RenderTree!!(渲染树)
区别:(dom树只是一个树形结构,没有规定每个dom节点的样式是什么,dom树和cssom结合起来,生成渲染树,渲染树在结构上和dom树是一致的树形结构,但是每个节点中样式(长宽高...)都在渲染树里,)(dom树是html代码的结构化,没有样式)(render树会有样式,cssom规定了它的样式)
(浏览器渲染页面时,要知道页面的结构是什么,也要知道样式的结构是什么)
4. 根据RenderTree开始渲染和展示
5. 遇到`<script>`时,会执行并**阻塞渲染**(单线程,因为js有权利改变dom结构,和html渲染冲突,因此要阻塞渲染)
##### 示例
1. 加载html代码
2. 分析,head不用渲染,但head中有css,先加载css文件(渲染是顺序执行),加载出来后解析(cssom),浏览器已经知道遇到div要怎样怎样,css已经解析完了,再渲染div的时候,在已知样式的情况下,**对div一次性渲染**。head中的css会先加载解析,此时浏览器已经知道规则,再渲染dom结构时,对拿到的div节点生成dom结构时,已经知道了cssom结构,一下子生成渲染树,渲染出来
3. 思考:为何把css放在head中?
规定:把css放在head中(body出来之前,把css拿到),加载完css,浏览器直接知道规则,渲染body时,已经把规则考虑进去渲染,
如果放在body下面或里面:渲染body后再渲染css,样式先会默认渲染,再重新渲染,(电脑配置,网络情况,页面规模,会影响体验),用户体验和性能都很差(能一次干的事要两次干)
4. script放在body中,div之间:遇到script停止渲染,加载执行script,阻塞浏览器的渲染(script有权利操作dom(改变结构或内容),浏览器不得不阻塞停止渲染),script如果改后面的div,会出错
5. 为何要把script放在body最下面(即将结束的位置)(性能优化问题)
* 不会阻塞页面渲染(body内前面的内容),没有执行script,先把html结构渲染出来,不会阻塞页面(性能为题)
* 把script放在最下面,script能拿到所有的标签(放上面script拿不到下面标签)
6. 插入图片
* 加载html内容
* 开始渲染,图片是异步请求,并不会阻碍dom树的渲染,但img标签可用
#### window.onload和DOMContentLoaded
~~~
window.addEventListener('load',function({
// 页面的全部资源加载完成才会执行,包括页面,视频等异步加载
}))
document.addEventListener('DOMContentLoaded',function(){
// DOM渲染完即可执行,此时图片、视频可能没有加载完
})
~~~
#### 解答
1. 从输入到得到html的详细过程
* 浏览器根据DNS服务器得到域名的IP地址
* 向这个Ip的技巧发送http请求
* 服务器收到、处理并返回http请求
* 浏览器得到返回内容
2. window.onload和DOMContentLoaded(尽量用第二种)
* 页面的全部资源加载完才会执行,包括图片、视频等
* DOM渲染完即可执行,此时图片、视频还没加载完
zepto/jquery如何判断页面加载完,它们用的是(DOMContentLoaded)
### 性能优化
* 综合性问题
* 没有标准答案,很多
* 只关注核心点,针对面试
#### 原则
1. 多使用内存、缓存(内存存储,不是硬盘)或者其他方法
2. 减少 cpu 计算、减少网络
#### 哪里入手
* 加载页面和静态资源(加载更快)
* 页面渲染
#### 加载资源优化
1. 静态资源的压缩合并(三个js文件,可以合并成一个,耗费一个请求)(压缩)
2. 静态资源缓存(资源名字不变,本地会有缓存,浏览器策略,第二次加载不会重新加载,文件名发生变化会重新请求)(减少请求)
3. 使用CDN让资源加载更快(大网站,有自己的,小网站用网上的)(为什么?CDN是不同区域的网络优化,北京访问地址,会就近找到CND进行加载)(距离远走的路由器比较多)
4. 使用SSR后端渲染,数据直接输出到HTML中(以前ssr:server site render,jsp,php,asp)
#### 渲染优化
1. css放前面,js放后面
2. 懒加载(图片懒加载、下拉加载更多)(什么时候用,什么时候加载)
3. 减少DOM查询,对DOM查询做缓存
4. 减少DOM操作,多个操作尽量合并在一起执行
(DOM操作是非常非常昂贵的)
5. **事件节流**()
6. 尽早执行操作(如DOMContentLoaded)
#### 示例讲解
1. 资源合并
CommonJS合并(模块化)
~~~
// 发送三个请求
<script src="a.js"></script>
<script src="b.js"></script>
<script src="c.js"></script>
// 发生一个请求
<script src="abc.js"></script>
~~~
2. 缓存
* 通过连接名称控制缓存
* `<script src="abc_1.js"></script>`(名字不变,不会重新下载)
* 只有内容改变的时候,链接名称才会改变
* `<script src="abc_2.js"></script>`
3. CDN
**bootcss**
4. 使用SSR后端渲染(vue,react)
* 现在vue react提出了这样的概念
* 其实jsp php asp都属于后端渲染
* 动态页面(数据直接输出到页面中,没必要ajax请求数据)
5. 懒加载
原理:其实src是赋值很小的preview的图片,真正的图片地址是放在data属性之后的,用的时候把data属性拿过来替换原理的src,会加快渲染速度
~~~
<img id="img1" src="preview.png" data-realsrc = "abc.png" />
<script>
var img1 = document.getElementById("img1");
img1.src = img1.getAttribute("data-realsrc");
</script>
~~~
6. 缓存DOM查询
~~~
// 未缓存dom查询(每次循环都进行一次dom查询)
var i;
for(var i=0; i<document.getElementByTagName('p').length;i++){
// todo
}
// 缓存了DOM查询
var pList = document.getElementsByTagName('p');
var i;
for(var i=0; i<pList .length;i++){
// todo
}
~~~
7. 合并DOM插入
~~~
var lisNode = document.getElementById("list");
//要插入10个list标签
var frag = document.createDocumentFragment();
var x,li;
for(x=0; x<10; x++){
li = document.createElement('li');
li.innerHTML = "list item"+x;
frag.appendChild(li);
}
listNode.appendChild(frag);
~~~
**document.createDocumentFragment();**//临时片段,它的appendChild不会触发dom操作
10次dom插入变成1次
8. 事件节流(减少cpu计算)
快速操作的时候,不要执行事件,什么时候执行什么时候操作,会提高性能
keyup触发事件操作,不要每次都触发,可以有个时间间隔
停下来(超过100ms以上)时触发change操作
~~~
var textarea = document.getElementById('text');
var timeoutId;
textarea.addEventListener('keyup', function(){
if(timeoutId){
clearTimeout(timeoutId)
}
timeoutId = setTimeout(function(){
// 触发change事件
}, 100)
})
~~~
9. 尽早操作 DOMContentLoaded(0.1s) load(2s)
### 安全性 -XSS(优先级比较低)
综合性问题:场景的前端安全问题有哪些
1. XSS跨站请求攻击
2. XSRF跨站请求伪造
后端来防,前端配合
#### XSS
* 新浪博客写文章,同时偷偷插入一段`<script>`
* 攻击代码中,获取cookie,发送自己的服务器(查看文章时,代码执行,获取cookie,一般会有账户信息,发送到自己的服务器)
* 发布博客,有人查看博客内容
* 会把查看者的cookie发送到攻击者的服务器(拿到很多人的账号)
原理:输入脚本,脚本中有攻击代码,获取信息发送到自己的服务器
解决:
1. 前端替换关键字,例如替换 < 为` <` >为 `>`不是很好,因为会影响性能,js执行效率比较低,前端只有浏览器,后端有强大的服务器
2. 后端替换(依赖于服务器的能力)
#### XSRF
* 登录一个购物网站,正在浏览商品
* 该网站付费接口是xxx.com/pay?id=100但是没有任何验证
* 然后你收到一个邮件,隐藏着`<img src=xxx.com/pay?id=100 />`请求悄悄付费,你的钱已经没有了
* 你查看邮件的时候,就悄悄付费了
解决方案
1. 增加验证流程,如输入指纹,密码,短信验证码(前端做接口,后端做功能)
- 空白目录
- 双樾
- JS基础知识
- JS-WEB-API
- 开发环境
- 运行环境
- ES6
- 原型
- 异步
- 虚拟dom
- mvvm
- 组件化和React
- hybrid
- 其他
- 补充
- 技巧
- 快乐动起来呀
- css
- 掘金小册子
- js基础知识
- ES6知识点
- JS异步
- JS进阶知识
- 思考题
- DevTools Tips
- 浏览器基础知识
- 浏览器缓存机制0
- 浏览器渲染原理
- 安全防范知识点0
- 从V8中看JS性能优化0
- 性能优化琐碎事
- Webpack性能优化0
- 实现小型打包工具0
- React和Vue
- Vue生命周期
- vue基础知识点
- Vue响应式
- vue高级
- React基础
- Vue.js技术解密
- 准备工作
- 数据驱动
- new Vue()
- vue实例挂载
- 组件化
- 深入响应式原理
- 编译
- 扩展
- Vue Router
- Vuex