1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        聊一聊我們前端組一起處理的項(xiàng)目優(yōu)化點(diǎn)

        共 12679字,需瀏覽 26分鐘

         ·

        2023-09-25 14:21

        前言

        很早一段時(shí)間,我們前端組做了一些國外系統(tǒng)的小優(yōu)化(集中表現(xiàn)在代碼執(zhí)行速度,系統(tǒng)安全等方面),故新建一篇文章來記錄這次優(yōu)化的經(jīng)歷。如果本文對您有幫助,煩請大家一鍵三連哦, 蟹蟹大家~

        1. 減小文件體積/網(wǎng)絡(luò)請求

        • 方法一:刪除需要預(yù)先加載和預(yù)先獲取的資源,一般使用這種方法

          link標(biāo)簽中的preloadprefetch

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

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

          合并js代碼的意義:

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

        image.png

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

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

        image.png

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

        • 前提:

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

        IEEE 754標(biāo)準(zhǔn)定義了兩種常見的浮點(diǎn)數(shù)表示形式:單精度(32位)和雙精度(64位)。在 js中,采用的是雙精度表示法,即64位。

        然而,由于二進(jìn)制和十進(jìn)制之間的轉(zhuǎn)換存在差異,某些十進(jìn)制分?jǐn)?shù)無法精確表示為有限位的二進(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類型,并過濾掉不是Number類型的結(jié)果`
            nums = nums.map(Number).filter((num) => num || num === 0)
            `如果過濾后的結(jié)果是長度為1的數(shù)組,那就返回?cái)?shù)組的第一項(xiàng)`
            `如果過濾后的結(jié)果為空數(shù)組,則返回0`
            if (nums.length < 2return nums[0] || 0
            `需要為reduce方法賦初值,是因?yàn)閎ig.js的運(yùn)算操作,是基于new Big格式的數(shù)字`
            `可以將Big對象轉(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ì)算方法,分別對應(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')
        • 測試:
        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} $的值是${eval(a + operator + b)}`)
              console.log(`big.js ${operator} 運(yùn)算:${a} ${operator} $的值是${result}`)
            })
          }
        }

        結(jié)果展示:

        image.png

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

        • 前提:

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

        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í),它會生成詳細(xì)的錯(cuò)誤堆棧跟蹤信息,包括異步操作鏈的每個(gè)步驟。這使得在調(diào)試和排查錯(cuò)誤時(shí)更容易定位問題所在。
        4. 可互操作性:bluebirdapi與原生Promise相似,因此可以與其他使用Promise的庫和代碼進(jìn)行互操作。 這使得在現(xiàn)有的代碼基礎(chǔ)上,遷移到bluebird更加容易,并且可以充分利用bluebird提供的額外功能。
        • 安裝依賴: npm install --save bluebird
        • 方法封裝(全局掛載):
        import Promise from 'bluebird'

        Promise.config({

          `確定是否啟用警告輸出。當(dāng)設(shè)置為true,bluebird會在控制臺輸出警告,例如不推薦使用的方法或潛在問題`
          warningsfalse,
          
          `確定是否啟用長堆棧跟蹤, bluebird會生成詳細(xì)的異步調(diào)用堆棧信息,包括Promise鏈中的每個(gè)步驟。`
          `這對于調(diào)試和錯(cuò)誤追蹤非常有用, 但啟用長堆棧跟蹤,可能會對性能產(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ù)等。`
          `這對于分析和優(yōu)化異步操作的性能非常有用。`
          monitoringtrue,
          
          `確定是否啟用異步掛鉤。異步掛鉤是node.js提供的一種機(jī)制,可以在異步操作的不同階段執(zhí)行回調(diào)函數(shù)。`
          `當(dāng)設(shè)置為true時(shí),bluebird將使用異步掛鉤來跟蹤和管理異步操作`
          asyncHooksfalse
        })
        window.bluePromise = Promise
        `main.js`

        import bluebird from '@/utils/bluebird'
        • 測試
        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é)果展示

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

        import Hashids from 'hashids'

        const hashids = new Hashids(

          `鹽值是一個(gè)可選的字符串參數(shù),用于增加生成的短碼的唯一性和安全性。每個(gè)不同的鹽值將產(chǎn)生不同的短碼序列,`
          `可以將鹽值視為項(xiàng)目的名稱或標(biāo)識符。如果不提供鹽值,則默認(rèn)為一個(gè)空字符串。`
          
          'toadditWeb'
          
          `是一個(gè)可選的整數(shù)參數(shù),用于指定生成的短碼的最小長度。如果生成的短碼長度小于指定的最小長度,`
          `hashids會自動填充短碼以達(dá)到最小長度。這只是一個(gè)最小長度的限制,實(shí)際生成的短碼長度可能更長。`
          `如果不提供最小長度,則默認(rèn)為0,即沒有最小長度限制。`
          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: 全局注冊`

        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)
        })
        • 測試:

        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è)鹽值下,不管頁面是否刷新,編碼結(jié)果都不會改變):

        image.png

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

        • 前提:

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

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

        最終效果:

        image.png

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

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

        來源:稀土掘金

        瀏覽 257
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            99在线国内精品自产拍 | 亚洲逼逼逼 | 日本内射精品一区二区视频 | hp高h喷水荡肉爽文np动漫 | 亂倫視頻85頁 | 爽好大快深点黄瓜视频动漫 | 扒开老师湿漉漉的黑森林 | 性,国产三级在线观看 | 污视频网站在线 | 伦理《禁忌11》 |