<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前端開發中,隨著業務和頁面增加,以元件為基本單位的結構下,元件數量會增長極快,為了優化我們會很顯然地想要進行一些工作:
非必要資源,指的首次渲染出某頁面所不必要的資源,如因為使用者操作才出現的圖片、彈窗等。
程式碼分塊和懶載入在頁面層面具有極大的優化作用,使用者很可能只是瀏覽dashboard頁面,可能根本就不會去看詳情等頁面,那我們就不必將詳情頁面的程式碼和dashboard頁面程式碼混在一起,使用者看某個頁面時只載入那個頁面對應的資源即可,可以較大地提升使用者體驗。本文就在Vue工程下如何在元件層面設定程式碼分塊和懶載入進行講解。
本文在@vue/cli 3以上版本。
一般來說,Vue中使用某元件過程大致如下:
<script> // Home.vue import HelloWorld from '@/components/HelloWorld.vue' export default { components: { HelloWorld, }, } </script>
這是我們最熟悉的方式了,我們在存取Home.vue時,Webpack為我們保證了HelloWorld.vue一定是存在的,這是由依賴關係決定的(Home.vue依賴於HelloWorld.vue)。
這很正常對吧,但是如果HelloWorld.vue是非必要資源呢,比如需要使用者點選一個按鈕才會出現的彈窗或者是預設隱藏的內容,只當某些條件觸發時才出現的頁面區域呢?如果是上述情況,當我們存取Home.vue時顯然沒必要馬上就將HelloWorld.vue請求過來,而且設定方法也及其簡單:
<template> <div class="home"> <button @click="() => showHello = true">Hello</button> <HelloWorld v-if="showHello" /> </div> </template>
<script> // Home.vue export default { components: { HelloWorld: () => import('@/components/HelloWorld.vue'), // A }, data() { return { showHello: false, } }, } </script>
只需像A行一樣簡單處理一下即可一舉兩得:HelloWorld.vue會被打包成獨立為單獨的js檔案,而且只有當我們點選按鈕時,這個獨立的js檔案才會被請求,這樣能夠減小主程式碼塊的體積。
簡單分析一下:import()會返回一個元件Promise,現在基本上所有的打包工具都理解此語法,而且還會觸發Webpack的程式碼分塊(Webpack 2之後)。
注意:Vue不會在意某個元件,直到它要被渲染出來。以上例來說,只有當我們觸發了按鈕,HelloWorld.vue才有了意義。
即使所有元件都可以設定懶載入,但是別濫用,大部分情況下只對非必要資源設定懶載入即可,像上例如果HelloWorld.vue是Home.vue中是一直存在的,那樣設定懶載入可能會適得其反,載入了Home.vue對應的js檔案後會馬上請求HelloWorld.vue對應的js檔案,如果HelloWorld.vue對應的js檔案比較小,那得到的收益可能不足以抵消一次http請求帶來的消耗。
元件懶載入雖然好處極多,但仍有缺陷,如上例點選按鈕後需等待HelloWorld.vue對應的js檔案被請求執行後頁面才會做出相應變化,這就涉及到載入狀態和錯誤狀態的處理(雖然一般情況下不會有問題,因為都是些小檔案,載入極快,但也有例外),所幸Vue也為我們考慮到了這些:
<script> // Home.vue import LoadingComponent from '@/components/Loading' export default { components: { HelloWorld: () => ({ component: import('@/components/HelloWorld.vue'), loading: LoadingComponent, // 載入HelloWorld.vue對應js檔案中展示 delay: 300, // loading的延遲生效時間 }), }, data() { return { showHello: false, } }, } </script>
從使用者體驗方面來說,般來說500ms內的響應時間還不至於失去使用者的注意力,所以可以為loading設定一個延遲時間,預設200ms內載入完成不會出現loading,當然也可以像上面一樣手動設定一下delay,單位ms。
<script> // Home.vue import ErrorComponent from '@/components/Error' export default { components: { HelloWorld: () => ({ component: import('@/components/HelloWorld.vue'), error: ErrorComponent, // 載入HelloWorld.vue對應js檔案失敗時展示,如檔案不存在 timeout: 2000, // 檔案載入的超時時間,超出時間未載入完成,會觸發ErrorComponent }), }, data() { return { showHello: false, } }, } </script>
出現錯誤的情形主要有以下幾點:
Vue還為資原始檔設定了預載入策略,即使用<link rel="prefetch">和<link rel="preload">策略,在build後的index.html檔案中或者開發模式下瀏覽器的Network面板裡可以具體檢視。關於兩者的具體用法這裡就不贅述了,這裡說一下兩者差異之處:preload的優先順序比prefetch的高,一般來說當前頁面的必要資源可以使用preload策略,當前頁面的非必要資源和其他頁面的資源使用prefetch策略。
通過設定資源預載入,瀏覽器為我們預先預先載入資源,在使用者用到某些資源時可以及時響應,可以在提升首次載入效能的同時為使用者後續的操作提供良好的體驗。
prefetch在Safari中暫時還不支援,所以懶載入在Safari中表現地相對較差。
Vue中使用懶載入和程式碼分塊對產品進行優化,簡單實用,但是這其中存在著權衡,如果專案較小,打包檔案並不大,則可能不需要進行程式碼分塊和懶載入,畢竟http請求也是挺貴的。
當專案較大時,使用懶載入和程式碼分塊就可以顯著地提升效能,但是同樣注意那需要由後來的請求彌補的,但所幸目前大部分瀏覽器都支援資源預載入策略,搭配使用效果更佳。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45