<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>

          聊一聊我們前端項(xiàng)目組是如何優(yōu)化項(xiàng)目的

          共 12010字,需瀏覽 25分鐘

           ·

          2023-08-28 17:14

          25a28780ab9beb8477157c50caf3ff91.webp

          1. 減小文件體積/網(wǎng)絡(luò)請(qǐng)求
          • 方法一:刪除需要預(yù)先加載和預(yù)先獲取的資源,一般使用這種方法

            link標(biāo)簽中的preloadprefetch

          1. preload插件用于預(yù)加載資源。 即在當(dāng)前頁(yè)面加載完成后,立即加載并緩存指定的資源。預(yù)加載的資源被認(rèn)為是當(dāng)前頁(yè)面所需的關(guān)鍵資源,因此會(huì)優(yōu)先下載和緩存。
          2. prefetch插件用于預(yù)獲取資源。 即在當(dāng)前頁(yè)面加載完成后,異步地加載并緩存指定的資源,以供將來(lái)可能需要的頁(yè)面使用。預(yù)獲取的資源被認(rèn)為是可能會(huì)在未來(lái)的導(dǎo)航中使用的資源,但不是當(dāng)前頁(yè)面所必需的。
          `vue.config.js`

          module.exports = {
            chainWebpack(config) => {
              `刪除需要預(yù)先加載(當(dāng)前頁(yè)面)的資源,當(dāng)需要這些資源的時(shí)候,頁(yè)面會(huì)自動(dòng)加載`
              config.plugins.delete('preload')  
              `刪除需要預(yù)先獲取(將來(lái)的頁(yè)面)的資源`
              config.plugins.delete('prefetch')
            }
          }
          • 方法二:使用webpack合并小文件

            合并js代碼的意義:

          1. 減少網(wǎng)絡(luò)請(qǐng)求: 每個(gè)文件都需要通過(guò)網(wǎng)絡(luò)進(jìn)行單獨(dú)的請(qǐng)求和響應(yīng)。通過(guò)將多個(gè)文件合并為一個(gè)文件,可以減少頁(yè)面需要發(fā)起的網(wǎng)絡(luò)請(qǐng)求次數(shù),從而降低延遲和提高加載速度。
          2. 緩存優(yōu)化: 合并代碼可以提高瀏覽器緩存的效率。當(dāng)多個(gè)頁(yè)面共享同一個(gè)文件時(shí),瀏覽器只需要下載并緩存一次該文件,而不是針對(duì)每個(gè)頁(yè)面都下載一次。這樣可以減少整體的重復(fù)下載和提高緩存命中率。
          3. 減少頁(yè)面渲染阻塞: 當(dāng)瀏覽器下載和執(zhí)行js代碼時(shí),它會(huì)阻塞頁(yè)面的渲染過(guò)程。通過(guò)合并js代碼,可以減少因?yàn)槎鄠€(gè)js文件的下載和執(zhí)行而造成的頁(yè)面渲染阻塞時(shí)間,提高頁(yè)面的響應(yīng)速度和用戶體驗(yàn)。
          4. 代碼優(yōu)化和壓縮: 在合并js代碼之前,可以對(duì)代碼進(jìn)行優(yōu)化和壓縮,去除空格、注釋和不必要的代碼,從而減少文件大小,并提高代碼的執(zhí)行效率。
          `vue.config.js: `

          const webpack = require('webpack')
          const ENV = process.env.NODE_ENV

          module.exports = {
            chainWebpack(config) => {
              config.when(ENV === 'production', config => {
                config.plugin('webpackOptimize')
                .use(
                  webpack.optimize.LimitChunkCountPlugin, 
                  `限制生成的代碼塊(chunks)的數(shù)量`
                  [{ maxChunks10 }]
                )
                .use(
                  webpack.optimize.MinChunkSizePlugin, 
                  `指定代碼塊的最小字節(jié)數(shù)`
                  [{ minChunkSize50000 }]
                )
              })
            }
          }
          • 優(yōu)化效果截圖

          優(yōu)化前的本地環(huán)境:

          844b07b872fd426d9b55ae2d336c563d.webpimage.png

          優(yōu)化后的本地環(huán)境(app.js文件較大,是由于main.js引入了大量的第三方庫(kù)): 3302c91807661735ab0fdf160365463b.webp

          優(yōu)化后的線上環(huán)境(首先,打包后有對(duì)這些文件進(jìn)行壓縮處理,app.js被壓縮至1.24MB"inspect": "vue inspect > output.js",使用npm run inspect可以查看webPack的配置信息。其次,運(yùn)維都有對(duì)這些文件作gzip壓縮處理, 所以體積都減小了很多, 最終app.js的體積減小至405KB): e4cb4781d8616599aba56eea530e8674.webp

          d9bfc297ab2198d76430440bedd40867.webpimage.png

          2. 加減乘除運(yùn)算集成`big.js`[1],解決js小數(shù)精度問(wèn)題

          • 前提:

          當(dāng)涉及到浮點(diǎn)數(shù)計(jì)算時(shí),js中的精度丟失問(wèn)題, 是由于使用IEEE 754標(biāo)準(zhǔn)來(lái)表示和計(jì)算浮點(diǎn)數(shù)的方式引起的。這個(gè)問(wèn)題不僅僅在js中存在,而是在所有使用IEEE 754標(biāo)準(zhǔn)的編程語(yǔ)言中都會(huì)遇到。

          IEEE 754標(biāo)準(zhǔn)定義了兩種常見(jiàn)的浮點(diǎn)數(shù)表示形式:?jiǎn)尉龋?code style="font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;font-size:14px;color:rgb(30,107,184);background-color:rgba(27,31,35,.05);">32位)和雙精度(64位)。在 js中,采用的是雙精度表示法,即64位。

          然而,由于二進(jìn)制和十進(jìn)制之間的轉(zhuǎn)換存在差異,某些十進(jìn)制分?jǐn)?shù)無(wú)法精確表示為有限位的二進(jìn)制浮點(diǎn)數(shù)。這導(dǎo)致了舍入誤差和精度丟失。

          • 安裝依賴: npm install --save big.js
          • 方法封裝:
          import Big from 'big.js'

          export function accFactory(method = 'add'{
            return function (...nums{
              `將傳入的參數(shù)轉(zhuǎn)換為Number類型,并過(guò)濾掉不是Number類型的結(jié)果`
              nums = nums.map(Number).filter((num) => num || num === 0)
              `如果過(guò)濾后的結(jié)果是長(zhǎng)度為1的數(shù)組,那就返回?cái)?shù)組的第一項(xiàng)`
              `如果過(guò)濾后的結(jié)果為空數(shù)組,則返回0`
              if (nums.length < 2return nums[0] || 0
              `需要為reduce方法賦初值,是因?yàn)閎ig.js的運(yùn)算操作,是基于new Big格式的數(shù)字`
              `可以將Big對(duì)象轉(zhuǎn)換為浮點(diǎn)數(shù),方便后續(xù)Number.toFixed()的操作`
              return parseFloat(nums.slice(1).reduce((prev, num) => prev[method](num), new Big(nums[0]))) || 0
            }
          }

          `plus、minus、times、div為big.js中的計(jì)算方法,分別對(duì)應(yīng)加減乘除這四個(gè)運(yùn)算操作`

          `浮點(diǎn)數(shù)求和`
          export const accAdd = accFactory('plus')
          `浮點(diǎn)數(shù)相減`
          export const accSub = accFactory('minus')
          `浮點(diǎn)數(shù)相乘`
          export const accMul = accFactory('times')
          `浮點(diǎn)數(shù)相除`
          export const accDiv = accFactory('div')
          • 測(cè)試:
          import { accAdd, accSub, accMul, accDiv } from '@/utils/calculate'

          mounted() {
            this.calTestHandler()
          },

          methods: {
            calTestHandler() {
              const operations = [
                { operator'+'method: accAdd, a0.1b0.2 },
                { operator'-'method: accSub, a0.1b0.3 },
                { operator'*'method: accMul, a0.1b0.2 },
                { operator'/'method: accDiv, a0.1b0.3 }
              ]
           
              operations.forEach((operation) => {
                const { operator, method, a, b } = operation
                const result = method(a, b)
                console.log(`原生js ${operator} 運(yùn)算:${a} ${operator} ${b}的值是${eval(a + operator + b)}`)
                console.log(`big.js ${operator} 運(yùn)算:${a} ${operator} ${b}的值是${result}`)
              })
            }
          }

          結(jié)果展示:

          03187c3d5935ce0d475f5ef52fb342ed.webpimage.png

          3. 使用`bluebird`[2]提升promise的執(zhí)行速度

          • 前提:

          bluebird是一個(gè)流行的Promise庫(kù),用于處理異步操作。它提供了強(qiáng)大的異步編程工具,使得編寫和管理異步代碼變得更加簡(jiǎn)單和可靠。

          1. Promise功能增強(qiáng): bluebird提供了許多額外的功能和操作,超出了原生Promise的范圍。它支持超時(shí)控制、并發(fā)控制、錯(cuò)誤處理、重試、進(jìn)度報(bào)告和取消等功能。這些功能使得處理復(fù)雜的異步控制流變得更加容易。
          2. 性能優(yōu)化:bluebird在性能方面進(jìn)行了優(yōu)化,比原生Promise更快。 它實(shí)現(xiàn)了高效的異步調(diào)度和內(nèi)存管理,以提供更快的執(zhí)行速度和更低的資源消耗。這使得在大規(guī)模異步操作的情況下,bluebird可以提供更高效的性能。
          3. 錯(cuò)誤追蹤和調(diào)試:bluebird提供了更好的錯(cuò)誤追蹤和調(diào)試支持。 當(dāng)使用bluebird進(jìn)行異步操作時(shí),它會(huì)生成詳細(xì)的錯(cuò)誤堆棧跟蹤信息,包括異步操作鏈的每個(gè)步驟。這使得在調(diào)試和排查錯(cuò)誤時(shí)更容易定位問(wèn)題所在。
          4. 可互操作性:bluebirdapi與原生Promise相似,因此可以與其他使用Promise的庫(kù)和代碼進(jìn)行互操作。 這使得在現(xiàn)有的代碼基礎(chǔ)上,遷移到bluebird更加容易,并且可以充分利用bluebird提供的額外功能。
          • 安裝依賴: npm install --save bluebird
          • 方法封裝(全局掛載):
          import Promise from 'bluebird'

          Promise.config({

            `確定是否啟用警告輸出。當(dāng)設(shè)置為true,bluebird會(huì)在控制臺(tái)輸出警告,例如不推薦使用的方法或潛在問(wèn)題`
            warningsfalse,
            
            `確定是否啟用長(zhǎng)堆棧跟蹤, bluebird會(huì)生成詳細(xì)的異步調(diào)用堆棧信息,包括Promise鏈中的每個(gè)步驟。`
            `這對(duì)于調(diào)試和錯(cuò)誤追蹤非常有用, 但啟用長(zhǎng)堆棧跟蹤,可能會(huì)對(duì)性能產(chǎn)生一些影響`
            longStackTracesfalse,
            
            `確定是否啟用取消功能。當(dāng)設(shè)置為true時(shí),bluebird允許取消異步操作。`
            `取消一個(gè)Promise將導(dǎo)致其相關(guān)的操作被中斷或忽略,有助于優(yōu)化資源使用和控制異步流程。`
            cancellationtrue,
            
            `確定是否啟用性能監(jiān)視。當(dāng)設(shè)置為true時(shí),bluebird可以收集異步操作的性能數(shù)據(jù),例如執(zhí)行時(shí)間、調(diào)用次數(shù)等。`
            `這對(duì)于分析和優(yōu)化異步操作的性能非常有用。`
            monitoringtrue,
            
            `確定是否啟用異步掛鉤。異步掛鉤是node.js提供的一種機(jī)制,可以在異步操作的不同階段執(zhí)行回調(diào)函數(shù)。`
            `當(dāng)設(shè)置為true時(shí),bluebird將使用異步掛鉤來(lái)跟蹤和管理異步操作`
            asyncHooksfalse
          })
          window.bluePromise = Promise
          `main.js`

          import bluebird from '@/utils/bluebird'
          • 測(cè)試
          mounted() {
           this.proTestHandler()
          },

          methods: {
            async proTestHandler() {
              const promises = []
              const bluebirds = []
              
              const promiseList = (promise, count, arr) => {
                for (let i = 0; i < count; i++) {
                  arr.push(new promise((resolve) => resolve(i)))
                }
              }
              
              const generatePromises = () => {
                promiseList(Promise1000000, promises)
                promiseList(bluePromise, 1000000, bluebirds)
              }
              
              generatePromises()
              console.log('promise')
              console.time()
              await Promise.all(promises)
              console.timeEnd()
              console.log('bluebirds')
              console.time()
              await bluePromise.all(bluebirds)
              console.timeEnd()
            }
          }

          結(jié)果展示

          02bdcae7670a1c7e28c2884231a67ef0.webpimage.png

          4. 使用`hashids`[3]加密路由id

          • 前提:

          在網(wǎng)址上應(yīng)用hashids有以下4點(diǎn)重要意義:

          1. 加密隱藏真實(shí)id: 在某些情況下,你可能希望隱藏網(wǎng)址中的真實(shí)id,以增加安全性和防止直接暴露敏感信息。使用hashids,可以將真實(shí)的數(shù)字id轉(zhuǎn)換為短字符串,并在網(wǎng)址中使用該短字符串代替原始id。這樣,外部用戶只能看到短字符串,而無(wú)法直接推斷出真實(shí)的id值。
          2. 可讀性和美觀性: 長(zhǎng)的數(shù)字id在網(wǎng)址中可能顯得冗長(zhǎng)和難以理解。使用hashids將其轉(zhuǎn)換為短字符串,可以大大提升網(wǎng)址的可讀性和美觀性。短字符串通常包含字母和數(shù)字的組合,更易于記憶和分享。
          3. 防止猜測(cè)和遍歷: 使用連續(xù)的數(shù)字id在網(wǎng)址中可能導(dǎo)致猜測(cè)和遍歷的風(fēng)險(xiǎn),因?yàn)楣粽呖梢酝ㄟ^(guò)遞增id來(lái)嘗試訪問(wèn)和暴露數(shù)據(jù)。通過(guò)使用hashids生成的短字符串作為id,可以有效地防止這種攻擊。由于短字符串是隨機(jī)生成的,攻擊者無(wú)法根據(jù)短字符串推斷出下一個(gè)id
          4. URL縮短和分享: hashids生成的短字符串可以用作url縮短服務(wù)的替代方案。你可以將長(zhǎng)的url轉(zhuǎn)換為短字符串,并在分享時(shí)使用該短字符串。這對(duì)于限制字符數(shù)、簡(jiǎn)化鏈接以及在社交媒體和短信中共享鏈接都非常有用。
          • 安裝依賴: npm install --save hashids
          • 方法封裝(全局掛載):
          `短碼方法封裝:`

          import Hashids from 'hashids'

          const hashids = new Hashids(

            `鹽值是一個(gè)可選的字符串參數(shù),用于增加生成的短碼的唯一性和安全性。每個(gè)不同的鹽值將產(chǎn)生不同的短碼序列,`
            `可以將鹽值視為項(xiàng)目的名稱或標(biāo)識(shí)符。如果不提供鹽值,則默認(rèn)為一個(gè)空字符串。`
            
            'toadditWeb'
            
            `是一個(gè)可選的整數(shù)參數(shù),用于指定生成的短碼的最小長(zhǎng)度。如果生成的短碼長(zhǎng)度小于指定的最小長(zhǎng)度,`
            `hashids會(huì)自動(dòng)填充短碼以達(dá)到最小長(zhǎng)度。這只是一個(gè)最小長(zhǎng)度的限制,實(shí)際生成的短碼長(zhǎng)度可能更長(zhǎng)。`
            `如果不提供最小長(zhǎng)度,則默認(rèn)為0,即沒(méi)有最小長(zhǎng)度限制。`
            8
            
            `字母表是一個(gè)可選的字符串參數(shù),用于定義生成短碼時(shí)使用的字符集。該字符串包含所有可用于生成短碼的字符。` 
            `通常,字母表中應(yīng)包含一組不容易混淆的字符,以避免生成的短碼產(chǎn)生歧義。如果不提供字母表,則默認(rèn)為`
            `"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"`
          )

          `短碼封裝`
          export function encode(val{
            return hashids.encode(val)
          }

          `短碼解析`
          export function decode(val{
            return hashids.decode(val)[0]
          }
          `glboal.js: 全局注冊(cè)`

          import { encode, decode } from '@/utils/hashids'

          export default {
            install(Vue) {
              Vue.prototype.$encode = window.$encode = (data) => encode(data)
              Vue.prototype.$decode = window.$decode = (data) => decode(data)
            }
          }
          `在main.js中掛載:`

          import Vue from 'vue'
          import App from './App'
          import globalConst from '@/commons/globalConst'

          Vue.use(globalConst)

          new Vue({
            el'#app',
            router,
            store,
            render(h) => h(App)
          })
          • 測(cè)試:

          mounted() {
            this.hashTestHandler()
          },

          methods: {
            hashTestHandler() {
              const testId = 18
              const encode = $encode(testId)
              console.log(`hashids編碼前: ${testId}`)
              console.log(`hashids編碼: ${encode}`)
              console.log(`hashids解碼: ${$decode(encode)}`)
            }
          }

          結(jié)果展示(在同一個(gè)鹽值下,不管頁(yè)面是否刷新,編碼結(jié)果都不會(huì)改變):

          050a73f10a5fc38a2f2d038011df4467.webpimage.png

          5. 登陸時(shí)使用`行為驗(yàn)證碼`[4]

          • 前提:

          登陸時(shí)使用行為驗(yàn)證碼有以下5點(diǎn)重要意義:

          1. 增強(qiáng)安全性: 傳統(tǒng)的驗(yàn)證碼可以被自動(dòng)化的機(jī)器人或惡意程序輕易地破解或繞過(guò)。而行為驗(yàn)證碼通過(guò)分析用戶的行為模式,可以更準(zhǔn)確地識(shí)別是否是真實(shí)用戶,從而提高安全性,防止惡意活動(dòng)和機(jī)器人攻擊。
          2. 用戶友好性: 相比于傳統(tǒng)的驗(yàn)證碼,行為驗(yàn)證碼通常對(duì)用戶來(lái)說(shuō)更加友好和便捷。用戶無(wú)需輸入復(fù)雜的文本或解析模糊的圖像,而是通過(guò)正常的交互行為完成驗(yàn)證,例如簡(jiǎn)單的滑動(dòng)、點(diǎn)擊、拖拽等操作。
          3. 無(wú)感知驗(yàn)證: 行為驗(yàn)證碼可以在用戶進(jìn)行正常的操作過(guò)程中進(jìn)行驗(yàn)證,幾乎無(wú)需用戶額外的干預(yù)或注意。這樣可以減少對(duì)用戶的干擾和阻礙,提升用戶體驗(yàn)。
          4. 自適應(yīng)性: 行為驗(yàn)證碼可以根據(jù)用戶的行為模式自適應(yīng)地進(jìn)行驗(yàn)證。它可以根據(jù)用戶的設(shè)備、IP地址、瀏覽器指紋、鼠標(biāo)移動(dòng)軌跡等因素來(lái)綜合評(píng)估用戶的真實(shí)性,從而提高準(zhǔn)確性和安全性。
          5. 防止數(shù)據(jù)濫用: 行為驗(yàn)證碼可以用于防止惡意用戶或攻擊者濫用系統(tǒng)或服務(wù)。通過(guò)分析用戶的行為模式和交互方式,可以及時(shí)識(shí)別和阻止異常行為,保護(hù)系統(tǒng)和數(shù)據(jù)的安全。
          前端參考文檔:https://github.com/Yunlingfly/vue-captcha/tree/master

          最終效果:

          7743dfa0833606d8a02cedf13fa71710.webpimage.png

          作者:沐浴在曙光下的貳貨道士 

          鏈接:https://juejin.cn/post/7264440609129119804 

          來(lái)源:稀土掘金 

          粉絲福利

          分享一個(gè)現(xiàn)代感十足的博客源碼(Headless blog),當(dāng)下流行的無(wú)頭博客方案,這個(gè)源碼使用了React、GatsbyJS v5 技術(shù),并擁有九個(gè)不同類型的博客風(fēng)格。此博客不僅支持本地Markdown文件,還支持Contentful CMS、Strapi CMS、Netlify CMS和Sanity CMS等內(nèi)容管理系統(tǒng),讓你能夠自由創(chuàng)作博客文章,喜歡的趕緊收下吧。


          瀏覽 62
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  亚洲无 码A片在线 | 福利在线观看中文字幕 | 可以免费看的黄色片 | 久久青青操| 影音先锋全部av鲁色资源站小说 |