运行环境
- 浏览器(server端有nodejs)
- 下载网页代码,渲染出页面,期间会执行若干js
- 要保证代码在浏览器中稳定且高效
主要靠知识点如下:
- 网页加载优化
- 性能和体验优化
- 安全
问题
- 从输入URL到渲染出页面的整个过程
- window.onload和DOMContentLoaded的区别
网页加载
- 加载资源的形式:html代码、媒体文件、js和css
- 加载资源的过程:
DNS解析:域名 => IP地址
浏览器根据IP地址向服务器发起http请求
服务器接受处理http请求,并返回给浏览器 - 渲染页面的过程:
根据html代码生成DOM树
根据CSS代码生成CSSOM树
将DOM树和CSSOM树整合为render树(渲染树)
浏览器根据render树渲染页面
遇到script则暂停渲染,优先加载并执行js代码,完成之后再继续,直至把渲染树渲染完成
思考:为何不把css放在body中,而放在head中?
防止重复构建渲染树
思考:为什么要把js放在body之后?
给用户更好的体验,先渲染所有的内容
4. window.onload和DOMContentLoaded:
前者需要页面的所有资源全部加载完毕才执行,包括图片和视频等;后者DOM渲染完即可执行,此时图片和视频可能没有加载完
性能优化
- 性能优化原则:
- 多使用内存、缓存或其他方法
- 减少CPU计算量,减少网络耗时
- 从何入手:
- 让加载更快:
- 减少资源体积:压缩代码
- 减少访问次数:合并代码,SSR服务端渲染,缓存(contenthash、cdn)
- 让渲染更快:
- css放在head,js放在body最下面
- 尽早执行js,在DOMContentLoaded触发
- 懒加载
- 对DOM查询进行缓存
- 频繁的DOM操作合并到一起插入DOM结构
- 节流和防抖
// 防抖,通过闭包实现timer不可被外部修改,只执行最后一次 function debounce(fn, delay) { let timer = null return function () { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments) }, delay) } } // 节流,不论事件如何触发,只周期性地触发 function throttle(fn, delay = 100) { let timer = null return function () { if (timer) { return } timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, delay) } }
- 让加载更快:
安全
- 常见web前端的攻击方式
- xss跨站请求攻击
通过嵌入脚本的方式将cookie发送到自己的服务器,预防方法:将<
、>
替换为<
和>
- xsrf跨站请求伪造
配合接口,当用户查看某一信息时,就形成了xsrf。xsrf预防通常采用 post方法,增加验证方法等
- xss跨站请求攻击