树酱的前端知识体系构建(上)

简介: 前沿:先预祝掘金升级成功... 树酱君是个渣渣,梳理了下发现还是蛮多知识点不够扎实,童鞋有机会也定期给自己做个复盘和回顾,梳理自己的知识体系。再加上前端娱乐圈变化多端,以至于我们既要加强对底层基础知识的巩固,查漏补缺,也要保持对新事物探索的好奇心。那树酱我是如何构建自己的知识体系呢?(特别算法是硬伤啊)⏰ 该本章为上下两章,本次分享是上章

微信截图_20220514092047.png


前沿:先预祝掘金升级成功... 树酱君是个渣渣,梳理了下发现还是蛮多知识点不够扎实,童鞋有机会也定期给自己做个复盘和回顾,梳理自己的知识体系。再加上前端娱乐圈变化多端,以至于我们既要加强对底层基础知识的巩固,查漏补缺,也要保持对新事物探索的好奇心。那树酱我是如何构建自己的知识体系呢?(特别算法是硬伤啊)⏰ 该本章为上下两章,本次分享是上章


1.Vue 知识体系


微信截图_20220514092100.png


1.1 基础原理


1.1.1 Vnode


Vnode也称虚拟node节点,是对真实元素的抽象。诞生的背景是因为前端在很长一段时间通过直接操作Dom来达到修改视图,随着项目庞大,维护就变成一个问题。那换个角度想如果把真实Dom树抽象成为一棵以JS语法构建的抽象,然后通过修改抽象树的结构来转换成真实的Dom来重新渲染到视图。



  • Vnode如何检测变化并更新视图呢? diff算法


🌲 拓展阅读:


1.1.2 nextTick


nextTick目的是将回调函数的调用延迟到下一次dom更新数据后,换句话说就是修改数据后并不会立即更新dom ,因为dom的更新是异步的,无法通过同步代码获取,需要使用nextTick,在下一次事件循环中获取(Vue中Dom的更新是异步的)


this.msg = "Hello world."
✅ this.$nextTick(() => {
    this.msg2 = this.$refs.msgDiv.innerHTML
  })
🚫 this.msg3 = this.$refs.msgDiv.innerHTML


🌲拓展阅读:



1.1.3 MVVM


MVVM全称为:Model-View-View-Model,诞生背景是在传统的MVC架构中,缺少一个数据解析的角色,而M、V、C等都不应该处理数据解析,于是专门为数据解析的就诞生了一个新的类:ViewModel,主要用于将Model和View关联起来,数据变化更新视图,视图变化更新数据


微信截图_20220514092110.png


🌲拓展阅读:


1.1.4 双向绑定原理


上一节提到mvvm,本质上就是vue数据双向绑定,它是通过数据劫持结合设计模式中的发布者-订阅者模式,主要包括以下步骤


  • 1.将数据data变成可观察: 通过 Object.defineProperty()设置属性的setter和getter来监听数据的变化,通过getter进行依赖收集,而每个setter方法就是一个观察者,关于更多的Object.defineProperty()实践可以阅读 树酱的如何更好管理 Api 接口 中有提到 ( Vue3.0 使用Proxy替代)


  • 2.添加订阅者Watcher和添加消息订阅器Dep( 如果数据变化,通知所有订阅者)


  • 3.实现Compile


🌲拓展阅读:


1.1.5 Vue相关的API


Vue暴露一些常用的API,包括全局、生命周期、组合、实例property等API,可以查看vue官方所有API集合文档


  • 全局 API :比如 Vue.use( plugin )用于全局引用插件, 具体使用可阅读树酱的
  • 组合 API: 比如 project/inject 用于允许祖先组件向其所有子孙后代注入一个依赖
  • 实例property API: 比如vm.$refs 获取持有注册过ref属性的所有 DOM 元素和组件实例


🌲拓展阅读:


1.2 vuex 状态管理


Vuex 是一个专为 Vue.js 应用开发的状态管理工具,采用集中式的存储方法来记录组件的状态,用一个对象就包含了全部的应用层级状态,而每个应用将仅仅包含一个 store 实例,但是可以用模块化来管理区分


