1 .在对js性能分析的时候,性能分析也会受到外在的影响,类似物理学中的观察者效应,观察代码的行为本身改变了代码的性能。如何在接下来的测试工作中来进行实践,挑选最好的测试工具
线程处理的两种方案
1 .web worker
2 .使用定时器挂起,简单的把运行时间较长的计算超分成独立的区块,然后使用js定时器控制执行。
内存的两种情况
1 .内存泄漏
2 .内存管理:js像很多高级的语言一样把内存管理抽象出来,绝大部分的运行环境实现了垃圾回收,但是这也是有代价的,当执行回收的时候,他会冻结整个运行环境,包括我么正在调用的主浏览器js线程,直到遍历完整个创建对象的“堆”,在这个过程中,他们去查找不在使用或者未用内存的对象
3 .对于大部分用户而言,GC是完全透明的,因为冻结运行环境的时间可以短到忽略不计,但是随着应用内存的增加,遍历整个堆去查找不在使用的对象所需要的时间将增长并最终会达到引起用户注意的程度
4 .解决方法:及时使用delete 关键字从内存中移除不在需要的js对象,从网页的dom树上移除不再是必须的节点
5 .下一步需要注意:前端排除内存问题的工具。
拆分初始化负载
寻找拆分
通过资源下载列表,可以将文件分为触发onload事件之前和之后两部分。webpack实现,Doloto,一个微软开发的自动代码系统
未定义标识符和竞争状态
1 .最容易出现的问题:加载资源的时候用户操作了和这个js脚本有关的函数。
2 .延时代码和界面元素相关的情况下,第一种是可以添加一个加载中提示,第二种是在延时加载代码的里面绑定界面元素的处理程序
3 .和界面无关:设定一个桩函数,名字相同,但是函数提为空,或者用一些临时代码代替原有函数的内容,最好的是使用桩函数记录这个用户的操作,等加载完成之后调用相应的代码
无阻塞加载脚本
1 .<script>脚本会对页面性能产生负面影响,大多数浏览器在下载或执行脚本的同时是不会下载其他内容的
2 .但是有的时候我们希望不阻塞其他内容下载的方式来加载js.
3 .src定义了需家在外部文件的url,如果缓存中有脚本文件,浏览器就从缓存中读取,否则就发送http请求
4 .浏览器在下载和执行脚本时出现阻塞的原因在于,脚本可能会改变页面或者js的命名空间,对后续内容造成影响.也有可能两个脚本同时修改一个东西,竞争状态会导致js错误
5 .脚本必须按照顺序执行,但是没有必要按照顺序下载
既能避免阻塞导致的减速影响,又能拥有外部脚本的好处。(脚本与页面其他资源并行下载)
1 .ajax从服务端获取脚本,不能跨域加载。跨域是前端还是后端服务器的行为啊。
2 .iframe加载X
3 .动态创建script元素
4 .defer属性:
5 .以上的技术都会影响用户感知页面是否加载完毕。浏览器提供了多种忙指示器,让用户感知到页面还在加载
1.状态栏
2.进度条
3.左上角地址栏图标下载时会旋转提示
4.鼠标光标变成沙漏或者其他类似的图形表示页面正忙
5.阻塞渲染,阻塞onload事件。当在下载脚本的时候,浏览器停止渲染所有脚本后面的内容,在全部渲染完毕之前通过冻结页面来表示浏览器正忙
6 .有的时候我们需要显示忙指示器来告诉用户页面正在运行,但是有的时候不需要显示任何指示器,鼓励用户开始与页面进行交互。具体的还需要查表。
脚本的执行顺序
1 .很多时候网页都是包含多个特定依赖顺序的脚本,使用上面的技术可以导致脚本并行下载,所以执行的时候也是会按照先到先来
2 .defer 属性可以保证脚本按照顺序执行而不管哪个先下载完毕
决策时的技术选择
1 .不同域,无序
script Dom Element:包含js广告和控件的网页是最适合这个情况的实例
2 .不同域,保持顺序
defer:从不同服务器下载多个存在依赖关系的js文件的页面
3 .同域,无序,无忙指示器
xhr技术是唯一不触发忙指示器的技术:在后台下载js文件的网页
4 .同域,无序,有忙指示器
管理xhr注入,在xhr发出时激活状态栏和光标,xhr返回时恢复。
5 .同域,有序,无忙指示器
xhr:把xhr响应塞进队列中,按照顺序执行,延迟加载的脚本则须有在之前脚本下载并执行完毕后才开始执行。符合有多个内部依赖的脚本在后台下载页面的情况。
整合异步脚本
1 .无阻塞脚本带来的性能是需要付出代价的。代码异步执行时可能会出现竞争状况,在使用外部脚本的时候,我们关注依赖外部脚本里定义的标识符的行内脚本,如果外部脚本异步加载而不考虑行内代码的依赖。可能会由于竞争状态而导致出现未定义标识符的错误。
2 .解决异步加载的外部脚本与行内脚本之间存在代码依赖的问题
3 .硬编码回调:让新加的外部脚本调用行内代码的函数。等外部脚本下载完毕在进行函数的调用
4 .window.onload触发行内脚本
5 .定时器轮询保证在行内代码执行前所依赖的外部脚本已经加载。(这个方法很垃圾)
6 .script onload
var domscript=document.createElement('script');
domscript.src='menu.js'
domscript.onloadDone=false
domscript.onload=function(){
domscript.onloadDone=true
}
domscript.onreadystatechange=function(){
if(('loaded'===domscript.readyState||'complete'===domscript.readyState)&&!domscript.onloadDone){
domscript.onloadDone=true;
init()
}
}
多个外部脚本的顺序加载
1 .放在一个队列中,一个加载完成在加载另一个。根据onload事件。
2 .这些原始的,破旧的技术好像可以抛弃了。
单个脚本执行顺序,类似于jquery的使用情况
react的脚本加载依赖顺序是什么?---整个集成系统的加载方式,或者说现代web开发的加载资源策略,被这个搞的都开始怀疑人生了。。
es6中的模块系统可以完美的解决这个问题。所以这些就不看了,只需要了解大致的原理
行内脚本
1 .由于行内脚本存在渲染,保持顺序和对document.write的依赖,行内脚本也会出现阻塞并行下载。就是在行内脚本解析的时候阻止浏览器下载资源
2 .chrome.firefox不会出现,浏览器已经优化了
3 .把行内脚本移到底部
4 .使用异步回调启动js的执行。定时器
5 .使用defer属性,也适用于行内脚本
css的执行顺序
1 .鉴于样式的级联特性,按照不同的顺序加载他们可能会产生意想不到的结果。
2 .浏览器是按照样式表在页面中列出的顺序来应用他们的,和下载的顺序无关。
3 .css的应用规则同样适用于样式表和行内样式,浏览器会等待下载时间长的样式表下载完成,以保证css是按照页面指定的顺序应用的
4 .首先浏览器会按照顺序处理css和js,因为这个示例表明了当行内脚本在样式表后面的时候,浏览器必须等样式表下载完之后才会开始执行行内脚本,因为行内脚本可能还有依赖于样式表中的样式的代码。
5 .所以,在样式表后面的行内脚本会阻塞所有后续资源的下载。
6 .行内脚本应该放在样式表之前或者其他资源之后。当然是在确认没有代码依赖的时候。
超越GZIP:
1 .即使已经启用了gzip压缩的用呢个,但是还是会存在这样的可能性,相当一部分用户在访问网站的时候,收到了未经压缩的响应。
2 .原理:浏览器在请求的时候加上Accept-encoding:Gzip,deflate。web服务器开启gzip,返回一个压缩响应:Content-Encoding:Gizp。作为头标记
3 .出现的元因:从服务端的日志可以看出,部分的请求头是损坏的:X-cept-encoding:gzip
4 .主要是web代理和pc安全软件故意关闭压缩功能来降低浏览器的体验,他们的相同之处就是需要对web服务器发送的响应进行监听
5 .以上的原因是无法控制的,那么如何在对这种情况进行响应呢?我们的目标就是:最小化未压缩文件的尺寸
6 .使用事件委托:当很多元素都需要响应某个事件的时候,我们把这个事件绑定到他们的父元素上面。
7 .使用相对url来表示页面
8 .移除空白
9 .移除属性的引号
10 .避免行内样式
11 .为js变量设置别名:由于几个常用的dom方法名都很长,压缩的时候完全可以变这种浪费。找到脚本中常用的别名,为他设置别名。
12 .引导用户发现这个错误的原因
13 .对GZIP的支持进行直接嗅探