zoukankan      html  css  js  c++  java
  • [JavaScript初级面试]17. 运行环境

    原则 -- 用空间换时间

    • 多使用内存,缓存
    • 减少CPU计算量,减少网络的加载耗时

    目标

    • 加载更快
      减少资源体积:压缩代码,图片:利用打包工具
      减少网络访问次数:合并代码,SSR服务器端渲染,缓存

    a.js b.js c.js => abc.js

    服务器端渲染:将网页和数据一起加载,一起渲染
    非SSR:先加载网页,再加载数据,再渲染数据

    静态资源加hash后缀,根据文件内容计算hash
    文件内容不变,hash不变,则url不变
    url和文件不变,则会出发http缓存机制,返回304

    使用更快的网络:CDN

    • 渲染更快
      CSS放在header,JS放在body最下面
      尽早开始执行JS,用DOMContentLoaded触发
      懒加载(图片懒加载,分页)
    // 开始建在较小的预览图片,真实图片地址放在data-realsrc中
    <img id="img1" src="preview.png" data-realsrc="abc.png"/>
    <script>
      // DOM加载完成后,再把真实图片加载出来
      var img1 = document.getElementById('img1')
      img1.src = img1.getAttribute('data-realsrc')
    </script>
    

    对DOM查询进行缓存
    频繁的DOM操作,合并到一起插入DOM结构

    防抖(debounce)
    场景:监听一个输入框change事件,如果用keyup会频发出发change事件
    用户输入结束或暂停时,才会触发change事件,就是防抖

    const input1 = document.getElementById('input1')
    let timer = null
    input1.addEventListener('keyup', function(){
      if(timer){
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        console.log(input1.value) // 模拟触发change事件
        timer = null // 清空定时器
      }, 500)
    })
    

    封装为debounce函数:

    function debounce(fn, delay = 500){
      let timer = null // 自由变量
      return function(){
        if(timer)
          clearTimeout(timer)
        timer = setTimeout(() => {
          fn.apply(this, arguments)
          time = null
        }, delay)
      }
    }
    
    input1.addEventListener('keyup', debounce(()=>{
      console.log(input1.value) // 箭头函数中,使用input1可以正确获取input1对象
      // 如果现在箭头函数中,使用this.value打印的并不是input1的value,而是window.value
      // 如果想动态指定this的值,此时就需要把箭头函数改为function,并在debounce函数中绑定事件触发时,this的值
    }, 500))
    

    节流(throttle)
    场景:拖拽一个元素时,要随时拿到该元素被拖拽的位置;
    直接用drag事件,则会频繁触发,很容易造成卡顿

    节流:无论拖拽速度多快,都会每个100ms触发一次

    <div id="div1" draggable="true">
    可拖拽
    </div>
    <script>
    const div1 = document.getElementById('div1')
    div1.addEventListener('drag', (e)=>{
       console.log(e.offsetX, e.offsetY) //频繁打印位置
    })
    </script>
    

    改良 ==> 节流

    const div1 = document.getElementById('div1')
    let timer = null
    div1.addEventListener('drag', (e)=>{
       if(timer)
         return
       timer = setTimeout(() => {
         console.log(e.offsetX, e.offsetY)
         timer = null
       }, 100)
    })
    
    

    改良 函数 ==> 节流

    function throttle(fn, delay = 100){
      let timer = null
      return function(){
        if(timer)
          return
        timer = setTimeout(() => {
          fn.apply(this, arguments) // arguments把div1注册的函数参数传入入
          timer = null
        }, delay)
      }
    }
    
    div1.addEventListener('drag', throttle(function(e){
      console.log(e.offsetX, e.offsetY)
    }, 200))
    

    本文来自博客园,作者:Max力出奇迹,转载请注明原文链接:https://www.cnblogs.com/welody/p/15214557.html

    如果觉得文章不错,欢迎点击推荐

  • 相关阅读:
    各种语言语法大全
    【mysql】SQL常用指令
    【JdbcTemplete】JdbcTemplete代码详解--模板方法详解
    【Spring-AOP-1】AOP相关概念
    【设计模式】命令行模式
    【设计模式】单件模式(Singleton)--各类单件模式的比较
    【设计模式】工厂方法模式(Factory Method)
    【设计模式】装饰者模式(Decorator)
    【并发编程】延时初始化
    【并发编程】AQS学习
  • 原文地址:https://www.cnblogs.com/welody/p/15214557.html
Copyright © 2011-2022 走看看