1.2.1 模块化状态化管理


由于vuex的单一状态树,会导致说随着应用庞大,应用要管理状态集合会很大,store 对象就会显得臃肿,难以管理,那就需要用到Module区分,每个Module都拥有自己的 state、mutation、action、getter


🌲拓展阅读:


1.2.2 持久化管理


我们可以使用状态持久化来实现缓存状态,因为vuex的数据是存放在内存中,当我们刷新页面的时候,内存会被删除,如果我们想持久化存储一些数据,就需要依赖     localstorge或者vuex-persistedstate


  • 手动利用HTML5的本地存储(localstorge)
  • 使用vuex-persistedstate插件


🌲拓展阅读:


注意: 默认情况下每次 commit 都会向 localstorage 写入数据,localstorage 写入是同步的,这样对性能存在影响,应该分场景尽量避免频繁写入持久化数据。


1.2.3 vuex 五种属性


  • state:vuex的基本数据,用来存储变量
  • getter:从基本数据(state)派生的数据,相当于state的计算属性
  • mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。
  • action:Action 提交的是 mutation,并且可以包含任意异步操作,但不能直接变更状态
  • modules:1.2.1 章节提到的vuex模块化


1.3 vue-router


SPA应用大多由前端路由来控制页面的跳转,通过url的切换,在不请求服务器的前提,更新页面视图,vue应用离不开vue-router,涉及知识内容包括以下几点


  • hash模式和history模式有什么不同?
  • 路由拦截应该怎么做?
  • 路由如何实现模块化管理?
  • keep-alive如何对组件进行缓存?


更多了解vue-router可以阅读树酱的 🌲前端路由那些事



1.4 组件开发


Vue组件开发是为了通过从业务代码中解耦出代码复用率高的片段,抽出并封装为高复用的组件、涉及知识内容包括以下几点


  • Vue 组件的三个重要因是什么? props、事件 和 slots
  • 组件间是如何通信的?
  • Vue组件化之插槽slot如何使用?
  • mixin 在组件中可以起到什么作用?
  • Vue高阶组件是什么?


1.4.1 组件间通信和传值


Vue组件的通信可以是:子父关系,也可以是子祖关系、兄弟关系。不同的的关系也就意味方式不同,主要包括以下几种方式:


  • $parent与$children
  • $emit
  • bus $eventBus: 事件总线,通过微信截图_20220514095721.pngon来完成传递接收
  • provide与inject
  • props 与 $refs


🌲拓展阅读:


1.4.2 Slot 插槽


来自Vue官方介绍:slot元素作为承载分发内容的出口,简单理解就是“占坑”,子组件预先把位置占好,然后根据业务场景需要,子组件在编写相应的信息


🌲拓展阅读:


1.4.3 Mixin 混入


mixin提供了一种非常灵活的方式,可以用来分发Vue组件中的可复用功能,借助Mixin多个组件可以共享数据和方法。同时引入mixin的组件,mixin中的方法和属性也就并入到该组件中,可以直接使用。钩子函数也将会在两个都被调用(Mixin中的钩子会先执行)


更多了解mixin实践可以阅读树酱的 🌲组件库源码中这些写法你掌握了吗? 中关于组件库mixin的用法


1.4.4 高阶组件


高阶组件也称为HOC,它被描述为一种在组件之间共享公共功能而不需要重复代码的方法。作用在于增强组件的功能,简单定义就是:你向一个方法传入组件,然后返回一个新的组件,这就是一个HOC


🌲拓展阅读:



1.5 axios


应用离不开请求库,而vue技术栈中请求库谈及最多的,非axios莫属,axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,涉及知识内容包括以下几点


  • axios 如何做二次封装(拦截器)?
  • 如何结合axios做API管理 ?
  • axios 如何取消请求?
  • token过期如何在axios刷新?


关于前三者的学习可以阅读树酱的🌲如何更好管理 Api 接口


🌲拓展阅读:



1.6 vue-cli


