收录待用,修改转载已取得腾讯云受权前端
目前Vue.js的火爆不亚于当初的React,本人对写代码有洁癖,代码也是艺术。此篇是准备篇,工欲善其事,必先利其器。咱们先在代码层面进行优化,对咱们完成整个技术架构是起到基础做用的。此准备篇是独立的,即便大家的项目不使用Vue.js,也不影响文章的阅读,是代码的基础优化。webpack
目前Vue.js的火爆不亚于当初的React,本人对写代码仍是有必定洁癖的,代码也是艺术。很长时间在找寻最适合本身的前端开发框架,包括在React最火的时候,我依然在坚持寻找,但React在我心目中并不完美。认识Vue.js的时候,Vue仍是1.0阶段,发现其理念和我心目中的理念至关接近。web
文档友好,API简洁易懂,申明式的模板(个人最爱),MVC的架构,同步/异步组件化等等。一路跟随Vue.js走来,从1.0到2.0,逐步成为世界级的JS框架。做为见证者仍是挺开心的。npm
咱们最新上线的项目是基于Vue的前端后端同构一体化实现的,运用了SSR(Sever Side Render)。从代码的编写和维护角度上,已经比较不错了。并且自己Vue.js的开发效率就很高,因此目前咱们团队还会在这块继续深挖。gulp
此篇是准备篇,工欲善其事,必先利其器。咱们先在代码层面进行优化,对咱们完成整个技术架构是起到基础做用的。此准备篇是独立的,即便大家的项目不使用Vue.js,也不影响文章的阅读,是代码的基础优化。后端
技术选型没有最好的,只有最适合业务的。目前咱们的业务是用gulp+webpack打包构建的。目前有几个痛点:promise
一、代码冗余。咱们常常引入了一个大的utils库,实际上只是引用了这个库中的一个方法,可是却打包了整个库,代码的冗余和浪费。随着引入的文件愈来愈多,这种问题也会变得愈来愈明显。不管是基于代码洁癖,仍是代码体积来看,都有优化的必要。浏览器
二、异步流程控制。随着JS前端的发展,咱们站着大牛的肩膀上,逐步摆脱了回调地狱,以及各类异步流程的坑。有着目前来看最好的异步流程解决方案「async/await方案」。Node 7.6版本已经正式支持了此特性,Browser端也能够统一,达到先后端同构的目的。清晰的异步流程控制对于团队代码的理解和维护都有着积极的意义。babel
三、代码洁癖的考虑,引入箭头函数,简化代码。利用箭头函数不绑定this的特性,解决this「漂移」问题。架构
一、优化方向一,其实经过tree-shaking的能力就能够作到了。咱们使用Webpack2来实现咱们tree-shaking的能力。但这里咱们要注意必定要用ES6的import/export来实现。代码以下:
./src/invoke.js
//模块的继承 export * from './invoke_base.js'; //定义变量或常量 const xxx = 1; //定义私有函数 function _private(){ // } //定义公有函数 export function aaa() { console.log(1); } export function bbb() { console.log(2); } export default function ccc(){ console.log(3); }
./src/invoke_base.js
export function ddd() { console.log(4); }
./src/tree_shaking.js
import * as uu from './invoke.js'; console.log(uu.ddd);
改造好代码后,经过执行webpack命令,咱们能够获得以下结果:
注意一下红框部分的内容,在非压缩模式下,实际上并非彻底意义上的tree-shaking,仍是有把没有使用的方法打入文件中,可是会提示「unused harmony export」这样的提示。
而后咱们执行一下webpack的压缩命令:
压缩代码中只有「console.log(4)」,也就是aaa, bbb, ccc这三个被标记为「unused harmony export」的方法在压缩版本中移除了,只有ddd因为被引用,因此保留了。证实咱们的tree-shaking是成功的。并且要看到ddd是基类模块的方法,证实在继承的状况下,tree-shaking也是正确执行的!
尽可能使用import * as uu from './invoke.js'
隐式语法而无须使用import {ddd} from './invoke.js'
这种显式语法。
使用前者很是方便的在调用的时候使用uu.xxx这种写法,并且tree-shaking是能够正确解析的。好比代码中只调用了uu.ddd,那么uu.aaa, uu.bbb, uu.ccc是能够tree-shaking过滤掉的。而不用特地地指定import {ddd} from './invoke.js'
这种隐式的写法极大的方便了咱们代码的灵活性。而不须要调用一个,我就要在import的地方显式的加一个!看,一切都很美好。tree-shaking是很智能的!
阶段性小结:
1)用import/export来改造代码,这是tree-shaking的基础,ES6的模块支持继承,能够正确执行tree-shaking。
2)webpack的打包非压缩的状况下会保留unused function,压缩版才会真正去掉。
3)尽可能使用import * as uu from './invoke.js'隐式语法而无须使用import {ddd} from './invoke.js'这种显式语法。
4)咱们的业务接入tree-shaking特性后,代码体积有减小30%。
二、优化方向二,在Browser侧咱们的异步流程控制其实并无特别复杂,毕竟使用场景上仍是没那么多的回调地狱。一般咱们的解决方案就是简单地就用回调处理,复杂的逻辑,可能有用相似Step.js,Async.js这种类库来解决。代码从可读性上仍是能够的,好比:
这个示例中综合了同步和异步代码,从代码的表现形式上仍是能够理解为同步的流程。但这种类库本质仍是callback的方式,采用Promise的方式是咱们将来的趋势,并且直接上Async/Await方案,争取一步到位。改造后咱们的代码能够相似以下图所示:
类比能够看出,咱们的代码在可读性上又上了个台阶。会有种摆脱了垃圾代码的舒畅感。
在后端Node 7.6已经正式支持了async/await语法,因此后端直接升级便可。在前端而言,咱们这里仍是有很多工做要作的。(不想看过程的朋友,直接下载本文结尾的DEMO自行实践)
1)首先咱们的浏览器端对Promise对象还有兼容问题:
咱们必须引入Promise-polyfill才能安心在浏览器端使用。通过咱们业务的实践和筛选,咱们最终选择了这个taylorhakes/promise-polyfill,这个Promise-polyfill的优势是代码少,该有的核心方法都有,知足咱们的业务须要。不要使用Babel自带的poly-fill,代码太冗余了。因此咱们在文件中引入:
import Promise from 'promise-polyfill';
2)其次咱们要经过Babel来翻译async/await语法,Babel翻译前:
Babel翻译后:
其实这样看起来并无特别的差异,但这样运行是会报错的。会提示:
这里主要是缺乏regeneratorRuntime的定义,因此咱们须要人为的补上去,在文件头部引入:
import "regenerator-runtime/runtime";
就能够愉快地在前端使用async/await啦
阶段性小结:
1)须要配置好webpack.config.js以及babel的配置,这个参考DEMO。
2)在须要进行async/await的文件引入
3)虽然能够支持浏览器的async/await语法,咱们看到实际编译的文件仍是很大的:
此问题待解决。
参考DEMO来看,有些配置的地方仍是要注意一下的。
一、webpack.config.js,因为是webpack2,和webpack并不彻底同样,这里须要修改兼容一下。
二、.babelrc的配置推荐使用babel-preset-env,这是目前最新的解决方案,会很是灵活的经过参数指定来兼容当前的环境。
三、必定要升级最新的正式版的webpack2,beta版的webpack2有一些BUG会致使编译不过。
四、因为进行Babel编译估计比较慢,建议开发阶段不要开Babel编译。如今的Chrome浏览器55版本以上都支持async/await语法,在开发模式中PC模拟调试的时候,彻底能够不开Babel编译。在进行真机调试的过程当中,IOS的最新浏览器和Android新系统的最新浏览器也都是支持async/await语法的,也不用编译。
因此作两个webpack文件是一个方法,好比webpack.dev.config.js以及webpack.config.js。咱们编译的过程放到提测阶段便可。这样节省开发编译的时间和效率,这是个小技巧。
http://static.zybuluo.com/wwanghee/atuflxa5zj7jkgnc2n6tgup0/async_await.zip
下载以后运行
npm install webpack //无压缩版 webpack --optimize-minimize //压缩版