不知道該如何命名這篇文章,算做是工作多年的一些基礎(chǔ)總結(jié)吧。短時間完成的,比較粗糙,也會有錯誤之處。最近太忙,沒太多時間沉淀。
顯示
人眼能夠識別的幀率大概是60FPS,所以一幀的顯示周期為16ms左右。客戶端都是以消息隊(duì)列的形式處理用戶操作或系統(tǒng)回調(diào),故我們在Activity的oncreate或?UIViewController的viewDidLoad等主線程回調(diào)中,代碼的執(zhí)行時間都不能超過16ms,否則會有丟幀的情況發(fā)生。
丟幀
CPU需要計算當(dāng)前頁面所有視圖的大小、位置及圖片解碼等,然后交給GPU渲染成圖像幀,最后提交幀緩沖區(qū)(現(xiàn)在系統(tǒng)大多采用雙緩沖區(qū),有點(diǎn)類似Android里的SurfaceView的機(jī)制)。液晶屏和早起的CRT顯示屏原理類似,都是由視頻控制器從幀緩沖區(qū)逐行讀取數(shù)據(jù),最終由顯示器完成畫面的顯示,16ms后重復(fù)此操作 。在這個過程中,如果CPU和GPU沒能將新的數(shù)據(jù)完成計算提交到幀緩沖區(qū),那這一幀將被丟棄,就是所謂的丟幀。
內(nèi)存與線程
內(nèi)存分為堆和棧,線程是CPU執(zhí)行的最小單元,每個線程都有自己的調(diào)用堆棧及各種寄存器的值、程序計數(shù)器和棧指針,所以線程創(chuàng)建的代價是挺大的,現(xiàn)在語言庫都有自己的線程池(Android中的AsyncTask及Ios中的GCD等都是基于此)。棧的內(nèi)存由操作系統(tǒng)管理,函數(shù)調(diào)用的時候?qū)⒑瘮?shù)參數(shù)與函數(shù)內(nèi)臨時變量等壓入棧,函數(shù)返回時會出棧自動釋放(由棧指針等控制);而在這個過程中通過new或者alloc等實(shí)例化出來的對象會保存在堆上,由開發(fā)人員自己管理(垃圾回收或delete等)。
客戶端優(yōu)化
常見的優(yōu)化手段有很多,比如減少View的嵌套層級,將大任務(wù)分解成多個小任務(wù)將由消息循環(huán)逐個處理。內(nèi)存方面做到需要多少用多少,減少內(nèi)存釋放需要付出的代價。盡量減少阻塞主線程,Android與Ios中的系統(tǒng)Ui庫都是在主線程中計算大小位置與繪制,如果業(yè)務(wù)產(chǎn)品需要,可以考慮SurfaceView和CoreText以及AsyncDisplayKit等優(yōu)秀第三方庫等。
感慨
計算機(jī)技術(shù)通過多年的發(fā)展,語言、編譯器、SDK及Library極大的提高了開發(fā)效率,但降低門檻的同時也讓優(yōu)秀更加難以企及了。不論軟件如何發(fā)展,硬件的構(gòu)成依舊沒什么變化,計算機(jī)的運(yùn)行基礎(chǔ)依舊,所以掌握了基礎(chǔ)與原理,就可以不變應(yīng)外變,迅速掌握新技術(shù)適應(yīng)業(yè)務(wù)與產(chǎn)品的發(fā)展。