vue-cli是vue官方的脚手架,可以使用Vue-cli来快速构建项目,且对 Babel、TypeScript、ESLint、单元测试等提供了开箱即用的支持,简化了部署、打包、代码扫描、单元测试等流程,涉及知识内容包括以下几点


  • 如何基于vue-cli部署项目?
  • 如何配置vue.config.js 打包性能最佳应用?
  • 本地开发跨域如何解决?


1.6.1 vue-cli 部署项目


前端部署离不开几个环境包括本地、mock、开发、测试、预生产、生产等等,需要根据不同环境定义不同的配置文件(管理api等),还需要定义好编译脚本(packjson中的scripts),还需要注意publicpath的定义是否需要修改


更多了解可以阅读树酱的🌲基于 Vue-cli 3x的项目部署


🌲拓展阅读:



1.6.2 配置最佳打包


前端SPA应用上线服务器本质上是编译好的静态资源上传,那编译打包就是影响性能较大的因素,那么如何配置vue.config.js打包性能最佳,可以阅读第4节的webpack配置插件,主要解决这几个问题


  • 针对请求数进行优化: (去除prefetch)
  • 公用代码提取,使用cdn加载: (config.externals)
  • 配置代码压缩


🌲拓展阅读:



1.6.3 本地开发devServer


本地开发中存在跨域问题?我们可以通过vue.config.js中devServer配置来做反响代理解决!如何做?看下面这篇


🌲拓展阅读:


2.工程化知识体系


微信截图_20220514092131.png


关于前端工程化,本质上是通过规范和工具来提高前端应用质量,树酱在之前曾梳理过,更多了解请阅读 🌲 前端工程化那些事,本文在原来文章的基础上拓展和补充


2.1 Git


众所周知,git不单单只是代码管理工具,还可以做分支管理、commit message检验、Pull Request等


🌲拓展阅读:



2.2 Npm


只会npm install? npm其实提供很多功能包括如下几个常用的


  • npm publish :发包管理
  • npm link :用来在本地项目和本地npm模块之间建立连接,可以在本地进行模块测试


🌲拓展阅读:



2.3 构建工具


前端项目构建工具很多包括Rollup、Webpack、Parcel,然而最近在Vue.js 3.0 Beta里,尤大大提到他在做的这个小工具 vite,关于vite是否能替代wepack?


  • Webpack:适⽤于⼤型项目构建:webpack目前生态最完善,应用场景更多,社区人气高,有强⼤的loader和插件⽣态
  • Rollup:适⽤于工具库的打包: 可以将各个模块打包进⼀个⽂件中,具备 Tree-shaking 来删除⽆⽤的代码,降低代码体积,但是不具备webpack强大的插件生态,定位更适用于聚焦于库的打包
  • Parcel:适⽤于试验: 虽然无配置的优势,可以快速打包应用,且打包效率,但是不具备Tree-shaking,导致输出文件偏大


🌲拓展阅读:


2.4 CI/CD 和项目部署


自从有了DevOps,持续集成,持续交付(CI/CD)成了项目部署主流,前端SPA项目部署需要打包📦应用,我们可以结合 Jenkins + Docker + Nginx 来完成,如果是SSR应用还需要用PM2来管理进程


更多了解可以阅读树酱的🌲前端运维部署那些事


🌲拓展阅读:

关于DevOps和工程化系列 推荐 shanyue山月老哥的专栏文章



3 Node知识体系


微信截图_20220514092143.png


树酱之前梳理了两篇关于node的面试官系列,感兴趣的童鞋可以看看面试官问你关于node的那些事(基础篇)面试官问你关于node的那些事(进阶篇)。同时对于node平时工作业务场景少,树酱的node体系也比较小,后期会调整补充,目前可能不太适合高阶的童鞋。


🌲拓展阅读:


4.性能优化


微信截图_20220514092153.png


4.1 性能指标


性能指标是用来通过获取数据来衡量应用的性能,并通过数据来体现出性能的好坏,常用的性能指标有以下几种


