<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          vue編碼之優(yōu)化手段

          共 5418字,需瀏覽 11分鐘

           ·

          2021-06-06 12:16



          前端獵手
           鏈接每一位開發(fā)者,讓編程更有趣兒!
          關(guān)注

          性能優(yōu)化本身就是一個很大的話題,并且它沒有一個定式,最好是在具體的項目中具體分析,而不是說看到一個優(yōu)化技巧一定要用在項目當(dāng)中,這篇文章主要聊聊在vue編碼階段有哪些常見的優(yōu)化手段。

          ?? 使用 key

          關(guān)于key在這篇 請闡述vue的diff算法文章有說到,key值在對比新舊虛擬節(jié)點時可以辨識虛擬節(jié)點,在更新子節(jié)點的時候,需要將舊虛擬節(jié)點列表與新虛擬節(jié)點相同的節(jié)點進行更新。如果在對比過程中設(shè)置了key值,那么對比的速度就會快很多。對于通過循環(huán)生成的列表,應(yīng)該給每個列表項添加一個穩(wěn)定且唯一的key,這樣有利于在列表發(fā)生變化時,盡量少刪除、新增、改動元素。

          ?? 使用凍結(jié)對象

          什么是凍結(jié)對象?凍結(jié)對象其實就是通過Object.freeze(傳一個對象)將對象凍結(jié),凍結(jié)之后,這個對象的屬性就不能修改添加了,是不可變的,當(dāng)然數(shù)組也能凍結(jié),凍結(jié)后什么操作都不行,增刪改就不要想了,由于凍結(jié)對象后不可變,vue會對凍結(jié)對象進行優(yōu)化處理,vue不會將凍結(jié)的對象處理成響應(yīng)式。我們在實際項目開發(fā)中可能會處理不會改變的數(shù)據(jù),它只需要渲染到頁面上就行了,所以這些數(shù)據(jù)是沒必要變成響應(yīng)式的,這時使用凍結(jié)對象可以減少vue將對象變成響應(yīng)式過程這個時間。

          當(dāng)然它也有一個弊端,就是將來想修改對象中的數(shù)據(jù),由于不是響應(yīng)式的,所以也不會渲染在頁面上。

          ? 使用計算屬性

          如果模板中某個數(shù)據(jù)會使用多次,并且該數(shù)據(jù)是通過計算得到的,盡量使用計算屬性,我們都知道計算屬性是有緩存的,計算屬性函數(shù)依賴的數(shù)據(jù)在沒有發(fā)生變化的情況下,會反復(fù)讀取緩存數(shù)據(jù),而計算屬性函數(shù)并不會反復(fù)執(zhí)行,但也有缺陷,就是不能傳參數(shù)。

          ?? 非實時綁定的表單項

          當(dāng)使用v-model綁定一個表單項時,當(dāng)用戶改變表單項的狀態(tài)時,也會隨之改變數(shù)據(jù),從而導(dǎo)致vue發(fā)生重新渲染(rerender),這會帶來一些性能的開銷。

          特別是當(dāng)用戶改變表單項時,頁面有一些動畫正在進行中,由于JS執(zhí)行線程和瀏覽器渲染線程是互斥的,最終會導(dǎo)致動畫出現(xiàn)卡頓。

          我們可以通過使用lazy或不使用v-model的方式解決問題,但要注意,這樣可能導(dǎo)致在某個時間段內(nèi)數(shù)據(jù)和表單項的值不一致。

          一個簡單例子: 插入一個任務(wù)到列表中

          GIF 2021-5-27 9-37-34.gif

          當(dāng)我們直接使用v-model進行雙向綁定,先不加lazy修飾符,然后將transition過渡時間調(diào)整為5s


          <template>
            <div id="app">
              <input
                type="text"
                placeholder="今天的任務(wù)完成了嗎?"
                v-model="message"
                @change="addContent"
              />

              <button @click="shuffle">隨機排序</button>
              <transition-group name="nums" tag="ul" class="box">
                <li v-for="(item, i) in likeList" :key="item" class="task">
                  <span>{{ item }}</span>
                  <button @click="deleteContent(i)">完成</button>
                </li>
              </transition-group>
            </div>

          </template>

          <script>
          export default {
            data() {
              return {
                likeList: ["寫代碼", "看書", "吃飯", "追女孩子"],
                message: "",
              };
            },
            methods: {
              deleteContent(i) {
                this.likeList.splice(i, 1);
              },
              shuffle() {
                this.likeList.sort(() => Math.random() - 0.5);
              },
              addContent() {
                if (this.likeList.includes(this.message.replace(/
          \s+/g, ""))) {
                  alert("當(dāng)前任務(wù)已存在,請重新輸入!");
                  this.message = "";
                  return;
                }
                this.likeList.unshift(this.message.replace(/
          \s+/g, ""));
                this.message = "";
              },
            },
          };
          </
          script>

          <style>
          #app {
            width500px;
            margin0 auto;
          }
          * {
            list-style: none;
          }
          input {
            width600px;
            height40px;
            font-size24px;
            border: none;
            outline: none;
            border-style: solid;
            border-color#ddd;
            background: paleturquoise;
            margin-bottom15px;
            text-indent1em;
          }
          .box {
            width500px;
            padding0 20px;
            margin-bottom200px;
          }
          .task {
            width100%;
            height50px;
            line-height50px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            border-bottom1px solid #ddd;
          }
          .task button {
            width70px;
            height30px;
          }
          .nums-enter {
            opacity0;
            transformtranslateX(-300px);
          }
          .nums-enter-active,
          .nums-leave-active,
          .nums-move {
            /* 修改這里的時間即可 */
            transition5s;
          }
          .nums-leave-to {
            opacity0;
            transformtranslateX(300px);
          }
          .nums-leave-active {
            position: absolute;
          }
          </style>


          效果如下:

          我們可以很明顯看到當(dāng)添加一項內(nèi)容的時候,不停的輸入內(nèi)容會導(dǎo)致頁面渲染變慢

          GIF 2021-5-27 9-4245646-14.gif

          然后給v-model加上lazy修飾符再看看,是不是跟不加有很大區(qū)別??

          GIF 2021-5-27 9-48-21.gif

          ?? 使用v-show替代v-if

          對于頻繁切換顯示狀態(tài)的元素,使用v-show可以保證虛擬dom樹的穩(wěn)定,避免頻繁的新增和刪除元素,尤其是當(dāng)內(nèi)部包含大量的dom元素的節(jié)點。

          ?? 使用延遲裝載(defer)

          使用延遲裝載主要解決白屏問題,首頁白屏?xí)r間主要受兩個因素的影響:

          • 打包體積過大

            包的體積過大需要消耗大量的傳輸時間,導(dǎo)致Js傳輸完成前頁面只有一個<div>,沒有可以顯示的內(nèi)容。

          • 需要立即渲染的內(nèi)容過多

            JS傳輸完成后,瀏覽器開始執(zhí)行JS構(gòu)造頁面。但是可能一開始要渲染的組件太多了,不僅會導(dǎo)致Js執(zhí)行時間很長,而且執(zhí)行完后瀏覽器要渲染的元素過多,從而導(dǎo)致白屏

          打包體積過大需要自行優(yōu)化打包體積,這里就不說了,主要聊聊渲染內(nèi)容過多的問題。

          一個可行的辦法就是延遲裝載組件,讓組件按照指定的先后順序依次一個一個渲染出來。

          延遲裝載是一個思路,本質(zhì)上就是利用requestAnimationFrame 事件分批渲染內(nèi)容,它的具體實現(xiàn)多種多樣。

          ?? keep-alive組件

          關(guān)于keep-alive 可以看看這篇文章:請闡述keep-alive組件的作用和原

          ?? 使用長列表優(yōu)化

          關(guān)于長列表優(yōu)化 可以看看這篇文章:vue編碼之長列表優(yōu)化

          ?? 好了, 以上就是我的分享,歡迎大家在評論區(qū)討論鴨~

          希望小伙伴們點贊 ?? 支持一下哦~ ??,我會更有動力的 ??

          瀏覽 37
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久黄色免费视频 | 日韩3级| A片黄色电影网站 | 操屄视频网 | www.69自拍 |