一定要避免全文件模塊引入责循、全局引入嗎糟港?實(shí)驗(yàn)告訴你答案

前言

我們?cè)谑褂媚_手架工具的時(shí)候一定是離不開webpack,但是很多人對(duì)于是不是一定要避免全局引入院仿、全模塊引入還很模糊,今天我做一系列實(shí)驗(yàn)來測(cè)試一下速和。

全文件模塊引入VS文件內(nèi)部分模塊按需引入

全文件模塊引入也就是:

import abc from '@/modules/abc.js'
abc.a()

文件內(nèi)部分模塊按需引入也就是:

import {a} from '@/modules/abc.js'
a()

我們搭建一個(gè)vue-cli 4歹垫,注意關(guān)掉eslint。然后測(cè)試這兩種寫法帶來的dist文件大小差距颠放。先說上面代碼的對(duì)比排惨,導(dǎo)致的大小差距應(yīng)該就是大約4個(gè)字節(jié)的差別,差別不明顯碰凶,我們的abc.js要寫的大一點(diǎn)暮芭,比如:

全文件模塊引入的abc.js:

export default {
  a() {
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
  },
  b() {
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
  },
  c() {
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
  },
}

文件內(nèi)部分模塊按需引入的abc.js:

  export function a() {
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
    console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
  }
  export function b() {
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
    console.log('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
  }
  export function c() {
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
    console.log('ccccccccccccccccccccccccccccccccccccccccccccc')
  }

再分別寫上對(duì)應(yīng)的import寫法,然后yarn build欲低,之后查看js文件夾三個(gè)js文件的大小之和:

全文件模塊引入:151,657 字節(jié)
文件內(nèi)部分模塊按需引入:150,402 字節(jié)

相差1200多字節(jié)辕宏!那么我們?cè)偎阉芽矗葱枰氲膉s文件里面有沒有一連串的a字符呢砾莱?答案是有瑞筐,然后再試試搜一連串的bc字符呢?答案是搜不到腊瑟。

結(jié)論一:按需引入聚假,真的可以減小dist體積块蚌。

第二個(gè)問題:按需引入前提下,export之外的代碼膘格,會(huì)被打包嗎峭范?

在abc.js頂部加上const x = 'xxxxxxxxxxxxxxx',然后在a模塊console.log(x)瘪贱。yarn build之后纱控,搜索dist的js,搜一連串x政敢,結(jié)果能搜到其徙。

然后,把a(bǔ)模塊的console.log(x)挪到b模塊喷户,重新build唾那。搜索dist的js,搜一連串x褪尝,結(jié)果搜不到闹获。

結(jié)論二:webpack會(huì)判斷export之外的代碼是否需要引入,需要的話河哑,也會(huì)打包避诽。不需要就不打包。

有人說璃谨,我在export之外敲一個(gè)console.log('yyyyyyyyyyyyyy')沙庐,結(jié)果被打包了,怎么解釋佳吞?

很好解釋啊拱雏,這行代碼,以webpack的智慧底扳,不可能判斷出它是對(duì)項(xiàng)目有用的還是沒用的铸抑,所以只好給打包上了。而且衷模,在export之外寫跟模塊無關(guān)的代碼鹊汛,是不是腦抽?

結(jié)論三:export之外的代碼阱冶,凡是webpack無法判斷有沒有用的刁憋,它會(huì)按照有用來處理。請(qǐng)不要寫與模塊無關(guān)的代碼熙揍,也不要為難webpack职祷,錯(cuò)在你,不在于webpack。

有人問有梆,一個(gè)vue文件使用了a模塊是尖,另一個(gè)vue文件使用了b和c模塊,按需引入還有意義嗎泥耀?

繼續(xù)做實(shí)驗(yàn)饺汹。

全文件引入寫法,dist的js文件之和是151,752 字節(jié)
按需引入寫法痰催,dist的js文件之和是151,860 字節(jié)

