优化问题
- 加载优化
压缩 合并 减少请求 缓存 无阻塞(script放到后面)
预加载 fontIcon 使用cdn资源 - css 优化
减少嵌套 精简去掉空css
字体尽量少 字体大小尽量少 - js优化
- 减少重绘和重排
- 避免不必要的Dom操作
- 尽量改变Class而不是Style,使用classList代替className
- 避免使用document.write
- 减少drawImage
- 缓存Dom选择与计算,每次Dom选择都要计算,缓存他。
- 缓存列表.length,每次.length都要计算,用一个变量保存这个值。
- 尽量使用事件代理,避免批量绑定事件。
- 尽量使用ID选择器,ID选择器是最快的。
- TOUCH事件优化,使用touchstart、touchend代替click,因快影响速度快,但应注意Touch响应过快,易引发误操作。
- 减少重绘和重排
- 渲染优化
- 减少Dom节点
- 动画优化
1. 尽量使用CSS3动画。
2. 合理使用requestAnimationFrame动画代替setTimeout。
3. 适当使用Canvas动画5个元素以内使用css动画,5个以上使用Canvas动画 - 高频事件优化
Touchmove、Scroll事件可导致多次渲染。- 使用requestAnimationFrame监听帧变化,使得在正确的时间进行渲染。
- 增加响应变化的时间间隔,减少重绘次数。
- GPU加速
CSS中以下属性(CSS3 transitions、CSS3 3Dtransforms、Opacity、Canvas、WebGL、Video)来触发GPU渲染,请合理使用。(PS:过渡使用会引发手机过耗电增加。)
浏览器渲染流程

