Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!
2013年7月28日,尤雨溪第一次在 GItHub 上为 Vue.js 提交代码;2015年10月26日,Vue.js 1.0.0版本发布;2016年10月1日,Vue.js 2.0发布。
最早的 Vue.js 只做视图层,没有路由, 没有状态管理,也没有官方的构建工具,只有一个库,放到网页里就可以直接用了。
后来,Vue.js 慢慢开始加入了一些官方的辅助工具,比如路由(Router)、状态管理方案(Vuex)和构建工具(Vue-cli)等。此时,Vue.js 的定位是:The Progressive Framework。翻译成中文,就是渐进式框架。
Vue.js2.0 引入了很多特性,比如虚拟 DOM,支持 JSX 和 TypeScript,支持流式服务端渲染,提供了跨平台的能力等。Vue.js 在国内的用户有阿里巴巴、百度、腾讯、新浪、网易、滴滴出行、360、美团等等。
Vue 已是一名前端工程师必备的技能,现在就让我们开始深入学习 Vue.js 内部的核心技术原理吧!
什么是webworker
众所周知,JavaScript是一个单线程的,也就是说,所有的任务都在一个线程上去执行,只能等着前面的任务执行完毕,才可以执行后面的任务。当我们面对大数据量计算的场景下,我们的页面就会出现一个假死的现象,用户什么都做不了,只能傻傻的等待。我们呢,就等待着测试小姐姐给我们提一个bug。。。
webworker就是来解决这个东西的,先说一句,webworker不是什么第三方的东西,它是JavaScript原生支持的。webworker为JavaScript创建多线程环境,允许主线程创建worker子线程,当然,可以创建多个。我们可以将一些任务,分配给子线程去做。在主线程运行的同时,子线程在后台也同时运行,互不干扰。等子线程做完了,就把结果返回给主线程。
这样的好处就是我们可以把那些计算量大、耗时长的任务,分配给worker线程去做,主线程就会很流畅,不会被阻塞或者拖慢。
但是,worker线程一旦创建成功,就会一直执行,不会被主线程上的活动打断。举个例子,当主线程有一个弹窗alert,那么会阻塞主线程,但是不会对子线程有任何影响。这也就说明了,worker是比较消耗资源的,不应该过度使用,而且当使用完毕了,就要给关闭。
原生webworker如何使用
废话不多说,直接上代码,在上代码之前,我们先设定一个场景:
你有一个十万级的简单累加运算,页面中有一个input输入框,进入页面的时候,计算开始,我们去观察input输入框能否同步输入。
不使用webworker
代码目录结构如下:
test_webworker
// index.js ---主线程
let sum = 0;
for (let i = 0; i < 200; i++) {
for (let i = 0; i < 10000; i++) {
sum += Math.random()
}
}
页面运行后效果:直接假死现象,因为后台正在计算,input框都没有渲染出来
使用webworker子线程
现在我们使用webworker,将这200万次累加计算,给worker子线程去做。
代码目录如下:
test_webworker
// index.js ---主线程
// 创建一个子线程
const worker = new Worker('worker.js')
// 接收子线程发来的消息
worker.onmessage = e => {
console.log('主线程接收到:', e.data)
worker.terminate();
}
// 向子线程发消息
worker.postMessage('子线程,你真帅!')
// worker.js ---子线程
// 接收主线程发来的消息
onmessage = e => {
console.log('子线程接收到:', e.data)
}
let sum = 0;
for (let i = 0; i < 200000; i++) {
for (let i = 0; i < 10000; i++) {
sum += Math.random()
}
}
// 向主线程发送消息
postMessage(sum)
页面运行如下:
在子线程运行的过程中,主线程中的input输入框是可以同时输入内容的,并没有因为计算而阻塞UI渲染。当worker运行完毕,就把sum传递给主线程,这样就解决了。
Vite 中使用webworker
在 Vite 中,不用这么复杂,我们只需要通过模块的方法,导入一个模块的 js,然后在后面冠以一个 ?worker,就会返回一个 MyWorker 或者是任何的 worker 对象,然后我们再去实例化这个 Worker,就会返回这个 worker 对象了。也就是说,我们可以把这个 worker 的 js,当成是一个模块来使用。
听起来好像很是一回事,其实很简单,通俗的两句话解决:
// 原生的:
const worker = new Worker('./worker.js)
worker.onmessage = function(ev){}
// Vite中的:用原生的,可以
const worker = new Worker('./worker.js)
worker.onmessage = function(ev){}
// Vite中的:用模块导入形式的,也可以
import MyWorker from './worker?worker'
const worker = new MyWorker()
worker.onmessage = function(ev){}
加上 ?worker 有啥用?加上后,就会把当前模块当成webworker来使用了,就可以通过 new 来创建 webworker 了。
Vue 进阶系列教程将在本号持续发布,一起查漏补缺学个痛快!若您有遇到其它相关问题,非常欢迎在评论中留言讨论,达到帮助更多人的目的。若感本文对您有所帮助请点个赞吧!
叶阳辉
HFun 前端攻城狮
往期精彩:
Vue 进阶系列丨Object 的变化侦测
Vue 进阶系列丨Array 的变化侦测
Vue 进阶系列丨虚拟DOM和VNode
Vue 进阶系列丨Patch 和模板编译
Vue 进阶系列丨事件相关的实例方法
Vue 进阶系列丨生命周期相关的实例方法
Vue 进阶系列丨生命周期
Vue 进阶系列丨自定义指令
Vue 进阶系列丨最佳实践
Vue 进阶系列丨Mixin 混入
Vue 进阶系列丨权限控制 addRoute()
Vue 进阶系列丨npm发布vue组件
Vue 进阶系列丨Vuex+TS 代码提示
Vue 进阶系列丨自定义指令实现按钮权限功能
Vue 进阶系列丨Pinia 的基本使用
Vue 进阶系列丨vue2和vue3定义插件的区别
Vue 进阶系列丨vuex持久化