渲染/性能/安全相关|青训营笔记

25 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第8天

从输入url到渲染出页面的过程

加载过程:

  1. DNS解析url,将域名转为IP地址
  2. 浏览器根据IP地址向服务器发起http请求
  3. 服务器处理http请求,并返回给浏览器

渲染过程:

  1. 网页根据HTML代码生成DOM树
  2. 根据CSS代码生成CSSOM树(CSS对象模型)
  3. 通常情况下DOM和CSSOM是并行构建的
  4. 将DOM和CSSOM整合成render树
  5. 根据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>脚本

  • 预防:对输入内容进行转义,替换特殊字符,例如 < > 分别替换为 &lt; &gt;,防止<script>标签执行

CSRF(Cross-site request forgery,跨站请求伪造) :攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的

  • 预防:提交请求时携带token、增加验证(如密码、验证码等)