为了账号安全,请及时绑定邮箱和手机立即绑定

前端进阶(笔记)

标签:
Html5


vue

v-show 和 v-if的区别

  • v-show通过css display控制显示和隐藏

  • v-if组件真正的渲染和销毁

  • 频繁切换用v-show否则v-if

为何 v-for 中要用key

  • 必须用key不能使用index和random

  • diff算法中通过tag和key来判断是不是sameNode

  • 减少渲染次数,提高渲染性能

vue生命周期(有父子组件的情况)

  • 父beforeCreate  >  父created  > 父beforeMount  >  子beforeCreate  >  子created   >  子beforeMount  >  子mounted  >  父mounted

vue组件如何通讯

  • props、$emit

  • EvenetBus自定义事件

    1. Vue.prototype.$bus = new Vue();

    2. this.$bus.$on("test", (data) => {});

    3. this.$bus.$emit("test", "go");

  • Vuex

  • $parent、$children,$attrs、$listenners,Provide、Inject,ref,observable

computed 和 watch

  • 相同: computedwatch都起到监听/依赖一个数据,并进行处理的作用。

  • computed

    1. 缓存,依赖的data、props 等属性数据发生变化的时候调用,可以提高性能;

    2. 在computed中的,属性都有一个 get 和一个 set 方法,当数据变化时,调用 set 方法。

  • watch

    1. 监听引用类型取不到oldValue

    2. 可以监听的数据来源:data,props,computed内的数据;可以看作是 computed 和 methods 的结合体。

    3. watch支持异步

    4. 不支持缓存

自定义v-model、$nextTick、slot、动态组件 异步组件、keep-alive、mixin


双向数据绑定v-model实现原理

  1. 绑定input value=this.name

  2. 通过监听input的onInput事件

  3. 更改this.name = $event.target.value;

  4. 数据改变重新触发render函数

Object,defineProperty的缺点

  •     不能监听数组,监听数组的变化需要重写数组的原型方法,为了保留数组原型的原始方法避免被污染,利用object.create(Array.prototype)创建新对象。

  •     深度监听,需要递归到底,一次性计算量大,可能会导致卡死。

  •     无法监听属性的新增和删除但是有替代方案(Vue.set,Vue.delete)

  •     为解决以上问题,vue3.0使用proxy,proxy的缺点无法使用polify浏览器兼容性差

虚拟DOM(Virtual DOM )

  •     用js模拟DOM结构(vnode)

  •     新旧vnode对比,得出最小的更新范围,最后更新DOM

  •     数据驱动视图的模式下,有效控制dom操作

diff算法

diff算法是比较两个vnode,计算出最小的变更,以便减少DOM操作次数,提高性能。

  • 其原理有:

  1. 只比较同级,不跨域比较;

  2. 如果tag不相同,直接删除重建,不再深度比较

  3. 如果tag和key都相同,默认是一样的节点,也不再深度比较

它的流程是:

    1. 首先,它会判断是否是首次渲染,因为如果是首次渲染,没有旧的vnode,不需要比较,直接渲染就可以了。

    2. 在非首次渲染,首先比较两个节点是否一样。如果不一样,直接删除重建;如果一样,就需要进行vnode比较、就是比较children。

    3. 如果新节点没有文本节点,删除旧节点的文本节点;如果有文本节点,替换掉旧的文本节点。

    4. 如果只有新节点有子节点,直接插入;如果只有旧节点有子节点,直接删除。

    5. 最后就是,新旧节点都有子节点的情况。

    6. 这时候会遍历新节点的children,每个新的子节点都需要在旧的children里面进行寻找,找一个一样的节点。

    7. 如果没有找到,新的子节点直接插入;如果找到了,这两个节点再进行vnode比较。

    8. 也可以简单的理解为,如果没有是重新渲染,如果有的话,直接把旧的子节点挪过来用就可以了。

组件渲染更新流程

整体编译流程 http://coding.imooc.com/learn/questiondetail/172128.html

模板编译

  • 使用vue-template-compiler,with语法

  • 将模板编译为render函数,执行函数返回vnode 

  • 基于vnode再执行渲染和更新(patch和diff)

  • 如果有需要可以用render函数代替template,react就是使用的render

  • 如果是在webpack环境下则vue-loader会在开发环境下预编译模板

为何使用异步渲染

  • $nextTick(()=>{});

  • 汇总data修改,一次性更新视图

  • 减少dom操作次数,提高性能

MVVM数据驱动视图