- 浏览器会将HTML解析成一个DOM树,DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
- 将CSS解析成 CSS Rule Tree 。
- 根据DOM树和CSSOM来构造 Rendering Tree。注意:Rendering Tree 渲染树并不等同于 DOM 树,因为一些像Header或display:none的东西就没必要放在渲染树中了。
- 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操作称之为layout,顾名思义就是计算出每个节点在屏幕中的位置。
- 再下一步就是绘制,即遍历render树,并使用UI后端层绘制每个节点。
重绘与重排
- 影响重排
- DOM元素的几何属性变化
- DOM树结构变化
- 获取某些属性
offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、 clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。 - 窗口大小变化
- 影响重绘
影响外观 (颜色变化 是否显示等问题),例如改变visibility, outline, background等属性 - 解决方式
- 避免在document上直接进行频繁的DOM操作, 如果确实需要可以采用off-document方式进行;
- 集中修改样式
- 缓存影响重排的属性值
- 设置position为absolute或者fixed
- 不要使用table布局
- 不要在css中写expression
- 监测方法
chrome调试工具 Performance
js内存回收机制与内存控制
- 垃圾回收是定期执行
- IE6 是按照对象个数触发垃圾回收
- IE7 判断内存比例的临界值
- 回收方法
- 引用计数 每次引用加1 去掉引用减1 没有引用则可以回收
- 标记清除 标记进入环境 结束时标记退出环境
解决循环引用 对象相互引用,导致引用计数始终是1 可以加入与根对象的可达性来清除
标记清除第一步就是寻找root对象可以到达的对象,标记活动,其它对象标记非活动。
标记清除第二步回收非活动对象 - 标记整理法
标记清除法第二步后将活动对象移动到统一的区域 防止内存碎片产生
- dom的回收机制是引用计数,当js对象引用dom对象时,导致dom对象不能被回收
闭包导致dom与js相互引用
//IE9以后不会出现循环引用问题
function bindEvent(){
var elem=document.getElementById("click_div");
elem.onclick=function(){
//这里的function通过onclick属性被dom引用
//function因为闭包问题 会引用elem变量
//elem变量即指向dom 所以造成了循环引用
}
}
- 全局变量引用了dom对象 导致dom对象不能被回收
var globalData={};
function cacheLi(){
globalData.lis=document.querySelectorAll("li")
}
//虽然dom树中移除了li 但是全局变量中依然引用了dom
//所以dom对象并不会从内存中移除
function removeLi(id){
let node=document.querySelector(`#${id}`);
node.parentNode.removeChild(node);
}
- 垃圾回收会导致js停止响应,所以优化策略
由David提供了2条优化方案- 分代回收(Generation GC)
分年轻代和老年代,减少每次遍历的对象个数,年轻代的gc频率会高一点
老年代 gc 频率低一点 - 增量GC
每次处理一点,下次再处理一点 类似react fiber
- 分代回收(Generation GC)
- 分代回收缺点
老年代对象太多 导致gc扫描的对象个数没有减少,造成程序依然长时间卡顿 - 增量缺点
当对象很少的时候,增量gc执行了多次 导致浪费
安全问题
跨域(CORS)CrossOrigin Resources Sharing,也即跨源资源共享
httpheader Access–Control-Allow-Origin
1、HTTP头只能说明请求来自一个特定的域,但是并不能保证这个事实。因为HTTP头可以被伪造。
所以未经身份验证的跨域请求应该永远不会被信任。如果一些重要的功能需要暴露或者返回敏感信息,应该需要验证Session ID。
2、第三方有可能被入侵
3、恶意跨域请求 通过非安全的论坛XSS注入 DDOS攻击
5、针对用户的攻击 用户访问呗注入的网站 施行跨域攻击,采集所有的数据并发送给攻击者
暴漏尽量少的接口
检查Referer的header
cdn防御
XSS Cross Site Script
论坛提权 必须 POST
javascribt 空格或者回车分开 躲避
HTTP only的cookie。
将Unicode的反斜线转译
禁制html标签输入
反射型XSS 欺骗用户点击
存储型XSS 上传到服务器
web workder ddos
重放攻击
技术细节
计算将一棵树转换成另一棵树的最小操作数是一个复杂的、研究成熟的问题。前沿的算法显示这个问题大约是O(n^3)的复杂度,其中n是树种节点的数量。
-
两个相同类的组件将会产生相似的树,而两个不同类的组件将会产生不同的树。
-
为多次渲染中稳定存在的元素分配一个唯一的key是可能的。
-
节点有不同的类型
-
相同类型的DOM节点
-
相同类型的自定义组件
虽然Fiber是协调算法的推倒重写,关于React文档)中的高阶知识还是一致的。主要的两点是: -
不同类型的组件很大程度上将会产生不同的树。React将不会比较他们,而是直接用新的完全替代旧的。
-
列表的diff使用key。Key应当是稳定、可预测、并且唯一的。
httpCode
201(已创建) 202(已接受) 203(非授权信息) 服务器已成功处理了请求,但返回了可能来自另一来源的信息。 204(无内容) 服务器成功处理了请求,但未返回任何内容。 205(重置内容) 服务器成功处理了请求,但未返回任何内容。与 204 响应不同,此响应要求请求者重置文档视图(例如清除表单内容以输入新内容)。 206(部分内容) 服务器成功处理了部分 GET 请求。300-307表示的意思是:要完成请求,您需要进一步进行操作。通常,这些状态代码是永远重定向的。300(多种选择) 服务器根据请求可执行多种操作。服务器可根据请求者 来选择一项操作,或提供操作列表供其选择。** 301(永久移动) ** 请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。您应使用此代码通知搜索引擎蜘蛛网页或网站已被永久移动到新位置。302(临时移动) 服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。会自动将请求者转到不同的位置。但由于搜索引擎会继续抓取原有位置并将其编入索引,因此您不应使用此代码来告诉搜索引擎页面或网站已被移动。 303(查看其他位置) 当请求者应对不同的位置进行单独的 GET 请求以检索响应时,服务器会返回此代码。对于除 HEAD 请求之外的所有请求,服务器会自动转到其他位置。304(未修改) 自从上次请求后,请求的网页未被修改过。服务器返回此响应时,不会返回网页内容。 305(使用代理) 请求者只能使用代理访问请求的网页。如果服务器返回此响应,那么,服务器还会指明请求者应当使用的代理。** 307(临时重定向)** 服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。会自动将请求者转到不同的位置。但由于搜索引擎会继续抓取原有位置并将其编入索引,因此您不应使用此代码来告诉搜索引擎某个页面或网站已被移动。400(错误请求) 服务器不理解请求的语法。 401(身份验证错误) 此页要求授权。您可能不希望将此网页纳入索引。403(禁止) 服务器拒绝请求。 404(未找到) 服务器找不到请求的网页。例如,对于服务器上不存在的网页经常会返回此代码。
405(方法禁用) 禁用请求中指定的方法。406(不接受) 无法使用请求的内容特性响应请求的网页。407(需要代理授权) 此状态码与 401 类似,但指定请求者必须授权使用代理。如果服务器返回此响应,还表示请求者应当使用代理。408(请求超时) 服务器等候请求时发生超时。
409(冲突) 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。服务器在响应与前一个请求相冲突的 PUT 请求时可能会返回此代码,以及两个请求的差异列表。410(已删除) 请求的资源永久删除后,服务器返回此响应。该代码与 404(未找到)代码相似,但在资源以前存在而现在不存在的情况下,有时会用来替代 404 代码。如果资源已永久删除,您应当使用 301 指定资源的新位置。 411(需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。412(未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。 413(请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。500(服务器内部错误) 服务器遇到错误,无法完成请求。501(尚未实施) 服务器不具备完成请求的功能。例如,当服务器无法识别请求方法时,服务器可能会返回此代码。 502(错误网关) 服务器作为网关或代理,从上游服务器收到了无效的响应。 503(服务不可用) 目前无法使用服务器(由于超载或进行停机维护)。通常,这只是一种暂时的状态。504(网关超时) 服务器作为网关或代理,未及时从上游服务器接收请求。 505(HTTP 版本不受支持) 服务器不支持请求中所使用的 HTTP 协议版本
网友评论