这是我参与「第五届青训营 」伴学笔记创作活动的第8天
从输入url到渲染出页面的过程
加载过程:
- DNS解析url,将域名转为IP地址
- 浏览器根据IP地址向服务器发起http请求
- 服务器处理http请求,并返回给浏览器
渲染过程:
- 网页根据HTML代码生成DOM树
- 根据CSS代码生成CSSOM树(CSS对象模型)
- 通常情况下DOM和CSSOM是并行构建的
- 将DOM和CSSOM整合成render树
- 根据render树渲染页面,遇到script标签则先暂停渲染,执行完js代码再渲染(因为js执行和页面渲染线程互斥)
tips:
- js代码最好放在body最后,以免操作DOM时某些节点没渲染完;
- css代码放在body之前(一般放在head中),避免重复渲染
性能优化
加载更快:减少资源体积,比如压缩/合并代码、使用缓存(如在文件名中使用hash)
渲染更快:懒加载(如下滑到末端才加载)、节流防抖、合并多个DOM操作、服务端渲染(SSR)
debounce/throttle
防抖debounce: 将高频操作合并为一次
- 场景:输入框输入
节流throttle: 将高频操作按周期执行
- 场景:按钮点击,一秒点击 10 下会发起 10 次请求,节流以后 1 秒内点再多次,都只会触发一次
function debounce(fn, delay = 500){
let _timer = null
// 不要用箭头函数,否则arguments会变成外层的,this指向也有问题
return function(){
if(_timer) clearTimeout(_timer) // 改成return就是throttle
_timer = setTimeout(()=>{
fn.apply(this, arguments)
_timer = null
}, delay)
}
}
// 使用
let inp = document.getElementById('input1')
inp.addEventListener('keyup', debounce(()=>{
// 停止输入0.5s后才获取值
console.log(inp.value)
}))
let drag = document.getElementById('drag1')
drag.addEventListener('drag',throttle((e)=>{
// 至少隔0.5s获取一次值
console.log(e.offsetX, e.offsetY)
}))
XSS/CSRF攻击
XSS(Cross-Site Scripting,跨站脚本攻击) :向网页注入恶意代码,如用户的输入中包含<script>
脚本
- 预防:对输入内容进行转义,替换特殊字符,例如
<
>
分别替换为<
;>
;,防止<script>
标签执行
CSRF(Cross-site request forgery,跨站请求伪造) :攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的
- 预防:提交请求时携带token、增加验证(如密码、验证码等)