从输入url到页面加载完成发生了什么?——前端角度
- 浏览器的地址栏输入URL并按下回车。
- 浏览器查找当前URL的DNS缓存记录。
- DNS解析URL对应的IP。
- 根据IP建立TCP连接(三次握手)。
- HTTP发起请求。
- 服务器处理请求,浏览器接收HTTP响应。
- 渲染页面,构建DOM树。
- 关闭TCP连接(四次挥手)
window.onload和DOMContentLoaded
window.addEventListener('load',function(){
//页面的资源全部加载完成才会执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded',function(){
//dom渲染完即可执行,此时图片、视频还没有加载完成
})
document load和document ready的区别
共同点:这两种事件都代表的是页面文档加载时触发。
异同:ready 事件的触发,表示文档结构已经加载完成(不包含图片等非文字媒体文件)。
onload 事件的触发,表示页面包含图片等文件在内的所有元素都加载完成。
浏览器是如何渲染页面
- 解析HTML文件,创建DOM树。自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
- 解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式<HTML中的style样式;
- 将CSS与DOM合并,构建渲染树(Render Tree)
- 布局和绘制,重绘(repaint)和重排(reflow)
前端性能优化
多使用内存、缓存或其他方法
减少CPU计算量、减少网络加载耗时
- 节流throttle和防抖debounce
- JavaScript 压缩和模块打包
- 按需加载资源
- 缓存
- 使用索引加速数据库查询
- 使用更快的转译方案
- 避免或最小化 JavaScript 和 CSS 的使用而阻塞渲染
- 图片编码优化
图片懒加载
手写防抖debounce
监听一个输入框的,文字变化后触发change事件
直接用keyup事件,则会频繁触发change事件
防抖:用户输入结束或暂停时,才会触发change事件
//js文件
const input1 = document.getElementById('input1')
//let timer = null
//input1.addEventListener('keyup',function(){
// if(timer){
// clearTimeout(timer)
// }
// timer = setTimeout(()=>{
// console.log(input1.value)
// timer = null
// },500)
//})
function debounce(fn,delay = 500){
let timer = null
return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(()=>{
fn.apply(this,arguments)
timer = null
},delay)
}
}
input1.addEventListener('keyup',debounce(function(){
console.log(input1.value)
},600))
节流throttle
拖拽一个元素时,要随时拿到该元素被拖拽的位置
直接用drag事件,则会频繁触发,很容易导致卡顿
节流:无论拖拽速度多快,都会每隔100ms触发一次
//html
<div id="div1" draggable="true">可拖拽</div>
//js
const div1 = document.getElementById('div1')
//let timer = null
//div1.addEventListener('drag',function(e){
// if(timer){
// return
// }
// timer = setTimeout(()=>{
// console.log(e.offsetX,e.offsetY)
// timer = null
// },100)
//})
function throttle(fn,delay = 100){
let time = null
return function(){
if(timer){
return
}
timer = setTimeout (()=>{
fn.apply(this,arguments)
timer = null
},delay)
}
}
div1.addEventListener('drag',throttle(function(e){
console.log(e.offsetX,e.offsetY)
},200))
CSS Sprites
CSS Sprites其实就是把网页中一些背景图片整合拼合成一张图片中,再利用DIV CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位
sprites优势:
- 减少http iis请求数,从而提高页面的性能
- 利用图片精灵还能减少图片的字节
- 在整理图片的过程中,不需要再纠结如此大量图片的名字问题
- 便于后期的维护和修改
sprites缺点:
- 开发的时候比较麻烦,你要通过photoshop(PS)或其他工具测量计算每一个背景单元的精确位置,这是针线活,没什么难度,但是很繁琐。你需要考虑当前盒子会不会漏出其他的背景图,比较头疼的是,页面自适应时,背景图的位置就没那么容易掌控了。
- 在维护的时候比较麻烦,因为他是多张图在一张图上,牵一发而动全身的感觉。轻易不要改变其他图片的位置,原位能放下就在原位改,放不下就在下面添加。
页面导入样式时,使用link和@import有什么区别
- link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;
- 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
- import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题
js延迟加载的方式有哪些?
- defer和async
- 动态创建DOM方式(创建script,插入到DOM中,加载完毕callBack)
- 按需异步载入js
浏览器的内核
- Trident内核:IE最先开发或使用的,也称IE内核 ,360浏览器使用的也是IE内核;
- Webkit内核:谷歌chrome浏览器最先开发或使用,也叫谷歌内核 ,枫树浏览器、太阳花使用的也是谷歌内核;
- Gecko内核: Netscape6开始采用的内核,后来的Mozilla FireFox (火狐浏览器) 也采用了该内核,K-Meleon浏览器也是使用这种内核;
- Presto内核:目前只有Opera浏览器采用该内核
W3c标准
w3c标准不是某一个标准,而是一系列标准的集合。网页主要由结构、表现、行为三部分组成,对应的标准有结构化标准语言有XHTML、xml,表现的标准语言有CSS,行为的标准有对象模型(如 w3c dom)、ECMAScripe等
Css语法结构
CSS的语法结构仅仅由三部分组成
- 选择符(Selector)
- 属性(property)
- 值(value)
常见的web前端攻击方式
- XSS跨站请求攻击
- XSRF跨站请求伪造
XSS跨站请求攻击
攻击原理:
不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)。最后导致的结果可能是:盗用Cookie破坏页面的正常结构,插入广告等恶意内容D-doss攻击。
预防:
替换特殊字符,如<变为<>变为>
<script>变为<script>,直接显示,而不是作为脚本执行
XSRF跨站请求伪造
用户打开浏览器,访问受信任银行网站,输入用户名和密码请求登录网站;
在用户信息通过验证后,银行网站产生Cookie信息并返回给浏览器,此时用户登录网站成功,可以正常发送请求到网站;
用户未退出银行网站之前,在同一浏览器中,打开一个TAB页访问其他网站B
这时候网站B 已被黑客注入诱导信息,加入是一张图片,图片地址指向 src=”http://bank.example/withdraw?... 点击之后转账给黑客这个账户
浏览器在接收到这些攻击性代码请求后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,根据用户的Cookie信息以C的权限处理该请求,导致来自黑客请求恶意代码被执行。预防
使用post接口
增加验证,例如密码、短信验证码、指纹等
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。