我们也可以通过lighthouse这个工具来测试下我们当前的应用

  • FCP: 首次内容绘制
  • FMP:首次有效绘制
  • TTI:首次可交互时间


下通过页面一个手机页面加载截图来帮助我们理解性能指标时间点所带来的体验


微信截图_20220514092210.png


🌲拓展阅读:



4.2 webpack


4.2.1 代码分割


在业务场景中,项目中可能会引入很多第三方库,这些库可能跟业务无关且内容也可能不变,如果都打包到一起,那么用户通过浏览器想要浏览最新效果就必须重新执行完新的文件,如果能把不变的代码都单独打成一个文件,且文件名每次都一样。那么浏览器可以从缓存中读取,而不是重新发起请求,或者将公共部分去重,那这个时候代码分割就起了个重要的作用


webpack 使用 SplitChunksPlugin去重和分离 chunk,而在vue-cli 3中是在的vue.config.js中只要配置chainWebpack中的splitChunks即可,如下:


微信截图_20220514094741.png


🌲拓展阅读:


引用一句话:代码分割的本质,就是在**“源码直接上线”“打包为唯一的脚本main.bundle.js”**这两种极端方案之间寻找一种更符合实际场景的中间状态,用可接受的服务器性能压力增加来换取更好的用户体验。



4.2.2 UglifyJs 压缩


通过UglifyJSPlugin来对js文件进行压缩,以此减小js文件的大小,加速资源加载速度,但是一般在生产环节开启,因为会拖慢了webpack原本的编译速度


微信截图_20220514094753.png


4.2.3  gizp  压缩


我们可以使用compression-webpack-plugin插件进行压缩,相当于gzip的效果


我们在vue-cli 3下的vue.config.js中configureWebpack配置如下:


微信截图_20220514094802.png


4.2.4 Tree-shaking


Tree-shaking也叫摇树优化,是webpack 2之后引入原本rollup特有的Tree-shaking。用来将无用代码移除。而tree-shaking 是在 ES6 modules 的静态特性基础上才得以实现的,也就是说只有你使用到 ES6 module  才能使用 tree-shaking


🌲拓展阅读:


4.2.5 webpack-bundle-analyzer


开发中,生产环节或者开发环境我们想对比下,分析报告进行性能优化对比,确定vue项目的性能是否得到完善,可以通过配置webpack-bundle-analyzer插件,他能以图形化的方式展示bundle中所有的模块的构成的各自构成的大小,执行方式: npm run build --report


微信截图_20220514094813.png


🌲拓展阅读:


4.3 Nginx


Nginx对性能的优化思考以下几点:


  • 如何在nginx配置gzip ?
  • 如何通过设置expires 缓存来调优?
  • 如何在负载均衡做优化性能?


关于Nginx 体系化学习可以阅读树酱的Nginx那些事


4.3.1 Gizp


开启Nginx gzip,压缩后,静态资源的大小会大大的减少,从而可以节约大量的带宽,提高传输效率,带来更好的响应和体验


微信截图_20220514094822.png


4.3.2 静态资源缓存设置


有些静态资源更新频率低或者不更新,我们可以通过设置expires来配置缓存时间,以此来达到优化性能作用,那怎么配置呢?


假设我想通过web应用的图片缓存一周,那你可以在nginx中配置如下,配置完之后一周之内的资源只会访问浏览器的资源,而不是去请求Nginx


微信截图_20220514094831.png



4.3.3 负载均衡


众所周知,负载均衡器可以通过分配其他的服务器给用户,来增加的网站的稳定性和响应速度,而且负载均衡器有四种常用方式,这里要提的是响应时间来分配的模式,可以让多台服务器竞争,找出相应最快的并返回内容给用户,配置如下


微信截图_20220514094840.png


🌲拓展阅读:


4.4 其他


4.4.1 预请求prefetch


prefetch是link元素中的rel属性值,通过定义该属性,让浏览器加载下一个页面可能会使用到的资源。加速下一个页面的加载速度,常用的应用场景在SSR中,首页的资源加载都使用preload,而非首页的其他路由的资源,则用prefetch,那两者又有啥区别呢?看下面


  • preload 是通知浏览器,页面必定需要的资源,但浏览器一定会加载这些资源
  • prefetch 是通知浏览器,页面可能需要的资源,但浏览器不一定会加载这些资源


