摘要:感受構(gòu)建工具給前端優(yōu)化工作帶來的便利。多多益處邏輯清晰,程序注重?cái)?shù)據(jù)與表現(xiàn)分離,可讀性強(qiáng),利于規(guī)避和排查問題構(gòu)建工具層出不窮。其實(shí)工具都能滿足需求,關(guān)鍵是看怎么用,工具的使用背后是對前端性能優(yōu)化的理解程度。
這篇主要介紹一下我在玩Webpack過程中的心得。通過實(shí)例介紹WebPack的安裝,插件使用及加載策略。感受構(gòu)建工具給前端優(yōu)化工作帶來的便利。
曾幾何時(shí)我們的JS是這樣引入頁面的
曾幾何時(shí),我們是如上圖的方式引入JS資源的,相信現(xiàn)在很少遇見了。近年來Web前端開發(fā)領(lǐng)域朝著規(guī)范開發(fā)的方向演進(jìn)。體現(xiàn)在以下兩點(diǎn):
MVC研發(fā)構(gòu)架。多多益處(邏輯清晰,程序注重?cái)?shù)據(jù)與表現(xiàn)分離,可讀性強(qiáng),利于規(guī)避和排查問題...)
構(gòu)建工具層出不窮。多多益處(提升團(tuán)隊(duì)協(xié)作,以及工程運(yùn)維,避免人工處理瑣碎而重復(fù)的工作)
模塊化開發(fā)
將前端性能優(yōu)化理論落地,代碼壓縮,合并,緩存控制,提取公共代碼等
其他的還包括比如你可以用ES 6 或CoffeeScript寫源碼,然后構(gòu)建出瀏覽器支持的ES5
所以,前端這么好玩,如果還有項(xiàng)目沒有前后端分離的話,真的是守舊過頭了。
主流構(gòu)建工具市面上有許多構(gòu)建工具,包括Grunt、Gulp、browserify等,這些和WebPack都是打包工具。但WebPack同時(shí)也具備以下特點(diǎn):
相比Grunt,WebPack除了具備豐富的插件外,同時(shí)帶有一套加載(Loader)系統(tǒng)。使它支持多種規(guī)范的加載方式,包括ES6、CommonJS、AMD等方式,這是Grunt、Gulp所不具備的。
從代碼混淆的角度來看,WebPack更加的極致
代碼分片為處理單元(而不是文件),使得文件的分片更為靈活。
P.S.此處只做簡單的比較,不論孰優(yōu)孰劣。其實(shí)工具都能滿足需求,關(guān)鍵是看怎么用,工具的使用背后是對前端性能優(yōu)化的理解程度。
WebPack安裝與使用WebPack運(yùn)行在 NodeJS之下,并且它及其插件都是使用NPM(NodeJS的包管理工具)管理。
安裝Node及NPM。到NodeJS官網(wǎng)安裝包,安裝即可
全局安裝WebPack。聯(lián)網(wǎng)情況下,執(zhí)行命令行 $npm install webpack -g 即可
此至即可使用WebPack了,到WebPack官網(wǎng)去按著Get start(http://webpack.github.io/docs/tutorials/getting-started/)的步驟來,感受一個(gè)最簡單的構(gòu)建過程。
然而要把WebPack用好,只是跑起來是遠(yuǎn)遠(yuǎn)不夠的。
WebPack插件花較大篇幅介紹插件的使用,以下通過在一個(gè)DemoApp的構(gòu)建過程中思考的一些問題(這些問題基本會在每個(gè)項(xiàng)目中遇到),讓這些插件逐一登場。
一、文件過大DemoApp最初的構(gòu)建結(jié)果如下:
這里生成了一個(gè)topic.xxx.js,這個(gè)文件本來很小,估計(jì)只有10Kb左右,但構(gòu)建的結(jié)果居然快1Mb了。在3G網(wǎng)絡(luò)(750Kb/s)下的加載瀑布流如下圖:
這張圖(體現(xiàn)前端文件加載過程)曝露了幾個(gè)問題:
上面箭頭所指的很藍(lán)色柱子,說明了大部分時(shí)間消耗在加載topic.xxxx.js上。
所有JS文件相關(guān)的柱子是一根結(jié)束了另一根才開始,說明不合理的文件合并策略,導(dǎo)致文件串行加載。
結(jié)果就是如底部的箭頭所看到的,頁面的加載時(shí)間太長了(3G網(wǎng)絡(luò),10+秒)。
觀察構(gòu)建的文件,發(fā)現(xiàn)原來構(gòu)建工具把React、jQuery等代碼庫合并到了topic.xxxx.js,造成此文件過大。如果再加一個(gè)activity模塊呢?很明顯,activity.xxx.js得到類似的結(jié)果,都太大了,并且React、jQuery等代碼庫重復(fù)被合并到activity和topic里,如下圖。如果再加模塊也會得到同樣的結(jié)果,模塊越多重復(fù)加載的情況越嚴(yán)重。
可見,提取公共代碼,情況可以得到改善,另外,壓縮代碼無疑是可以使文件變小的。
提取React、jQuery等庫文件。它們很少變化,并且到處被復(fù)用,應(yīng)該被提取出來,并且得到長時(shí)間的緩存。此處使用插件:WebPack.optimize.CommonsChunkPlugin(WebPack內(nèi)建插件)
代碼壓縮。React由700+ Kb壓縮成100+ Kb。此處使用插件:WebPack.optimize.UglifyJsPlugin (WebPack內(nèi)建插件)
處理后topic.xxx.js和activity.xxx.js都很小了,并且多了jquery.xxx.js和react.xxx.js
再看看文件加載的瀑布流,柱子所占比例短了,同時(shí)資源并行加載。
到此為止,這個(gè)問題算比較好地解決了,但還不夠,隨著項(xiàng)目越來越大,還有一個(gè)重要因素會導(dǎo)致文件很大。這部分內(nèi)容放到本文的最后介紹。
二、如何緩存緩存控制要做到兩件事情,提到緩存命中率
對于沒有修改的文件,從緩存中獲取文件
對于已經(jīng)修改的文件,不要從緩存中獲取
圍繞這兩點(diǎn),演繹出了很多方案,此處列兩種:
不處理,等待用戶瀏覽器緩存過期,自動更新。這是最偷懶的,命中率低一些,同時(shí)可能會出現(xiàn)部分文件沒有更新,導(dǎo)致報(bào)錯(cuò)的情況。
Http頭對文件設(shè)置很大的max-age,例如1年。同時(shí),給每個(gè)文件命名上帶上該文件的版本號,例如把文件的hash值做為版本號,topic. ef8bed6c.js。即是讓文件很長時(shí)間不過期。
當(dāng)文件沒有更新時(shí),使用緩存的文件自然不會出錯(cuò);
當(dāng)文件已經(jīng)有更新時(shí),其hash值必然改變,此時(shí)文件名變了,自然不存在此文件的緩存,于是瀏覽器會去加載最新的文件。
從上面的截圖可以看出來,通過WebPack是可以很輕松做到第二點(diǎn)的——只需要給文件名配置上[chunkhash:8]即可,其中8是指hash長度為8,默認(rèn)是16。
P.S.這樣的處理效果已經(jīng)很好了,但同樣有劣處,即瀏覽器給這種緩存方式的緩存容量太少了,只有12Mb,且不分Host。所以更極致的做法是以文件名為Key,文件內(nèi)容為value,緩存在localStorage里,命中則從緩存中取,不命中則去服務(wù)器取,雖然緩存容量也只有5Mb,但是每個(gè)Host是獨(dú)享這5Mb的。
三、自動生成頁面文件名帶上版本號后,每一次文件變化,都需要Html文件里手動修改引用的文件名,這種重復(fù)工作很瑣碎且容易出錯(cuò)。
使用 HtmlWebpackPlugin 和 ExtractTextPlugin 插件可以解決此問題。
生成帶JS的頁面
生成帶css的頁面
使用WebPack打包,最爽的事情莫過于可以像服務(wù)器編程那樣直接require文件,看起來是同步地從服務(wù)器上取得文件直接就使用了。如下面的代碼一樣,沒有任何異步邏輯,代碼很干凈。
而,這種爽是有代價(jià)的,對于直接require模塊,WebPack的做法是把依賴的文件都打包在一起,造成文件很臃腫。
所以在寫代碼的時(shí)候要注意適度同步加載,同步的代碼會被合成并且打包在一起;異步加載的代碼會被分片成一個(gè)個(gè)chunk,在需要該模塊時(shí)再加載,即按需加載,這個(gè)度是要開發(fā)者自己把握的,同步加載過多代碼會造成文件過大影響加載速度,異步過多則文件太碎,造成過多的Http請求,同樣影響加載速度。
同步加載的寫法,如:
var TopicItem = require("../topic/topicitem");
異步加載的寫法,如:
一個(gè)原則是:首屏需要的同步加載,首屏過后才需要的則按需加載(異步)
結(jié)語以上是WebPack構(gòu)建工具比較好的實(shí)踐,可見,要用好還是很考驗(yàn)前端性能優(yōu)化的功力的,比較什么時(shí)候同步,什么時(shí)候異步,如果做緩存等等。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/78853.html
摘要:前端每周清單半年盤點(diǎn)之與篇前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。與求同存異近日,宣布將的構(gòu)建工具由遷移到,引發(fā)了很多開發(fā)者的討論。 前端每周清單半年盤點(diǎn)之 React 與 ReactNative 篇 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為...
摘要:發(fā)布是由團(tuán)隊(duì)開源的,操作接口庫,已成為事實(shí)上的瀏覽器操作標(biāo)準(zhǔn)。本周正式發(fā)布,為我們帶來了,,支持自定義頭部與腳部,支持增強(qiáng),兼容原生協(xié)議等特性變化。新特性介紹日前發(fā)布了大版本更新,引入了一系列的新特性與提升,本文即是對這些變化進(jìn)行深入解讀。 showImg(https://segmentfault.com/img/remote/1460000012940044); 前端每周清單專注前端...
摘要:延伸閱讀學(xué)習(xí)與實(shí)踐資料索引與前端工程化實(shí)踐前端每周清單半年盤點(diǎn)之篇前端每周清單半年盤點(diǎn)之與篇前端每周清單半年盤點(diǎn)之篇 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(ID:frontshow),及時(shí)獲取前端每周清單;本文則是對于半年來發(fā)布的前端每周清單...
摘要:感謝王下邀月熊分享的前端每周清單,為方便大家閱讀,特整理一份索引。王下邀月熊大大也于年月日整理了自己的前端每周清單系列,并以年月為單位進(jìn)行分類,具體內(nèi)容看這里前端每周清單年度總結(jié)與盤點(diǎn)。 感謝 王下邀月熊_Chevalier 分享的前端每周清單,為方便大家閱讀,特整理一份索引。 王下邀月熊大大也于 2018 年 3 月 31 日整理了自己的前端每周清單系列,并以年/月為單位進(jìn)行分類,具...
閱讀 1406·2021-11-08 13:14
閱讀 760·2021-09-23 11:31
閱讀 1051·2021-07-29 13:48
閱讀 2789·2019-08-29 12:29
閱讀 3384·2019-08-29 11:24
閱讀 1910·2019-08-26 12:02
閱讀 3703·2019-08-26 10:34
閱讀 3447·2019-08-23 17:07