使开发人员不再关注具体dom,将精力放到对数据的处理上

vue常见性能优化

  • data层级避免过深

  • v-show v-if

  • computed

  • v-for时加key,以及避免同时使用v-if

  • beforedestory 及时销毁自定义事件、DOM事件、定时器等

  • 使用异步组件import(),和路由import()

  • keep-alive

  • 使用vue-loader在开发环境下做模板预编译

  • 服务端渲染

    • const renderer = require('vue-server-renderer')

    • renderer.renderToString()

vue 如何解析模板?

  • 模板就是一段字符串,非结构化的数据,没法分析。因此,第一步是将非结构化的模板字符串,转变成结构化的 JS 对象,抽象语法树,即 AST 。其实就是一个 JS 对象,这样就结构化了。

  • 第二步,将 AST 转换成一个 render 函数,步骤是先转换为一段函数体的字符串,然后再用new Function(...)生成函数。

  • 第三部,渲染时执行 render 函数,返回虚拟 DOM 对象,然后执行虚拟 DOM 的patch方法,渲染成真正的 html 。


webpack

前端为何要进行构建和打包

  • 代码层面

  1. 体积更小(tree-shaking、压缩、合并),加载更快

  2. 编译高级语言或语法(ts、es6+、模块化、less/scss)

  3. 兼容性和错误检查(polyfill、postcss、eslint)

  • 研发流程方面

  1. 统一、高效的开发环境

  2. 统一构建流程和产出标准

  3. 继承公司构建规范(提测、上线等)

module chunk bundle 分别什么意思,有何区别

  • mudule: 各个源码文件(如src文件下的文件),webpack中一切皆模块

  • chunk:

    1. 多模块合并成的,如entry import() splitChunk

    2. webpack分析过程中,通过entry import等文件的依赖分析,分析出模块的多个集合

loader 和plugin的区别

  • loader:翻译官,将文件翻译成webpack能识别的js语言,模块转换器,如less转换为css

  • plugin:扩展插件,如 htmlwebpackplugin,是用来增强功能的

常见loader和plugin都有哪些


webpack如何实现懒加载

import()语法,结合vue react异步组件,结合vue-router react-router 异步加载路由

webpack常见性能优化 — 优化构建速度

可用于生产环境优化babel-loader、IgnorePlugin忽略无用文件、noParse避免重复打包、happyPack多进程打包、ParallelUglifyPlugin 多进程压缩 JS

可用于生产环境自动刷新、热更新、DllPlugin 动态链接库插件

  • 优化babel-loader

{
  tets:"/.js$/",
  use:['babel-loader?cacheDirectory'],//?cacheDirectory开启缓存
  include:path.resolve(__dirname,'src'),//明确编译范围
  exculde:path.resolve(__dirname,'node_modules')//排除编译范围
 }
  • IgnorePlugin忽略无用文件

    直接忽略相关文件不进行引入,减小文件体积

//webpack.prod.js配置 忽略 moment 下的 /local 目录
plugins:[
  new webpack.IgnorePlugin(/\.\/locale/,/moment/)
]

//main.js使用 全部忽略之后需要手动引入所需文件
import moment from 'moment'
import‘moment/locale/zh-cn’;
  • noParse避免重复打包

    引入相关文件,但不再进行打包

    已经模块化处理过的文件不需要再进行打包所以需要配置,比如jQuery.min.js等

module:{
  noParse:[/jQuery\.min\.js$/]
}
  • 大文件按需使用 happyPack多进程打包

    因为js是单线程的,使用happyPack可以多进程打包,提高构建速度(特别是多核CPU)

const HappyPack = require('happypack')
module:{rules:{
  tets:"/.js$/",
  use:['happypack/loader?id=babel']//把对 .js 文件的处理转交给 id 为 babel的 HappyPack 市里
}}
plugins:[
  new HappyPack({
    id:"babel",
    loaders:['babel-loader?cacheDirectory']
  })
]
  • 大文件按需使用 ParallelUglifyPlugin 多进程压缩 JS

    webpack有内置的Uglify JS压缩工具,但是单线程没办法多进程压缩,使用 ParallelUglify 可以使压缩更快