微信截图_20220514094850.png


🌲拓展阅读:

那发现请求数增多,是因为我们页面预先渲染了其它组件,我不想要预加载,我应该怎么处理?


可以在vue.config.js 中delete 掉 preload 与 prefetch


微信截图_20220514094859.png


dns-prefetch又是啥?跟prefetch一样吗?


假设现在我们访问百度baidu.com,这个时候需要DNS把域名先转化为对应的 IP 地址,这过程非常耗时。 可以通过DNS prefetch 分析这个页面需要的资源所在的域名,在浏览器空闲时提前将这些域名转化为 IP 地址,减少DNS的请求次数,进行DNS预先获取


<link rel='dns-prefetch' href='http://baidu.com'>  


4.4.2 defer 与 async


defer与async是配置script标签中的两个属性,使用场景是在不阻塞页面dom文档树解析的基础上,控制脚本的下载和执行,那两者有啥区别


  • defer: 渲染完再执行, 加载完成后需要等待页面也加载完成才会执行代码
  • async: 下载完就执行, 加载完成后会自动执行脚本


🌲拓展阅读:


4.4.3 SSR 与 Prerender


服务端渲染SSR和预渲染Prerender,可以解决白屏时间太长的问题,可以提升浏览器显示页面的速度,但是不推荐用预渲染,预渲染如果你项目中路由过多,比如你有1000篇文章需要预渲染,每次更新都要执行一次,不现实


微信截图_20220514094909.png


🌲拓展阅读:


4.4.4 防抖与节流


函数节流和函数防抖都是在限制被触发函数的执行次数,以解决函数触发频率过高导致浏览器响应速度跟不上出现的卡顿、延迟现象。这也就是前端的性能优化。


  • 防抖 debounce:顾名思义就是防止抖动,适用场景:在短时间内多次触发同一实践,限制只执行一次。
  • 节流 throttle: 类似阀门管制一样,阀门会定期开放,函数执行一次之后,在一个时间段内会失效关闭,过了时间则会重新激活开启


🌲拓展阅读:


4.5 按需加载


根据视图需要再加载,比如一个页面图片很多,如果加载完页面全部加载图片,会影响性能,让图片滚动到可视化区域再加载不香吗?  再比如一个长列表数据很长,不限制的往下加载dom数据,每一次都是一次重绘,对性能影响很大,在页面上创建一个容器作为可视区,在这个可视区内展示长列表中的一部分,然后只在这个区域不香吗?


4.5.1 vue-lazyload


关于vue-lazyload可以阅读树酱的聊聊前端的按需加载 - 图片懒加载


4.5.2 组件动态加载


关于组件动态可以阅读树酱的聊聊前端的按需加载 - 组件的按需加载


4.5.3 虚拟列表


虚拟列表其实是按需显示的一种实现,即只对可见区域进行渲染,对非可见区域中的数据不渲染或部分渲染的技术,从而达到极高的渲染性能。


微信截图_20220514094926.png



