Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

高性能Javascript读书笔记 #11

Open
PunkMoon opened this issue Apr 7, 2018 · 0 comments
Open

高性能Javascript读书笔记 #11

PunkMoon opened this issue Apr 7, 2018 · 0 comments

Comments

@PunkMoon
Copy link
Owner

PunkMoon commented Apr 7, 2018

加载和执行

  • 脚本的位置放到body标签的底部,避免脚本阻塞
  • 通过合并脚本文件,减少脚本文件的请求
  • 脚本延迟执行。defer需要等待页面完成后执行,async是加载完后自动执行。使用defer时,需要确保不会修改DOM

数据存取

作用域链

解释

当函数被创建的时候,他的作用域链中就被插入了一个对象变量,这个全局对象代表着在全局范围内定义的变量。例如window/document/navigater等

执行这个函数时会创建一个称为执行环境 的内部对象。每个执行环境都是独一无二的,每执行一次就会创建一次执行环境。每个执行环境都有自己的作用域链。

当执行环境被创建的时候,他的作用域链就初始化为当前运行函数[[Scope]]属性的对象,也就是那个全局对象

这个初始化的过程一旦完成,一个称为活动对象的新对象就为执行环境创建好了。活动对象同时被推入作用域链的最前端。

在函数执行过程中,每遇到一个变量就会搜索执行环境中的作用域链,查找同名的标识符。搜索过程中作用域链头部开始,也就是当前运行函数的活动对象。如果找到,就是用这个标识符对应的变量,反之继续搜索作用域链中的下个对象。

应用

  • 尽可能是使用局部变量,如果多次引用全局变量,可以储存到局部变量里。

  • with语句 try-catch语句 会动态改变作用域所以尽量避免使用。

  • 当闭包被创建的时候,它的[[Scope]]被初始化成和当前函数一样的对象,由于闭包的[[Scope]]属性包含了和执行环境作用域链相同的对象的引用,因此会产生副作用。

    引入闭包时,由于引用仍然存在于闭包的[[Scope]]对象中,因此激活对象无法被销毁。这意味着闭包函数需要更多的内存开销。

    闭包代码执行时会创建一个自身创建的活动对象。会涉及到频繁的跨作用域访问标识符。

    减轻闭包对执行速度的影响:将常用的跨作用域变量存储在局部变量中,然后直接访问局部变量。

  • 嵌套对象成员会影响性能

  • 属性或方法在原型链中的位置月神,访问它的速度越慢

DOM

重绘与重排

  • DOM树表示页面结构,渲染树表示DOM节点如何显示
  • DOM的变化影响了元素的几何属性,浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树,这个过程叫做重排
  • 完成重排后,浏览器重新绘制受影响的部分到屏幕中,该过程成为重绘
  • 不改变几何属性的DOM变化,例如背景颜色改变只会发生重绘,不会重排
  • 当需要对DOM元素进行一系列操作的时候,可以通过以下步骤来减少重绘和和重排
    • 使元素脱离文档流
      • 隐藏元素,应用修改,重新显示
      • 使用document fragment创建一个子树 完成后替换原始元素document.createDocumentFragment();
      • 原始元素拷贝到一个脱离文档的节点中,修改副本,完成后替换原始元素
    • 使其应用多重改变
    • 将元素带回文档中

事件委托

每个事件都会经历三个阶段:

  • 捕获
  • 到达目标
  • 冒泡

算法和流程控制

  • for-in循环明显要慢,因为每次循环都要同事搜索实例和原型属性
  • 优化if-else
    • 确保最可能出现的条件放在首位
    • 将条件组织成一系列的嵌套

字符串和正则表达式

  1. 正则表达处理步骤:
    • 编译
    • 设置起始位置:lastIndex属性
    • 匹配每个正则表达式字元
    • 匹配成功或者失败

快速响应的用户界面

  1. setTimeout中的第二个参数表示的是任务何时被添加到到UI队列,而不是一定会在这段时间后执行
  2. 无论发生何种情况,创建一个定时器会造成ui线程暂停。
  3. setInterval()和setTimeout()最主要的区别是如果UI队列中已经存在同一个setInterval()创建的任务,那么后续的任务不会被添加到UI队列中

数据请求

  1. 对于那些不会改变服务器状态,只会获取数据的请求,应该使用GET。经get请求的数据会被缓存起来。
  2. 对于少量数据而言,一个GET请求往服务器只发送一个数据包。而一个POST请求,至少要发送两个数据包,一个装载头信息,另一个装载POST正文。
  3. 优化AJAX性能:
    • 通过设置HTTP头信息里的缓存时间缓存数据
    • 减少请求数
    • 缩短页面的加载时间
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant