设为首页 收藏本站
查看: 1107|回复: 0

[经验分享] 【前端构建】WebPack实例与前端性能优化

[复制链接]

尚未签到

发表于 2017-2-23 11:00:23 | 显示全部楼层 |阅读模式
  计划把微信的文章也搬一份上来。
  这篇主要介绍一下我在玩Webpack过程中的心得。通过实例介绍WebPack的安装,插件使用及加载策略。感受构建工具给前端优化工作带来的便利。
壹 | Fisrt
DSC0000.jpg

  曾几何时,我们是如上图的方式引入JS资源的,相信现在很少遇见了。近年来Web前端开发领域朝着规范开发的方向演进。体现在以下两点:

  •   MVC研发构架。多多益处(逻辑清晰,程序注重数据与表现分离,可读性强,利于规避和排查问题...)
  •   构建工具层出不穷。多多益处(提升团队协作,以及工程运维,避免人工处理琐碎而重复的工作)

    • 模块化开发
    • 将前端性能优化理论落地,代码压缩,合并,缓存控制,提取公共代码等
    • 其他的还包括比如你可以用ES 6 或CoffeeScript写源码,然后构建出浏览器支持的ES5

  所以,前端这么好玩,如果还有项目没有前后端分离的话,真的是守旧过头了。
  
  主流构建工具
  市面上有许多构建工具,包括Grunt、Gulp、browserify等,这些和WebPack都是打包工具。但WebPack同时也具备以下特点:

  •   相比Grunt,WebPack除了具备丰富的插件外,同时带有一套加载(Loader)系统。使它支持多种规范的加载方式,包括ES6、CommonJS、AMD等方式,这是Grunt、Gulp所不具备的。
  •   从代码混淆的角度来看,WebPack更加的极致
  •   代码分片为处理单元(而不是文件),使得文件的分片更为灵活。
  P.S.此处只做简单的比较,不论孰优孰劣。其实工具都能满足需求,关键是看怎么用,工具的使用背后是对前端性能优化的理解程度。
貳 | Second
  WebPack安装与使用
  WebPack运行在 NodeJS之下,并且它及其插件都是使用NPM(NodeJS的包管理工具)管理。

  •   安装Node及NPM。到NodeJS官网安装包,安装即可
  •   全局安装WebPack。联网情况下,执行命令行 $npm install webpack -g 即可。
  此至即可使用WebPack了,到WebPack官网去按着Get start(http://webpack.github.io/docs/tutorials/getting-started/)的步骤来,感受一个最简单的构建过程。
  然而要把WebPack用好,只是跑起来是远远不够的。
叁 | Third
  WebPack插件
  花较大篇幅介绍插件的使用,以下通过在一个DemoApp的构建过程中思考的一些问题(这些问题基本会在每个项目中遇到),让这些插件逐一登场。
  一、文件过大
  DemoApp最初的构建结果如下:
DSC0001.jpg

  这里生成了一个topic.xxx.js,这个文件本来很小,估计只有10Kb左右,但构建的结果居然快1Mb了。在3G网络(750Kb/s)下的加载瀑布流如下图:
DSC0002.jpg

  这张图(体现前端文件加载过程)曝露了几个问题:

  •   上面箭头所指的很蓝色柱子,说明了大部分时间消耗在加载topic.xxxx.js上。
  •   所有JS文件相关的柱子是一根结束了另一根才开始,说明不合理的文件合并策略,导致文件串行加载。
  •   结果就是如底部的箭头所看到的,页面的加载时间太长了(3G网络,10+秒)。
  观察构建的文件,发现原来构建工具把React、jQuery等代码库合并到了topic.xxxx.js,造成此文件过大。如果再加一个activity模块呢?很明显,activity.xxx.js得到类似的结果,都太大了,并且React、jQuery等代码库重复被合并到activity和topic里,如下图。如果再加模块也会得到同样的结果,模块越多重复加载的情况越严重
DSC0003.jpg

  可见,提取公共代码,情况可以得到改善,另外,压缩代码无疑是可以使文件变小的。
  1. 提取React、jQuery等库文件。它们很少变化,并且到处被复用,应该被提取出来,并且得到长时间的缓存。
  此处使用插件:WebPack.optimize.CommonsChunkPlugin(WebPack内建插件)
   DSC0004.jpg
  2. 代码压缩。React由700+ Kb压缩成100+ Kb
  此处使用插件:WebPack.optimize.UglifyJsPlugin (WebPack内建插件)
   DSC0005.jpg
  处理后topic.xxx.js和activity.xxx.js都很小了,并且多了jquery.xxx.js和react.xxx.js
   DSC0006.jpg
  再看看文件加载的瀑布流,柱子所占比例短了,同时资源并行加载。
DSC0007.jpg

  到此为止,这个问题算比较好地解决了,但还不够,随着项目越来越大,还有一个重要因素会导致文件很大。这部分内容放到本文的最后介绍。
  二、如何缓存
  缓存控制要做到两件事情,提到缓存命中率

  •   对于没有修改的文件,从缓存中获取文件
  •   对于已经修改的文件,不要从缓存中获取
  围绕这两点,演绎出了很多方案,此处列两种:

  •   不处理,等待用户浏览器缓存过期,自动更新。这是最偷懒的,命中率低一些,同时可能会出现部分文件没有更新,导致报错的情况。
  •   Http头对文件设置很大的max-age,例如1年。同时,给每个文件命名上带上该文件的版本号,例如把文件的hash值做为版本号,topic. ef8bed6c.js。即是让文件很长时间不过期。


      •   当文件没有更新时,使用缓存的文件自然不会出错;
      •   当文件已经有更新时,其hash值必然改变,此时文件名变了,自然不存在此文件的缓存,于是浏览器会去加载最新的文件。


  从上面的截图可以看出来,通过WebPack是可以很轻松做到第二点的——只需要给文件名配置上[chunkhash:8]即可,其中8是指hash长度为8,默认是16。
DSC0008.jpg

  P.S.这样的处理效果已经很好了,但同样有劣处,即浏览器给这种缓存方式的缓存容量太少了,只有12Mb,且不分Host。所以更极致的做法是以文件名为Key,文件内容为value,缓存在localStorage里,命中则从缓存中取,不命中则去服务器取,虽然缓存容量也只有5Mb,但是每个Host是独享这5Mb的。
  三、自动生成页面
  文件名带上版本号后,每一次文件变化,都需要Html文件里手动修改引用的文件名,这种重复工作很琐碎且容易出错。
DSC0009.jpg

  使用 HtmlWebpackPlugin ExtractTextPlugin 插件可以解决此问题。

  •   生成带JS的页面
  • DSC00010.jpg

  • 生成带css的页面
  new ExtractTextPlugin("comm.[contenthash:9].css")
  插件介绍到此为止,然而,还有一个关于同步加载和异步加载的问题,否则入口文件还是会很臃肿。
肆 | Fourth
  关于同步加载和异步加载
  使用WebPack打包,最爽的事情莫过于可以像服务器编程那样直接require文件,看起来是同步地从服务器上取得文件直接就使用了。如下面的代码一样,没有任何异步逻辑,代码很干净。
DSC00011.jpg

  然而,这种爽是有代价的,对于直接require模块,WebPack的做法是把依赖的文件都打包在一起,造成文件很臃肿。
  所以在写代码的时候要注意适度同步加载,同步的代码会被合成并且打包在一起;异步加载的代码会被分片成一个个chunk,在需要该模块时再加载,即按需加载,这个度是要开发者自己把握的,同步加载过多代码会造成文件过大影响加载速度,异步过多则文件太碎,造成过多的Http请求,同样影响加载速度。

  •   同步加载的写法,如:
  var TopicItem = require('../topic/topicitem');


  •   异步加载的写法,如:
DSC00012.jpg

  一个原则是:首屏需要的同步加载,首屏过后才需要的则按需加载(异步)
  结语
  以上是WebPack构建工具比较好的实践,可见,要用好还是很考验前端性能优化的功力的,比较什么时候同步,什么时候异步,如果做缓存等等。
DSC00013.jpg

  如果觉得文章有用,顺手点击下方的推荐

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-346136-1-1.html 上篇帖子: [.net 面向对象程序设计深入](4)MVC 6 —— 谈谈MVC的版本变迁及新版本6.0发展方向 下篇帖子: 有关npm rum的3个简洁技巧
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表