const  ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
plugins:[
  new ParallelUglifyPlugin({
    uglifyJS:{//依然是使用UglifyJS,只不过开启了多进程
      output:{
        beautify:false,//是否压缩为一行
        comments:False,//删除所有的注释
      },
      compress:{
          drop_console:true,//删除所有的console语句,可以兼容ie
          collapse_vars:true,//内嵌定义了但是只用到一次的变量
          reduce_vars:true//提取出现多次但是没有定义成变量去引用的静态值
      }
    }
  })
]
  • 自动刷新

    每当检测到文件改变浏览器会刷新当前页面,页面状态会丢失

module.export = {//不常用,一般使用 devServer替代
    watch:true,
    watchOptions:{
        ignored:/node_modules/,忽略文件下的监听
        aggregateTimeout:300,//监听到稳健变化等待默认300ms,防止文件更改过快编译频率太高
        poll:1000,//默认每隔100ms询问一次
    }
}

devServer:{
    port:8080,
    progress:true,
    contentBase:'dist',
    open:true,
    compress:true,//启用gzip压缩
    hot:true,
    proxy:{}
}
  • 热更新

    检测到文件发生改变,不刷新页面更新数据。

const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin')
entry:{
  index:[
    'webpack-dev-server/client?http://localhost:8080/',
    'webpack/hot/dev-server',
    path.join('src','index.')
  ]
}
plugins:[
    new HotModuleReplacementPlugin()
]
devServer:{
    hot:true,
}

//index.js 文件开启
if(module.hot){
    module.hot.accept(listenner,fn)//listenner 可以是字符串也可以是数组'src'||['/src']
}
  • DllPlugin 动态链接库插件

  1. 开发环境使用     

  2. 前端框架如vue体积大,构建慢,较稳定,不常升级版本,同一版本只构建一次即可,考虑使用 DllPlugin

  3. 首先使用DllPlugin打包出dll文件  plugins:[new webpack,DllPlugin({})]

  4. DllReferencePlugin使用dll文件  ‘webpack/lib/DllReferencePlugin’

webpack常见性能优化 — 优化产出代码

体积更小,合理分包不重复加载,速度更快 内存使用更小

小图片base64编码、bundle使用contenthash、懒加载 import()、提取公共代码、IgnorePlugin忽略无用文件、使用CDN加速、使用production、Scope Hoisting

  • 小图片base64编码

rules:{
  test:/\.(png|jpg|jpeg|gif)$/,
  use:{
    loader:'url-loader',
    options:{
      limit:5 * 1024,//小于 5kb 输出位base64
      outputPath:'/img/'
    }
  }
}
  • bundle使用contenthash

    根据文件内容生成hash,文件不变则生成的文件名不变,请求页面可以命中缓存文件、

  • 懒加载 import()

  • 提取公共代码

optimization:{
  splitChunks:{
    chunk:'all',//initial async all
    cacheGroup:{//缓存分组
      vendor:{//第三方模块
          name:'vendor',//chunk名称
          priority:1,//数字越大权限越高,优先提取
          test:/node_modules/,
          minSize:0,//大小限制
          minChunks:1//最少复用过几次
        },
       common:{//公共模块
          name:'vendor',//chunk名称
          priority:0,//数字越大权限越高
          minSize:0,//大小限制
          minChunks:1//最少复用过几次
        }
      }
    }
}
  • IgnorePlugin忽略无用文件

    可以使打包出来的代码更少

  • 使用CDN加速

output:{
    publicPath:‘cndurl’//修改所有静态文件 url 的前缀为改cdn地址
}
rules:use:options:{
  publicPath:'cndurl'//针对图片设置cdn加速
}
  • 使用production

  1. 自动压缩代码,减小代码体积

  2. vue react 等会自动删掉调试代码(如开发环境的warning)

  3. 自动启用Tree-Shaking(删除没有用到的js代码),以下分析ES6 module和commonjs的区别

            1). 必须ES6 Module 才能让其生效,commonjs 不行

            2).es6 module 静态引入,编译时引入。commonjs 动态引入,执行时引入。

            3).只有es6 module才能静态分析,实现Tree-Shaking

  1. 可以使代码体积更小

  2. 创建函数作用域更少

  3. 代码可读性更好

https://img1.sycdn.imooc.com/5f44e6300001089913320433.jpg

babel 和 webpack的区别

  • babel:js新语法编译工具,不关心模块化

  • webpack:打包构建工具,十多个loader plugin的集合


babel

babel-runtime 和 babel-polyfill有什么区别

https://blog.csdn.net/m0_37613019/article/details/108226550

https://www.cnblogs.com/L-xmin/p/12493824.html

babel-polyfill会污染全局对象

Proxy为何不能被pplyfill

 



点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消