根据引言,作者将全书划分为四个部分:
一、页面加载js的最佳方式(开发前准备)
二、改善js代码的编程技巧(开发中)
三、构建与部署(发布)
四、发布后性能检测与问题追踪(线上问题优化)
这样的组织结构也符合我们的开发习惯,首先进入第一部分。
起因:script脚本的加载会阻塞浏览器渲染页面和处理用户交互,如果加载的script脚本太多太大,就会长时间阻塞,造成页面假死。
解决方案:
放在底部。
放在底部可以保证页面主体结构已经基本加载完成展示给用户,才去加载script脚本。这条准则也有特例,如果是一些公司的埋点脚本,可能要求必须放在head里,以确保能上报页面加载时长。
减少script数量,合并脚本。
不论是使用concat打包工具合并,还是cdn提供的combo,都能达到该目的。
在页面加载完成之后再去触发加载js,这样可以防止script加载阻塞页面。
script标签自带defer属性,可以达到这个目的。捎带一提,async属性可以触发异步加载,合理利用了宽带。
或者使用动态脚本元素,通过js文件动态创建script标签,文件加载完成之后会立刻执行。
这个技术的重点在于不论在何时启动下载,文件的下载和执行过程都不会阻塞页面其他进程。
通过XHR加载脚本,由于不是在script标签中加载,所以可以控制script标签中的代码执行时间。在需要的时候再去把script标签添加到页面上。
这也是jsonp的原理。
先加载很少量的jsLoader代码,之后通过loader来加载剩余的代码。
function loadScript(url, callback) { var script = document.createElement('script'); script.type = 'text/javascript'; if (script.readyState) { // IE script.onreadystatechange = function () { if (script.readyState == 'loaded' || script.readyState == 'complete') { script.onreadystatechange = null; callback(); } } } else { // 其他浏览器 script.onload = function () { callback(); } } script.src = url; document.getElementsByTagName('head')[0].appendChild(script); } loadScript('rest.js', function () { Rest.init() });
作者介绍了上述3个类库中lazyload的使用方式,其实原理就是上述所说,在体验上各有不同。关键就是loader中监听script的onload事件,决定script的执行时机。
这个部分从2到8章分别介绍不同的提高性能的技巧。
嵌套对象层数越多,也会减慢速度。例如,location.href要快于window.location.href。
解决方法:
大部分的性能损耗都是与对象查找相关,所以建议缓存对象,减少查找次数。
其次,要注意重绘和重排,对DOM的哪些操作会引起重绘和重排,减少这方面的操作。
最后,需要注意DOM事件处理用户交互。
使用innerHTML和原生的document.createElement()类似的方法,速度相差不大。在最新版的webkit内核浏览器(chrome和safari)以外,innerHTML会更快,而且相较而言,代码量也少很多。
HTML集合是包含了DOM节点引用的类数组对象,例如document.getElementByName()这样的方法,需要注意的是HTML集合一直与文档保持着连接,每次需要新信息的时候,都会重新查询。
在查找DOM元素时,尽可能使用原生方法,如最新支持比较完善的querySelectorAll()。
为了减少重排和重绘,批量修改样式时,“离线”操作DOM树,使用缓存,并减少访问布局信息的次数。在动画中使用绝对定位,使用拖放代理。
使用事件委托来减少事件处理器的数量。
事实上,这些工具的功能在新版的chrome开发工具都有了,所以我建议好好学习chrome开发者工具。
感谢阅读。
如对本文有疑问, 点击进行留言回复!!
JavaScript 好题汇总分享(持续更新,看到好题就写)
XMLHttpRequest 2级 &&进度事件&&JSONP
使用递归原生实现拷贝&&最简单的方法实现深拷贝
网友评论