相差108個(gè)字節(jié)兜辞。差距應(yīng)該是體現(xiàn)在了按需引入方案webpack打包之后的一些邊邊角角的引入語句上,畢竟拆開引入要重復(fù)寫若干遍引入語句夸溶。

結(jié)論四:文件的所有模塊都用得到的前提下逸吵,還是全文件引入的寫法節(jié)省字節(jié)(盡管節(jié)省的很有限),而且缝裁,全文件寫法還有一個(gè)更大的優(yōu)點(diǎn)就是扫皱,它的執(zhí)行是abc.a(),而按需引入是a()捷绑,無疑韩脑,abc.a()會(huì)讓你知道a方法是從哪來的,書寫更為清晰粹污。

結(jié)論五:開發(fā)者自己編的模塊段多,要分成兩類:
1、針對(duì)服務(wù)全局的模塊壮吩;
2进苍、針對(duì)服務(wù)某個(gè)頁面或組件的模塊。
對(duì)于針對(duì)服務(wù)全局的模塊鸭叙,應(yīng)當(dāng)按需引入琅捏,理由在本文后半部分有討論。
對(duì)于針對(duì)服務(wù)某個(gè)頁面或組件的模塊递雀,應(yīng)在頁面或組件里全文件引入,這樣思路更簡單蚀浆,代碼清晰度更高缀程。
同理,對(duì)于開源組件庫的引入市俊,如果你能確定所有組件全用得到(這一點(diǎn)很難做到杨凑,比如一個(gè)組件庫提供50個(gè)組件,你敢說你50個(gè)你會(huì)全用遍摆昧?)撩满,就一定要全文件引入,否則,還是按需引入的好伺帘。

本文附贈(zèng)一個(gè)實(shí)驗(yàn)昭躺,拿Vant組件庫的幾種引入方法,做實(shí)驗(yàn)測(cè)試一下伪嫁。

現(xiàn)在打開Vant的官網(wǎng)看它的手冊(cè)领炫,它介紹了幾種引入方法,我們一一測(cè)試张咳。

Vant兩種引入模式測(cè)試

yarn add vant安裝是沒啥說的帝洪。

方式一. 自動(dòng)按需引入組件(Vant官方推薦)

官方要求安裝babel-plugin-import,由于它只作為dev依賴脚猾,不影響打包體積葱峡,所以咱們放心裝上:yarn add babel-plugin-import --dev。然后在babel.config.js中配置龙助,也不多說砰奕。然后使用import { Button } from 'vant';來引用組件即可,并不需要Vue.use(Button);泌参。

然后我們?cè)贖ome.vue寫一個(gè)button脆淹。

<van-button type="default">這是個(gè)按鈕</van-button>
import {Button} from 'vant'
  components: {
    VanButton: Button
  }

dist得到146,791字節(jié)。

方式二沽一、手動(dòng)按需引入組件

去babel.config.js刪除掉配置盖溺,改用方式二,也就是引入方式有區(qū)別铣缠。

import Button from 'vant/lib/button';
import 'vant/lib/button/style';

dist得到150,926字節(jié)烘嘱。

結(jié)論六:Vant官方推薦的引入方式確實(shí)能節(jié)省體積。

到此蝗蛙,全文件引入和按需引入的對(duì)比就結(jié)束了蝇庭,然后我們實(shí)驗(yàn)一下某個(gè)組件全局引入和局部引入的區(qū)別。

單一組件全局引入VS局部引入

拿Vant的Icon組件做一個(gè)測(cè)試捡硅。

局部引入

首先我們?cè)?個(gè).vue文件內(nèi)局部引入Icon組件哮内。

<van-icon name="close" /><van-icon name="chat" info="99+" />
import {Icon} from 'vant';
  components: {
    VanIcon: Icon
  }

dist得到144,325字節(jié)。

全局引入

main.js:

const globalComponents = {
  install: () => {
    Vue.component('VanIcon', Icon)
  }
}
Vue.use(globalComponents)

