加载过程
- DNS 解析:域名→IP 地址
- 浏览器根据 IP 地址向服务器发起 http 请求
- 服务器处理 http 请求,并返回给浏览器
渲染过程
- 根据 HTML 代码生成 DOM Tree
- 根据 CSS 代码生成 CSSOM
- 将 DOM Tree 和 CSSOM 整合成 Render Tree
- 根据 Render Tree 渲染页面
- 遇到<script>则暂停渲染,优先加载并执行 js 代码,完成再继续
- 直到 Render Tree 渲染完成
windows.onload 和 DOMContentLoaded 的区别
- windows.onload 资源全部加载完才能执行,包括图片视频等
- DOMContentLoaded DOM 渲染完成就执行,图片视频可能还未下载
性能优化原则
- 多使用内存、缓存或其他方法
- 减少 CPU 计算量,减少网络加载耗时
- (适用于所有的编程性能优化——空间换时间)
让加载得更快
- 减少资源体积:压缩代码
- 减少访问次数:合并代码,SSR 服务端渲染(将网页和数据一起加载,一起渲染),缓存
- 使用更快的网络:CDN
让渲染的更快
- CSS 放在 head,JS 放在 body 最下面
- 尽早开始执行 JS,用 DOMContentLoaded 触发
- 懒加载(图片懒加载)
- 对 DOM 查询进行缓存
- 频繁 DOM 操作的,合并到一起插入 DOM 结构
- 节流 throttle 防抖 debounce
防抖 debounce
- 监听一个输入框的文字变化后触发 change 事件
- 直接监听,会频繁触发
- 防抖,当用户输入结束或者暂停输入是,才会触发change 事件
function debounce(fn, delay = 500) {
let timer = null;
return function() {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
let input1 = document.getElementById('input1')
input1.addEventListener('keyup', debounce(() => {
console.log(input1.value);
}))
节流 throttle
使用场景:
- 拖拽一个元素时,要随时拿到该元素被拖拽的位置
- 直接使用drag事件,则会频繁触发,容易导致卡顿
- 节流,无论速度多快,每隔 100ms 触发一次
function throttle (fn, delay = 100) {
let timer = null
return function () {
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
let drag1 = document.getElementById('drag1')
drag1.addEventListener('drag', throttle((e) => {
console.log(e.offsetX, e.offsetY)
}))
安全
XSS 攻击
场景:一个博客网站,被人嵌入<script>脚本,脚本内容,获取 cookie,发送到攻击者的服务器
预防:替换特殊字符,如 < 变为 < > 变为 >
XSRF 攻击
场景:商品购买链接,没有任何验证,则可以伪造该链接诱导用户点击
预防:使用 post 接口,增加验证,如密码、验证码