Tracy JS 小笔记 - json, 异步加载, 时间线

json

  • 它是一个对象,是为了数据传输,为了前后端的通讯
    属性名强制加双引号
    {
    "name": "Tracy",
    "age" : 18
    }
  • JSON 是一个静态类,相当于 Match, 有各种方法可以使用
    • 前端传 json 给后端
      var obj = { "name" : "Tracy", "age" : 18};
      JSON.stringfy(obj); //把对象转换成 字符串的 json 格式,传输给后台
    • 后端传 json 给前端
      var str = JSON.stringfy(obj); //后端传过来的 也是字符串的 json 格式
      var obj = JSON.parse(str);// 把 json 行形式的字符串转换为对象

异步加载

  • 在页面加载的时候,html 和 css 是并行一起被解析的,在解析的时候分别生成 domTree 和 cssTree 它们加合并在一起汇成了一个 renderTree (渲染树) 然后再汇成一个页面 我们把 JS 写在下边,就相当于在生成 domTree 的时候页面刚刚解析完(而不是下载完)的时候就执行 JS
    比如说 image, 图片 size 很大,解析完的意思是: 认出了这个是一个 image 标签后然后马上挂到树上去,而开启另一个新的线程,异步同时下载这个图片。
  • domTree 遵循深度优先原则,既 先遍历 html 然后遍历 head 和里面的所有 meta, 都遍历结束后,再遍历 body 里的标签
  • 我们要尽量减少 js 对于节点的添加和删除操作,如果必须要做,也要尽量一次性做完,因为一旦 节点变了,相当于 domTree 变了,进而 randerTree 也变了,然后页面需要重新绘制一遍,影响页面效率。
    以下情况会导致页面 randerTree 的 reflow 重排
    • dom 节点的删除,添加
    • dom 节点的宽高变化,位置变化(display:none/block)
      因为一个元素的高度变了,页面其他元素的相应都会发生改变
    • 查看 dom 节点的位置 offsetWidth, offsetLeft,
      为何它要重绘页面? 因为调用的时候页面重排这样返回的值才是时时的
  • repaint 重绘, 这个也会稍微影响页面效率, 不过是可以忍受的,它不会把整个页面都重绘,只是一部分。
    • 改变 dom 节点的颜色
    • 改变 dom 节点的背景图片
  • 普通加载 js

    • 一些 js, 并不改变页面,就是一些工具包的 js, 我们需要做异步加载,这样一边下载 js 一边下载 html css 互相不受影响, 否则页面会在执行到 js 的时候空白,如果下载不了这个 js 页面会一直持续空白
      JS 加载的缺点: 加载工具方法没有必要阻塞文档,过多加载 js 会影响页面效率,一旦网速不好,那么整个网页将等待 js 加载而不进行后续渲染等工作
    • 有些工具方法需要按需加载,需要调用的时候加载,不需要调用的时候就不加载
    • 普通 js 下载完立即执行
  • 异步加载 js 三种方案

    • defer 异步加载,但要等 dom 文档全部解析完才会被执行(既: domTree 生成完毕)。 只有 IE 能用,也可以将代码写到内部
      (Tips: 凡是属性名等于属性值的,我们只写属性名就行了,比如这里的 defer 其实是 defer="defer" 的简写)
      <script defer src="#.js"></script>
      <script defer ></script> some js code ... <script>
    • async 异步加载,加载完就执行, async 只能加载外部脚本,不能把 js 写在 script 标签里, W3C 标准方法, IE9 以上浏览器都能用
      <script async src="#.js"></script>
    • 如何让上面两个兼容呢? 这里就提出的最常用的第三种方法:
      创建 script, 插入到 dom 中,加载完毕后 callBack
      它除了可以实现异步加载,也可以实现按需加载
      比如说一个用户点击一个按钮之后,才下载一个 tool.js 然后执行里面的某个函数
      <script> 
          var scrpit = document.createElement('script'); 
          scrpit.type = "text/javascript"; 
          scrpit.src = "tool.js";//这个分号执行完,系统就发了一个请求异步下载这个文件了 
      
          if(scrpit.readyState){ //只有 IE 有的方法
              scrpit.onreadystatechange = function(){
                  if(scrpit.readyState == "complete" || scrpit.readyState == "loaded") {
                      text();
                  }
              }
          }else{
              scrpit.onload = function(){ //但是 IE 没有这个方法 
                  //这里就是说 script 下载完了之后开始执行的code  
                  text(); //假设 tool.js 里有这个 text(); 方法,如果不写到这里的话,我们马上直接调用的话,会报错,因为 js 文件还没有下载完毕
              }
          }
         
      
          document.head.appendChild(scrpit);//这句话写出来,就开始执行 js 了,这句话不写就永远不执行 
      </script> 
      
      
      上面的 code 打包成一个函数
      The best way to load external JavaScript
      
      function loadScript(url, callback){
      
          var script = document.createElement("script")
          script.type = "text/javascript";
      
          if(callback){
              if (script.readyState){  //IE
                  script.onreadystatechange = function(){
                      if (script.readyState == "loaded" ||
                              script.readyState == "complete"){
                          script.onreadystatechange = null;
                          callback();
                      }
                  };
              } else {  //Others
                  script.onload = function(){
                      callback();
                  };
              }
          }
          
          script.src = url;
          document.getElementsByTagName("head")[0].appendChild(script);
      }
      
      loadScript('tool.js', function(){ text();}); //调用js 并且执行里面的方法
      loadScript('tool.js'); //只调用 js
      

浏览器加载时间线

  1. 创建 Document 对象,开始解析 web 页面。解析HTML元素和他们的文本内容后添加 Element 对象和 Text 节点到文档中。这个阶段document.readyState = ‘loading’。
  2. 遇到 link 外部 css,创建线程进行异步加载,并继续解析文档。
    • 遇到 script 外部 js,并且没有设置 async、defer,浏览器加载,并阻塞,等待 js 加载完成并执行该脚本,然后继续解析文档。
    • 遇到script外部js,并且设置有async、defer,浏览器创建线程异步加载,并继续解析文档。 对于async属性的脚本,脚本加载完成后立即执行。(异步加载的 js 禁止使用document.write() 方法,它会把所有页面的东西覆盖,相当于 window.onload = function(){document.write("a");})
  3. 遇到img等带 src 的标签,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档。
  4. 当文档解析完成后 (domeTree 构建完,解析完不代表加载完,所有文件都下载完)
    • document.readyState = ‘interactive’。
    • 所有设置有defer的脚本会按照顺序执行。(注意与async的不同,但同样禁止使用document.write());
    • document 对象触发 DOMContentLoaded 事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。 (这个事件只在 addEventLisener 上有用,不能直接写 .onDOM.... ,这个方法就是 dome 解析完直接可以执行的函数,就比 window.onload 强了很多)
      document.addEventListener('DOMContentLoaded',function(){...js 写法... },false); == $(document).ready(function(){ ... 这个是jQuery 写法...})
  5. 当所有 async 的脚本加载完成并执行后、img 等加载完成后,document.readyState = ‘complete’,window对象触发load事件。
  6. 从此,以异步响应方式处理用户输入、网络事件等。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值