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

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

  • 相关阅读:
    Android中TextView设置下划线
    BottomSheetDialogFragment 如何设置高度和禁止滑动(Kotlin)
    [iOS]使用GCD创建定时器
    [iOS]定时器NSTimer、CADisplayLink的内存管理
    [iOS]dispatch_after()中self和weakself的使用
    [Flutter]在Mac上安装Flutter运行环境
    wx小程序反编译为js代码
    Android | 玩转AppBarLayout,设置scrollFlags滑动属性详解
    玩转微信 | 炫酷的聊天满屏掉爱心系列,赶紧收藏
    Android使用更简单的方式实现滑块拼图验证码功能
  • 原文地址:https://www.cnblogs.com/welody/p/15214557.html
Copyright © 2011-2022 走看看