組件內(nèi)去掉import和components變量壮韭。

dist得到144,332 字節(jié)北发。

相比之下,兩種方式相差7字節(jié)喷屋,局部引入方式體積小琳拨。但是!因?yàn)槿忠雽懥艘粋€(gè)install方法占了100多字節(jié)屯曹,而局部引入多寫的那些代碼加起來也沒有90字節(jié)狱庇。所以結(jié)論是:

結(jié)論七:全局引入節(jié)省字節(jié)惊畏,其實(shí)這很好理解,一次引入密任,全局使用颜启,當(dāng)然省字節(jié)。而且項(xiàng)目越大批什,全局引入就越節(jié)省字節(jié)农曲。

其實(shí),這兩種方式對(duì)于代碼量的差別已經(jīng)是次要矛盾驻债,因?yàn)閮煞N引入方式打包進(jìn)來的組件體積是差不多的乳规,并不是說局部多次引入就會(huì)多次打包,這個(gè)常識(shí)我就不做實(shí)驗(yàn)了合呐。主要矛盾集中在內(nèi)存占用和js文件按需加載方面暮的。

全局引入的優(yōu)勢(shì):

  1. 一次引入,全局使用淌实,無需任何局部引入的語句冻辩。

局部引入的優(yōu)勢(shì):

  1. 最大優(yōu)勢(shì)就是拆分js文件帶來的優(yōu)勢(shì),也就是說拆祈,一些組件只在某些.vue里使用恨闪,結(jié)合webpack的路由懶加載,那么這些Vant組件所在的js文件將會(huì)在即將被使用的時(shí)候才會(huì)網(wǎng)絡(luò)請(qǐng)求它放坏,這樣會(huì)提高首屏打開速度咙咽。

  2. 默認(rèn)不加載一些Vant組件,也會(huì)降低JS的內(nèi)存占用淤年。

這時(shí)候結(jié)論差不多可以總結(jié)一下了:

結(jié)論八:如果一個(gè)Vant組件在80%的頁面都會(huì)用到钧敞,尤其是首頁會(huì)用到,比如一個(gè)移動(dòng)項(xiàng)目麸粮,NavBar溉苛、Icon和Button在95%的頁面都有用到,那么一定要全局引入它弄诲。如果一個(gè)Vant組件在20%或更少的頁面用到愚战,比如Uploader組件,應(yīng)當(dāng)局部引入它齐遵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凤巨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子洛搀,更是在濱河造成了極大的恐慌,老刑警劉巖佑淀,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件留美,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谎砾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門逢倍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人景图,你說我怎么就攤上這事较雕。” “怎么了挚币?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵亮蒋,是天一觀的道長。 經(jīng)常有香客問我妆毕,道長慎玖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任笛粘,我火速辦了婚禮趁怔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘薪前。我一直安慰自己润努,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布示括。 她就那樣靜靜地躺著铺浇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪例诀。 梳的紋絲不亂的頭發(fā)上随抠,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音繁涂,去河邊找鬼拱她。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扔罪,可吹牛的內(nèi)容都是我干的秉沼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼矿酵,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼唬复!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起全肮,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤敞咧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后辜腺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體休建,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乍恐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了测砂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茵烈。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砌些,靈堂內(nèi)的尸體忽然破棺而出呜投,到底是詐尸還是另有隱情,我是刑警寧澤存璃,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布仑荐,位于F島的核電站,受9級(jí)特大地震影響有巧,放射性物質(zhì)發(fā)生泄漏释漆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一篮迎、第九天 我趴在偏房一處隱蔽的房頂上張望男图。 院中可真熱鬧,春花似錦甜橱、人聲如沸逊笆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽难裆。三九已至,卻和暖如春镊掖,著一層夾襖步出監(jiān)牢的瞬間乃戈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工亩进, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留症虑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓归薛,卻偏偏與公主長得像谍憔,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子主籍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容