• <em id="6vhwh"><rt id="6vhwh"></rt></em>

    <style id="6vhwh"></style>

    <style id="6vhwh"></style>
    1. <style id="6vhwh"></style>
        <sub id="6vhwh"><p id="6vhwh"></p></sub>
        <p id="6vhwh"></p>
          1. 国产亚洲欧洲av综合一区二区三区 ,色爱综合另类图片av,亚洲av免费成人在线,久久热在线视频精品视频,成在人线av无码免费,国产精品一区二区久久毛片,亚洲精品成人片在线观看精品字幕 ,久久亚洲精品成人av秋霞

            popsloader(popsloader v4g)

            更新時間:2023-03-02 10:19:04 閱讀: 評論:0

            渲染優(yōu)化

            渲染優(yōu)化是前端優(yōu)化中一個很重要的部分,一個好的首屏?xí)r間能給用戶帶來很好的體驗,這里要說的一點是關(guān)于首屏?xí)r間的定義,不同的團(tuán)隊對首屏?xí)r間定義不一樣,有的團(tuán)隊認(rèn)為首屏?xí)r間就是白屏?xí)r間,是從頁面加載到第一個畫面出現(xiàn)的時間。但是當(dāng)我們說到用戶體驗的時候,僅僅是這樣還達(dá)不到效果,所以有的前端團(tuán)隊認(rèn)為,首屏?xí)r間應(yīng)該是從頁面加載到用戶可以進(jìn)行正常的頁面操作時間,那么我們就依照后者來進(jìn)行說明

            js css 加載順序

            說渲染優(yōu)化之前,我們還需要說一個小插曲,就是比較經(jīng)典的一道問題"瀏覽器地址欄輸入url發(fā)生了什么",理解了這個我們才可以更清楚js,css加載順序?qū)︿秩镜挠绊?/p>問題 1:地址欄輸入url 發(fā)生了什么

            這個問題經(jīng)常被人提起,有人回答比較簡潔點,有人可能回答的比較詳細(xì),下面就說一下主要流程

            首先會進(jìn)行 url 解析,根據(jù) dns 系統(tǒng)進(jìn)行 ip 查找根據(jù) ip 就可以找到服務(wù)器,然后瀏覽器和服務(wù)器會進(jìn)行 TCP 三次握手建立連接,如果此時是 https 的話,還會建立 TLS 連接以及協(xié)商加密算法,這里就會出現(xiàn)另一個需要注意的問題"https 和 http 的區(qū)別"(下文會講到)連接建立之后瀏覽器開始發(fā)送請求獲取文件,此時這里還會出現(xiàn)一種情況就是緩存,建立連接后是走緩存還是直接重新獲取,需要看后臺設(shè)置,所以這里會有一個關(guān)注的問題"瀏覽器緩存機(jī)制",緩存我們等會在講,現(xiàn)在我們就當(dāng)沒有緩存,直接去獲取文件首先獲取 html 文件,構(gòu)建 DOM 樹,這個過程是邊下載邊解析,并不是等 html 文件全部下載完了,再去解析 html,這樣比較浪費時間,而是下載一點解析一點好了解析到 html 頭部時候,又會出現(xiàn)一種問題,css,js 放到哪里了?不同的位置會造成渲染的不同,此時就會出現(xiàn)另一個需要關(guān)注的問題"css,js 位置應(yīng)該放哪里?為什么",我們先按照正確的位置來說明(css 放頭部,js 放尾部)解析到了 html 頭部發(fā)現(xiàn)有 css 文件,此時下載 css 文件,css 文件也是一邊下載一邊解析的,構(gòu)建的是 CSSOM 樹,當(dāng) DOM 樹和 CSSOM 樹全部構(gòu)建完之后,瀏覽器會把 DOM 樹和 CSSOM 樹構(gòu)建成渲染樹。樣式計算, 上面最后一句"DOM 樹和 CSSOM 樹會一起構(gòu)建成渲染樹"說的有點籠統(tǒng),其實還有更細(xì)一點的操作,但是一般回答到上面應(yīng)該就可以了,我們現(xiàn)在接上面說一下構(gòu)造渲染樹的時候還做了哪些事情。第一個就是樣式計算,DOM樹 和 CSSOM樹有了之后,瀏覽器開始樣式計算,主要是為 DOM 樹上的節(jié)點找到對應(yīng)的樣式構(gòu)建布局樹,樣式計算完之后就開始構(gòu)建布局樹。主要是為 DOM 樹上的節(jié)點找到頁面上對應(yīng)位置以及一些"display:none"元素的隱藏。構(gòu)建分層樹,布局樹完成后瀏覽器還需要建立分層樹,主要是為了滿足滾動條,z-index,position 這些復(fù)雜的分層操作將分層樹圖塊化,利用光柵找到視圖窗口下的對應(yīng)的位圖。主要是因為一個頁面可能有幾屏那么長,一下渲染出來比較浪費,所以瀏覽器會找到視圖窗口對應(yīng)的圖塊,將這部分的圖塊進(jìn)行渲染最終渲染進(jìn)程將整個頁面渲染出來,在渲染的過程中會還出現(xiàn)重排和重繪,這也是比較愛問的問題"重排重繪為什么會影響渲染,如何避免?"以上過程大概講解了一下從 url 到頁面渲染的整個過程,其實涉及到了幾個需要關(guān)注的問題,下面來具體講講問題 2:js css 順序?qū)η岸藘?yōu)化影響

            上面我們說到了整個渲染流程,但是沒有說到 css 和 js 對渲染的影響。渲染樹的構(gòu)成必須要 DOM 樹和 CSSOM 樹的,所以盡快的構(gòu)建 CSSOM 樹是一個重要的優(yōu)化手段,如果 css 文件放在尾部,那么整個過程就是一個串行的過程先解析了 dom,再去解析 css。所以 css 我們一般都是放在頭部,這樣 DOM 樹和 CSSOM 樹的構(gòu)建是同步進(jìn)行的。

            再來看 js,因為 js 的運行會阻止 DOM 樹的渲染的,所以一旦我們的 js 放在了頭部,而且也沒有異步加載這些操作的話,js 一旦一直在運行,DOM 樹就一直構(gòu)建不出來,那么頁面就會一直出現(xiàn)白屏界面,所以一般我們會把 js 文件放在尾部。當(dāng)然放到尾部也不是就沒有問題了,只是問題相對較小,放到尾部的 js 文件如果過大,運行時間長,代碼加載時,就會有大量耗時的操作造成頁面不可點擊,這就是另一個問題,但這肯定比白屏要好,白屏是什么頁面都沒有,這種是頁面有了只是操作不流暢。

            js 腳本放在尾部還有一個原因,有時候 js 代碼會有操作 dom 節(jié)點的情況,如果放在頭部執(zhí)行,DOM樹還沒有構(gòu)建,拿不到 DOM 節(jié)點但是你又去使用就會出現(xiàn)報錯情況,錯誤沒處理好的話頁面會直接崩掉

            問題 3:重排重繪為什么會影響渲染,如何避免?

            重排和重繪為什么會影響渲染,哪個影響更大,如何避免是經(jīng)常被問到的一道題目,我們先來說一下重繪

            重繪重繪指的是不影響界面布局的操作,比如更改顏色,那么根據(jù)上面的渲染講解我們知道,重繪之后我們只需要在重復(fù)進(jìn)行一下樣式計算,就可以直接渲染了,對瀏覽器渲染的影響相對較小重排重排指的是影響界面布局的操作,比如改變寬高,隱藏節(jié)點等。對于重排就不是一個重新計算樣式那么簡單了,因為改變了布局,根據(jù)上面的渲染流程來看涉及到的階段有樣式計算,布局樹重新生成,分層樹重新生成,所以重排對瀏覽器的渲染影響是比較高的避免方法js 盡量減少對樣式的操作,能用 css 完成的就用 css對 dom 操作盡量少,能用 createDocumentFragment 的地方盡量用如果必須要用 js 操作樣式,能合并盡量合并不要分多次操作resize 事件 最好加上防抖,能盡量少觸發(fā)就少觸發(fā)加載圖片的時候,提前寫好寬高問題 4:瀏覽器緩存機(jī)制

            瀏覽器緩存是比較常見的問題,我會從瀏覽器緩存的方式,緩存的實現(xiàn), 緩存在哪里這幾個點來說明

            緩存方式

            我們經(jīng)常說的瀏覽器緩存有兩種,一種是強(qiáng)制緩存,一種是協(xié)商緩存,因為下面有具體實現(xiàn)講解,所以這里就說一下概念

            協(xié)商緩存協(xié)商緩存意思是文件已經(jīng)被緩存了,但是否從緩存中讀取是需要和服務(wù)器進(jìn)行協(xié)商,具體如何協(xié)商要看請求頭/響應(yīng)頭的字段設(shè)置,下面會說到。需要注意的是協(xié)商緩存還是發(fā)了請求的強(qiáng)制緩存強(qiáng)制緩存就是文件直接從緩存中獲取,不需要發(fā)送請求緩存實現(xiàn)強(qiáng)制緩存

            強(qiáng)制緩存在 http1.0 的時候用的是 Expires,是響應(yīng)頭里面的一個字段表示的是文件過期時間。是一個絕對時間,正因為是絕對時間所以在某些情況下,服務(wù)器的時區(qū)和瀏覽器時區(qū)不一致的時候就會導(dǎo)致緩存失效。為了解決這個問題,HTPP1.1 引入了一個新的響應(yīng)頭 cache-control 它的可選值如下

            cache-controlmax-age: 緩存過期時間,是一個相對時間public: 表示客戶端和代理服務(wù)器都會緩存private: 表示只在客戶端緩存no-cache: 協(xié)商緩存標(biāo)識符,表示文件會被緩存但是需要和服務(wù)器協(xié)商no-store: 表示文件不會被緩存

            HTTP1.1 利用的就是 max-age:600 來強(qiáng)制緩存,因為是相對時間,所以不會出現(xiàn) Expires 問題

            協(xié)商緩存協(xié)商緩存是利用 Last-Modified/if-Modified-Since,Etag/if-None-Match 這兩對請求、響應(yīng)頭。Last-Modified/if-Modified-SinceEtag/If-None-Match由于 Last-Modified 的時間粒度是秒,有的文件在 1s 內(nèi)可能被改動多次。這種方式在這種特殊情況下還是會失效,所以HTTP1.1又引入了 Etag 字段。這個字段是根據(jù)文件內(nèi)容生成一個標(biāo)記符比如"W/"5f9583bd-10a8"",然后再和 If-None-Match 進(jìn)行對比就能更準(zhǔn)確的知道文件有沒有被改動過瀏覽器第一次發(fā)送請求獲取文件緩存下來,服務(wù)器響應(yīng)頭返回一個 if-Modified-Since,記錄被改動的時間瀏覽器第二次發(fā)送請求的時候會帶上一個 Last-Modified 請求頭,時間就是 if-Modified-Since 返回的值。然后服務(wù)器拿到這個字段和自己內(nèi)部設(shè)置的時間進(jìn)行對比,時間相同表示沒有修改,就直接返回 304 從緩存里面獲取文件緩存在哪里

            知道了緩存方式和實現(xiàn),再來說一下緩存存在哪個地方,我們打開掘金可以看到如下的信息 。緩存的來源有兩個地方 from dist cache,from memeory cache

            form memory cache

            這個是緩存在內(nèi)存里面,優(yōu)點是快速,但是具有時效性,當(dāng)關(guān)閉 tab 時候緩存就會失效。

            from dist cache

            這個是緩存在磁盤里面,雖然慢但是還是比請求快,優(yōu)點是緩存可以一直被保留,即使關(guān)閉 tab 頁,也會一直存在

            何時緩存在memory,合適緩存在dist?

            這個問題網(wǎng)上很少找的到標(biāo)準(zhǔn)答案,大家一致的說法是js,圖片文件瀏覽器會自動保存在memory中,css文件因為不常修改保存在dist里面,我們可以打開掘金網(wǎng)站,很大一部分文件都是按照這個規(guī)則來的,但是也有少數(shù)js文件也是緩存在dist里面。所以他的存放機(jī)制到底是什么樣了?我?guī)е@個疑問查了好多文章,雖然最后沒有確切找到答案,但是一個知乎的回答可以給我們提供思路,下面引用一個知乎回答者一段話

            第一個現(xiàn)象(以圖片為例):訪問-> 200 -> 退出瀏覽器再進(jìn)來-> 200(from disk cache) -> 刷新 -> 200(from memory cache)??偨Y(jié): 會不會是chrome很聰明的判斷既然已經(jīng)從disk拿來了, 第二次就內(nèi)存拿吧 快。(笑哭)第二個現(xiàn)象(以圖片為例):只要圖片是ba64 我看都是from memroy cache??偨Y(jié): 解析渲染圖片這么費勁的事情,還是做一次然后放到內(nèi)存吧。用的時候直接拿第三個現(xiàn)象(以js css為例):個人在做靜態(tài)測試的發(fā)現(xiàn),大型的js css文件都是直接disk cache。結(jié): chrome會不會說 我去 你這么大太占地方了。你就去硬盤里呆著吧。慢就慢點吧。第四個現(xiàn)象:隱私模式下,幾乎都是 from memroy cache。總結(jié): 隱私模式 是吧。我不能暴露你東西,還是放到內(nèi)存吧。你關(guān),我死。

            上面幾點是雖然很幽默,但是卻可以從中找到一部分答案,但是我覺得另一個知乎回答我更贊同

            瀏覽器運行的時候也是由幾個進(jìn)程協(xié)作的,所以操作系統(tǒng)為了節(jié)省內(nèi)存,會把一部分內(nèi)存里的資源交換回磁盤的交換區(qū),當(dāng)然交換是有策略的,比如最常用的就是LRU。

            什么時候存dist,什么時候存memoey都是在瀏覽器控制下的,memory不夠了可能就會考慮去存dist了,所以經(jīng)過上面所說我自己總結(jié)結(jié)果如下

            大一點的文件會緩存在dist里面,因為內(nèi)存也是有限的,磁盤的空間更大小一點文件js,圖片存的是memorycss文件一般存在dist特殊情況memory大小是有限制的,瀏覽器也會根據(jù)自己的內(nèi)置算法,把一部分js文件存到dist里面問題 5:https 和 http 的區(qū)別

            說到https和http的區(qū)別,可以說一下https服務(wù)器和客戶端連接的差異,以及https特定的加密算法協(xié)商,甚至可能還要說到對稱加密,非對稱加密和證書等,篇幅很長,請看我之前單獨寫的一篇https詳解,里面講的非常詳細(xì)。

            請求優(yōu)化

            講請求優(yōu)化的之前先來總結(jié)下上面說到的js, css文件順序優(yōu)化,為了讓渲染更快,我們需要把js放到尾部,css放到頭部,然后還要注意在書寫js的時候盡量減少重排,重繪。書寫html,css的時候盡量簡潔,不要冗余,目的是為了更快的構(gòu)建DOM樹和CSSOM樹。好了下面我們在來說說請求優(yōu)化,請求優(yōu)化可以從請求數(shù)量和請求時間兩方面入手

            減少請求數(shù)量將小圖片打包成ba64利用雪碧圖融合多個小圖片利用緩存上面已經(jīng)說到過減少請求時間將js,css,html等文件能壓縮的盡量壓縮,減少文件大小,加快下載速度利用webpack打包根據(jù)路由進(jìn)行懶加載,不要初始就加載全部,那樣文件會很大能升級到高版本的http就升級到高版本(這個回答是套話),為什么高版本能提高速度具體看上面我說的那篇https文章建立內(nèi)部CDN能更快速的獲取文件webpack優(yōu)化

            介紹了渲染優(yōu)化,現(xiàn)在來看看webpack優(yōu)化,自己平常寫demo給團(tuán)隊做培訓(xùn)的時候都是自己手寫webpack配置,雖然也就幾十行,但每次都能讓我鞏固webpack的基本配置,下面直接說一下webpack優(yōu)化手段有哪些

            基礎(chǔ)配置優(yōu)化extensions 這個配置是屬于resolve里面的,經(jīng)常用來對文件后綴進(jìn)行擴(kuò)展,寫法如下

            resolve:{extensions:['.ts','.tsx','.js']}

            這個配置表示webpack會根據(jù)extensions去尋找文件后綴名,所以如果我們的項目主要用ts寫的話,那我們就可以.tsx和.ts寫前面,目的是為了讓webpack能夠快速解析

            alias 這個配置也是屬于resolve里面的,是用來映射路徑,能減少打包時間的主要原因是能夠讓webpack快速的解析文件路徑,找到對應(yīng)的文件,配置如下

            resolve:{alias:{Components:path.resolve(__dirname,'./src/components')}}noPar

            noPar表示不需要解析的文件,有的文件可能是來自第三方的文件,被 providePlugin引入作為windows上的變量來使用,這樣的文件相對比較大,并且已經(jīng)是被打包過的,所以把這種文件排除在外是很有必要的,配置如下

            module:{noPar:[/proj4.js/]}exclude

            某些loader會有這樣一個屬性,目的是指定loader作用的范圍,exclude表示排除某些文件不需要babel-loader處理,loader的作用范圍小了,打包速度自然就快了,用babel-loader舉一個簡單例子

            {test:/.js$/,loader:"babel-loader",exclude:path.resolve(__dirname,'node_modules')}devtool

            這個配置是一個調(diào)試項,不同的配置展示效果不一樣,打包大小和打包速度也不一樣,比如開發(fā)環(huán)境下cheap-source-map肯定比source-map快,至于為什么,強(qiáng)烈推薦自己之前寫的這一篇講解devtool的文章:webpack devtools篇講的非常詳細(xì)。

            {devtool:'cheap-source-map'}

            .eslintignore

            這個雖不是webpack配置但是對打包速度優(yōu)化還是很有用的,在我的實踐中eslint檢查對打包的速度影響很大,但是很多情況我們不能沒有這個eslint檢查,eslint檢查如果僅僅在vs里面開啟的話,可能不怎么保險。

            因為有可能你vs中的eslint插件突然關(guān)閉了或者某些原因vs不能檢查了,只能靠webpack構(gòu)建去幫你攔住錯誤代碼的提交,即使這樣還不能確保萬無一失,因為你可能某一次提交代碼很急沒有啟動服務(wù),直接盲改提交上去了。這個時候只能通過最后一道屏障給你保護(hù),就是在CI的時候。比如我們也會是在jenkins構(gòu)建的時候幫你進(jìn)行eslint檢查,三道屏障確保了我們最終出的鏡像是不會有問題的。

            所以eslint是很重要的,不能刪掉,在不能刪掉的情況下怎么讓檢查的時間更少了,我們就可以通過忽略文件,讓不必要的文件禁止eslint,只對需要的文件eslint可以很大程度提高打包速度

            loader,plugins優(yōu)化

            上述說了幾個基礎(chǔ)配置優(yōu)化,應(yīng)該還有其他的基礎(chǔ)配置,今后遇到了再繼續(xù)添加,現(xiàn)在在來講講利用某些loader,plugins來提高打包速度的例子

            cache-loader

            這個loader就是在第一次打包的時候會緩存打包的結(jié)果,在第二次打包的時候就會直接讀取緩存的內(nèi)容,從而提高打包效率。但是也需要合理利用,我們要記住一點你加的每一個loader,plugins都會帶來額外的打包時間。這個額外時間比他帶來的減少時間多,那么一味的增加這個loader就沒意義,所以cache-loader最好用在耗時比較大的loader上,配置如下

            {rules:[{test:/.vue$/,u:['cache-loader','vue-loader'],include:path.resolve(__dirname,'./src')}]}webpack-parallel-uglify-plugin, uglifyjs-webpack-plugin, terr-webpack-plugin

            在上面的渲染優(yōu)化中我們已經(jīng)知道,文件越小渲染的速度是越快的。所以我們在配置webpack時候經(jīng)常會用到壓縮,但是壓縮也是需要消耗時間的,所以我們我們經(jīng)常會用到上面三個插件之一來開啟并行壓縮,減少壓縮時間,我們用webpack4推薦使用的ter-webpack-plugin做例子來說明

            optimization:{minimizer:[newTerrPlugin({parallel:true,cache:true})],}happypack, parallel-webpack, thread-loader

            這幾個loader/plugin和上面一樣也是開啟并行的,只不過是開啟并行構(gòu)建。由于happypack的作者說自己的興趣已經(jīng)不再js上了,所以已經(jīng)沒有維護(hù)了,并推薦如果使用的是webpack4的話,就去使用thread-loader。基本配置如下

            {test:/.js$/,u:[{loader:"thread-loader",options:threadLoaderOptions},"babel-loader",],exclude:/node_modules/,}DllPlugin,webpack.DllReferencePlugin

            上面說的幾個并行插件理論上是可以增加構(gòu)建速度,網(wǎng)上很多文章都是這么說的,但是我在實際的過程中使用,發(fā)現(xiàn)有時候不僅沒提升反而還降低了打包速度,網(wǎng)速查閱給的理由是可能你的電腦核數(shù)本來就低,或者當(dāng)時你CPU運行已經(jīng)很高了,再去開啟多進(jìn)程導(dǎo)致構(gòu)建速度降低。

            上面說的幾個并行插件可能在某些情況下達(dá)不到你想要的效果,然而在我們團(tuán)隊優(yōu)化webpack性能經(jīng)驗來看,這次所說的兩個插件是很明顯并且每次都能提高打包速度的。原理就是先把第三方依賴先打包一次生成一個js文件,然后真正打包項目代碼時候,會根據(jù)映射文件直接從打包出來的js文件獲取所需要的對象,而不用再去打包第三方文件。只不過這種情況打包配置稍微麻煩點,需要寫一個webpack.dll.js。大致如下

            webpack.dll.js

            constpath=require('path');constwebpack=require('webpack');module.exports={entry:{library:["vue","moment"]},output:{filename:'[name].dll.js',path:path.resolve(__dirname,'json-dll'),library:'[name]'},plugins:[newwebpack.DllPlugin({path:'./json-dll/library.json',name:'[name].json'})]}

            webpack.dev.js

            newAddAstHtmlWebpack({filepath:path.resolve(__dirname,'./json-dll/library.dll.js')}),newwebpack.DllReferencePlugin({manifest:require("./json-dll/library.json")})其他優(yōu)化配置

            這些插件就簡單的介紹下,在我的個人項目中已經(jīng)使用過,自我感覺還可以,具體使用可以查閱npm或者github

            webpack-bundle-analyzer

            這個插件可以用可視化幫我們分析打包體積,從而來采用合適的優(yōu)化方式去改進(jìn)我們的webpack配置

            speed-measure-webpack-plugin

            這個插件可以告訴我們打包時候每一個loader或者plugin花費了多少時間,從而對耗時比較長的plugin和loader做優(yōu)化

            friendly-errors-webpack-plugin

            這個插件可以幫我們優(yōu)化打包日志,我們打包時候經(jīng)常看到很長一個日志信息,有的時候是不需要的,也不會去看所以可以用這個插件來簡化

            代碼優(yōu)化

            這是最后一部分代碼優(yōu)化了,這里的代碼性能優(yōu)化我只說我在工作中感受到的,至于其他的比較小的優(yōu)化點比如createDocumentFragment使用可以查查其他文章

            能不操作dom不要操作dom,哪怕有時候需要改設(shè)計

            很多情況下我們都能用css還原設(shè)計稿,但是有些時候單單從css沒法還原,尤其組件還不是你寫的時候,比如我們團(tuán)隊用的就是antd,有時候的產(chǎn)品設(shè)計單從css上沒法實現(xiàn),只能動用js,刪除,增加節(jié)點在配合樣式才能完成。

            由于我們又是一個做大數(shù)據(jù)的公司,這個時候就會出現(xiàn)性能問題,最開始寫代碼時候,產(chǎn)品說什么就是什么,說什么我都會想辦法搞出來,不管用什么方法。后來到客戶現(xiàn)場大數(shù)據(jù)情況下,性能缺點立馬暴露的出來。

            所以代碼優(yōu)化的原則之一我認(rèn)為是能不寫的代碼就不寫,當(dāng)然這是要從性能角度出發(fā),通過性能分析給產(chǎn)品說出理由,并且最好還能提供更好的解決方案,這個才是我們需要考慮的。

            如果用的是react 一定用寫shouldComponentUpdate這個生命周期函數(shù),不然打印的時候你會發(fā)現(xiàn),你自己都迷糊為什么執(zhí)行了這么多遍

            將復(fù)雜的比對,變成簡單比對

            這句話是什么意思了?我們就拿shouldComponentUpdate舉例子,用這個函數(shù)沒問題,但是可以做得更好,我們在工作中經(jīng)常這么寫

            shouldComponentUpdate(nextPrpops){returnJSON.stringify(nextPrpops.data)!==JSON.stringify(this.props.data)}

            如果這是一個分頁表格,data是每一頁數(shù)據(jù),數(shù)據(jù)改變了重新渲染,在小數(shù)據(jù)場景下這本身是沒有問題。但是如果在大數(shù)據(jù)的場景下可能會有問題,可能有人有疑問,既然做了分頁怎么還會有大數(shù)據(jù)了,因為我們的產(chǎn)品是做大數(shù)據(jù)分析日志的,一頁十條日志,有的日志可能非常的長,也就是說就算是10條數(shù)據(jù)比對起來也是很耗時,所以當(dāng)時想法能不能找到其他的替代變量來表示數(shù)據(jù)變了?比如下面這樣

            shouldComponentUpdate(nextPrpops){returnnextPrpops.data[0].id!==this.props.data[0].id}

            第一條的id不一樣就表示數(shù)據(jù)變化了行不行,顯然在某種情況下是存在的,也有人會說可能會出現(xiàn)id一樣,那如果換成下面這種了?

            shouldComponentUpdate(nextPrpops){returnnextPrpops.current!==this.props.current}

            將data的比對轉(zhuǎn)換成了current的比對,因為頁數(shù)變了,數(shù)據(jù)基本都是變了,對于我們自己日志的展示來說基本不存在兩頁數(shù)據(jù)是一模一樣的,如果有那可能是后臺問題。然后再好好思考這個問題,即使存在了兩頁數(shù)據(jù)一摸一樣,頂多就是這個表格不重新渲染,但是兩頁數(shù)據(jù)一摸一樣不重新渲染是不是也沒有問題,因為數(shù)據(jù)是一樣的?;蛘呷绻氵€是不放心,那下面這種會不會好點

            this.tState({data,requestId:guid()})shouldComponentUpdate(nextPrpops){returnnextPrpops.requestId!==this.props.requestId}

            給一個requestId跟蹤data,后面就只比對requestId。上面的寫法可能都有問題,但是主要是想說的是我們在寫代碼時候可以想想是不是可以"將復(fù)雜的比對,變成簡單比對"

            學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法,一定會在你的工作中派上用場

            我們經(jīng)常會聽到學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法沒有什么大的用處,因為工作基本用不上。這句話我之前覺得沒錯,現(xiàn)在看來錯的很嚴(yán)重。我們所學(xué)的每一樣技能,都會在將來的人生中派上用場。之前寫完代碼就丟了不去優(yōu)化所以我覺得算法沒意義,又難又容易忘記。但現(xiàn)在要求自己做完需求,開啟mock,打開perfermance進(jìn)行大數(shù)據(jù)量的測試,看著那些標(biāo)紅的火焰圖和肉眼可見的卡頓,就明白了算法和數(shù)據(jù)結(jié)構(gòu)的重要性,因為此時你只能從它身上獲取優(yōu)化,平時你很排斥它,到優(yōu)化的時候你是那么想擁有它。我拿自己之前寫的代碼舉例,由于公司代碼是保密的我就把變量換一下,偽代碼如下

            data.filter(({id})=>{returnlectedIds.includes(id);})

            就是這樣幾行代碼,邏輯就是篩選出data里面已經(jīng)被勾選的數(shù)據(jù)。基本上很多人都可能這么寫,因為我看我們團(tuán)隊里面都是這么寫的。產(chǎn)品當(dāng)時已經(jīng)限制data最多200數(shù)據(jù),所以寫完完全沒壓力,性能沒影響。但是秉著對性能優(yōu)化的原則(主要是被現(xiàn)場環(huán)境搞怕了~~~),我開啟了mock服務(wù),將數(shù)據(jù)調(diào)到了2萬條再去測試,代碼弊端就暴露出來了,界面進(jìn)入卡頓,重新選擇的時候也會卡頓。然后就開始了優(yōu)化,當(dāng)時具體的思路如下

            按照現(xiàn)在的代碼來看,這是一個兩層循環(huán)的暴力搜索時間復(fù)雜度為O(n^2)。所以想著能不能降一下復(fù)雜度至少是O(nlogn),看了一下代碼只能從lectedIds.includes(id)這句入手,于是想著可不可以用二分,但是立馬被否定因為二分是需要有序的,我這數(shù)組都是字符串怎么二分。

            安靜了一下之后,回想起看過的算法課程和書籍以及做的算法題,改變暴力搜索的方法基本都是

            1:上指針

            2:數(shù)組升維

            3:利用hash表

            前兩者被我否定了因為我覺得還沒那么復(fù)雜,于是利用hash表思想解決這個問題,因為js里面有一個天然的hash表結(jié)構(gòu)就是對象。我們知道hash表的查詢是O(1)的,所以我將代碼改寫如下

            constids={};lectedIds.forEach(id=>ids[id]=1);data.filter(({id})=>{return!!ids[id];})

            將從lectedIds查詢變成從ids查詢,這樣時間復(fù)雜度就從O(n^2)變成了O(n)了,這段代碼增加了

            constids={};lectedIds.forEach(id=>ids[id]=1);

            其實增加了一個lectedIds遍歷也是一個O(n)的復(fù)雜度,總來說復(fù)雜度是O(2n),但是從時間復(fù)雜度長期期望來看還是一個O(n)的時間復(fù)雜度,只不過額外增加了一個對象,所以這也是一個典型的空間換時間的例子,但是也不要擔(dān)心,ids用完之后垃圾回收機(jī)制會把他回收的。

            本文發(fā)布于:2023-02-28 21:05:00,感謝您對本站的認(rèn)可!

            本文鏈接:http://m.newhan.cn/zhishi/a/1677723544102683.html

            版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請與我們聯(lián)系,我們將在24小時內(nèi)刪除。

            本文word下載地址:popsloader(popsloader v4g).doc

            本文 PDF 下載地址:popsloader(popsloader v4g).pdf

            標(biāo)簽:popsloader   v4g
            相關(guān)文章
            留言與評論(共有 0 條評論)
               
            驗證碼:
            推薦文章
            排行榜
            Copyright ?2019-2022 Comsenz Inc.Powered by ? 實用文體寫作網(wǎng)旗下知識大全大全欄目是一個全百科類寶庫! 優(yōu)秀范文|法律文書|專利查詢|
            主站蜘蛛池模板: 扒开双腿猛进入喷水高潮叫声| 国产一二三五区不在卡| 亚洲一区二区三区四区三级视频 | 亚洲午夜片| 亚洲AV综合色区无码一区| 麻豆精品久久久久久久99蜜桃| 亚洲欧美日本久久网站| 中文字幕日韩一区二区不卡| 91福利一区福利二区| 亚洲国产韩国欧美在线| 精品国产Av电影无码久久久| 亚洲大片中文字幕久久| 国产超碰无码最新上传| 成人国产亚洲精品一区二区| 天堂久久久久VA久久久久| 欧美性群另类交| 国产乱人伦AV在线A| 精品理论一区二区三区| 国产欧美精品一区二区三区-老狼| 国产深夜福利在线免费观看| 亚洲线精品一区二区三区| 亚洲午夜无码久久久久蜜臀av| 国产在线午夜不卡精品影院 | 不卡一区二区三区在线视频| 韩国免费A级毛片久久| 亚洲愉拍自拍另类天堂| 免费激情网址| 97视频精品全国免费观看| 亚洲人亚洲人成电影网站色| 久久综合精品国产一区二区三区无 | 天堂网亚洲综合在线| 精品无码人妻| 奇米四色7777中文字幕| 亚洲国产日韩在线视频| 国语对白爽死我了| 国产一区二区亚洲一区二区三区 | 人妻有码av中文字幕久久琪| 久久精品aⅴ无码中文字幕| 四虎成人在线观看免费| 亚洲欧美高清在线精品一区二区 | 九九热热久久这里只有精品|