creeperyang / blog

前端博客,关注基础知识和性能优化。
MIT License
2.64k stars 211 forks source link

编程资源(概念解释/优秀博文/其它) #15

Closed creeperyang closed 7 years ago

creeperyang commented 8 years ago

一 概念篇

程序基本概念

1. 同步与异步,阻塞与非阻塞

同步异步阻塞非阻塞是两组概念,但很容易混淆。比如同步不代表阻塞同步也可以是非阻塞的。

1.1 同步异步

  1. 同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)
  2. 所谓同步,就是在发出调用时,

    1. 在没有得到结果之前,调用不返回。
    2. 一旦调用返回,即得到返回值。

    换句话说,就是由调用者主动等待这个调用的结果。

  3. 异步则是相反,调用在发出之后,调用就直接返回,但没有返回结果。

    换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

    1.2 阻塞非阻塞

  4. 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态
  5. 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
  6. 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程

    1.3 示例

以打电话让书店老板查找某本书为例来讲:

总结:阻塞与非阻塞 与 是否同步异步无关(跟老板通过什么方式回答你无关)。

原文

creeperyang commented 8 years ago

二 优秀博文和讨论

1. 如何看待《React: CSS in JS》?

https://github.com/hax/hax.github.com/issues/22

Hax 大神开的主题讨论,里面有非常精彩的关于怎么使用/组织 CSS 乃至 组件化的讨论。

有各种观点的碰撞,但基本都做到罗列资料,清晰阐述,有的放矢。

2. 再谈 CSS 预处理器

http://efe.baidu.com/blog/revisiting-css-preprocessors/

算是跟上面的紧密相关,介绍CSS预处理器,以及CSS的模块化,组织方式等等。

3. JavaScript内存泄漏与如何避免

https://auth0.com/blog/2016/01/26/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/

内存泄漏的4种情况:

  1. 意外的全局变量
  2. 遗忘的timer或callback

    1. setInterval

      var someResource = getData();
      setInterval(function handler() {
      var node = document.getElementById('Node');
      if(node) {
          // Do stuff with node and someResource.
          node.innerHTML = JSON.stringify(someResource));
      }
      }, 1000);

      setInterval中有nodesomeResource的引用。虽然在未来nodesomeResource可能都已经不再需要,比如node可能在dom树中被删除了,但handler仍然是active的,不会被回收,那么作为依赖的nodesomeResource也不会被回收。所以记得不再需要时clear掉setInterval

    2. observer/callback

      对observer而言,一旦不再需要,建议移除。过去,如IE6等浏览器无法处理循环依赖,所以这么做很有必要,但现在,大多浏览器可以正确搜集不可访问的observer handler

      var element = document.getElementById('button');
      
      function onClick(event) {
      element.innerHtml = 'text';
      }
      element.addEventListener('click', onClick);
      // Do stuff
      element.removeEventListener('click',   onClick);
      element.parentNode.removeChild(element);
      // Now when element goes out of scope,
      // both element and onClick will be collected   even in old browsers that don't
      // handle cycles well.
  3. 脱离DOM的引用(Out of DOM references)

    有时候,在数据中存储dom节点很有用,但记住,在dom树中删除该节点后必须在数据中也删除节点的引用,才可以让节点被正常回收。

    另外,必入你在data structure中引用了某个tr节点,然后你在dom树中删除了table,事实上,整个table而不是tr节点仍被缓存。

  4. 闭包

    由于某个JS runtime实现细节的问题,以下代码会造成内存泄漏:

    var theThing = null;
    var replaceThing = function () {
     var originalThing = theThing;
     var unused = function () {
       if (originalThing)
         console.log("hi");
     };
     theThing = {
       longStr: new Array(1000000).join('*'),
       someMethod: function () {
         console.log(someMessage);
       }
     };
    };
    setInterval(replaceThing, 1000);

    以上代码干了这样一件事:每次replaceThing被调用,theThing获得一个大数组,并创建了一个新闭包(someMethod)。同时,变量unused持有一个闭包,引用了originalThing(它是上一次调用replaceThingtheThing)。

    迷惑了吗?重点是在同一个父作用域中,一旦一个为不同闭包使用的作用域被创建,该作用域是共享的。

    在上面的例子中,为闭包someMethod创建的作用域被闭包unused共享,即使unused从未被调用,someMethod可能通过theThing被使用。而someMethod共享unused的作用域,所以即使unused从未被使用,它引用originalThing使得originalThing一直active,阻止被回收。

    当上面的代码被反复执行,内存持续增长。实际上,闭包的链表被创建,每个闭包都非直接的引用一个大数组,导致内存增长。

    Meteor 的博文 解释了如何修复此种问题。在 replaceThing 的最后添加 originalThing = null 。

creeperyang commented 8 years ago

三 发现博客

creeperyang commented 8 years ago

四 webpack

  1. DllPlugin https://segmentfault.com/a/1190000005969643