相关文章
|
4天前
|
前端开发 JavaScript 开发工具
从前端到后端:构建现代化的全栈开发环境
在当今技术迅速发展的时代,全栈开发已成为越来越受欢迎的趋势。本文将探讨如何构建现代化的全栈开发环境,涵盖从前端到后端的各个方面,包括技术选型、开发工具、部署流程等内容,帮助开发者更高效地搭建全栈项目。
|
4天前
|
编解码 前端开发 JavaScript
构建高效响应式Web界面:现代前端框架的比较
【4月更文挑战第9天】在移动设备和多样屏幕尺寸盛行的时代,构建能够适应不同视口的响应式Web界面变得至关重要。本文深入探讨了几种流行的前端框架——Bootstrap、Foundation和Tailwind CSS,分析它们在创建响应式设计中的优势与局限。通过对比这些框架的栅格系统、组件库和定制化能力,开发者可以更好地理解如何选择合适的工具来优化前端开发流程,并最终实现高性能、跨平台兼容的用户界面。
|
4天前
|
资源调度 前端开发 测试技术
前端工程化实践:从零搭建现代化项目构建流程
【4月更文挑战第6天】本文介绍了前端工程化的概念和重要性,包括模块化、自动化、规范化和CI/CD。接着,讨论了选择合适的工具链,如包管理器、构建工具和测试框架。然后,详细阐述了如何从零开始搭建一个基于React的现代化项目构建流程,涉及初始化、代码规范、测试、CSS处理、代码分割和CI/CD配置。最后,提到了持续优化与迭代的方向,如性能优化、类型检查和微前端。通过这样的实践,开发者可以提升开发效率和代码质量,为项目长远发展奠定基础。
44 0
|
4天前
|
前端开发 JavaScript 关系型数据库
从前端到后端:构建现代化Web应用的技术探索
在当今互联网时代,Web应用的开发已成为了各行各业不可或缺的一部分。从前端到后端,这篇文章将带你深入探索如何构建现代化的Web应用。我们将介绍多种技术,包括前端开发、后端开发以及各种编程语言(如Java、Python、C、PHP、Go)和数据库,帮助你了解如何利用这些技术构建出高效、安全和可扩展的Web应用。
|
4天前
|
移动开发 前端开发 数据可视化
前端HTML:构建网页的基石
前端HTML:构建网页的基石
21 0
|
2天前
|
前端开发 Java Go
从前端到后端:构建现代化Web应用的技术实践
本文将介绍如何通过前端和后端技术相结合,构建现代化Web应用的技术实践。我们将探讨前端开发、后端架构以及多种编程语言(如Java、Python、C、PHP、Go)在构建高效、可扩展的Web应用中的应用。
|
2天前
|
Web App开发 前端开发 JavaScript
构建跨浏览器兼容的前端应用:技术实践与挑战
【5月更文挑战第16天】构建跨浏览器兼容的前端应用是应对浏览器差异和多样性的挑战。使用现代框架(如React、Vue)能自动转换代码,编写可移植的Web标准代码,结合浏览器兼容性测试工具和Polyfill解决旧浏览器支持问题。关注浏览器更新,应对性能、API差异和样式问题,采用渐进增强、条件判断和CSS Reset策略确保应用在各种浏览器上运行良好。
|
2天前
|
前端开发 JavaScript NoSQL
从前端到后端:构建全栈开发者的必备技能
随着互联网技术的不断发展,全栈开发者的需求日益增长。本文将介绍如何从前端到后端,掌握全栈开发所需的关键技能,包括前端框架的选择、后端语言的学习以及数据库的应用,帮助读者构建成为全面的技术专家。
|
4天前
|
存储 JavaScript 前端开发
使用Vue.js构建交互式前端的技术探索
【5月更文挑战第12天】Vue.js是渐进式前端框架,以其简洁和强大的特性深受开发者喜爱。它聚焦视图层,采用MVVM模式实现数据与视图的双向绑定,简化开发。核心特性包括响应式数据绑定、组件化、模板系统和虚拟DOM。通过创建Vue实例、编写模板及定义方法,可以构建交互式前端,如计数器应用。Vue.js让复杂、交互式的前端开发变得更加高效和易维护。
|
4天前
|
开发框架 Dart 前端开发
【Flutter前端技术开发专栏】Flutter中的Web支持:构建跨平台Web应用
【4月更文挑战第30天】Flutter,Google的开源跨平台框架,已延伸至Web领域,让开发者能用同一代码库构建移动和Web应用。Flutter Web通过将Dart代码编译成JavaScript和WASM运行在Web上。尽管性能可能不及原生Web应用,但适合交互性强、UI复杂的应用。开发者应关注性能优化、兼容性测试,并利用Flutter的声明式UI、热重载等优势。随着其发展,Flutter Web为跨平台开发带来更多潜力。
【Flutter前端技术开发专栏】Flutter中的Web支持:构建跨平台Web应用