小程序以免安裝用完即走的特性自發(fā)布初就很火雕什,即使是現(xiàn)在也是熱度不減。小程序雖然是一個 HTML5筛圆,但是通過限制開發(fā)者的寫法篙顺,提供一套自定義的組件以及寫法面褐,并且將一部分耗費(fèi)性能的組件使用客戶端渲染來極大的提高網(wǎng)頁的性能拌禾。
小程序雖跟網(wǎng)頁差距不大,但碰到坑的情況也是在所難免的盆耽,下面就我這段時間碰到的一些比較經(jīng)典的問題來說一下我的解決方法。
遇到的問題
1數(shù)據(jù)傳輸長度超過最大長度
一個新聞流的項目中扼菠,用戶可以無限下拉加載數(shù)據(jù)摄杂,內(nèi)部會使用一個數(shù)組將列表的數(shù)據(jù)存儲起來。當(dāng)我使用 tinajs 重構(gòu)完項目后準(zhǔn)備試試的時候發(fā)現(xiàn)循榆,當(dāng)我加載數(shù)據(jù)超過一定數(shù)量限制(大概200條數(shù)據(jù))之后析恢,控制臺就會報“輸出傳輸長度超過最大長度”的錯誤。
2滾動問題
我們的小程序有一個下拉刷新的功能秧饮,小程序自己官方是有封裝 onPullDownRefresh
接口來幫助我們完成這個事映挂。不過因?yàn)槲覀兊南吕⑿率怯凶远x樣式的泽篮,所以就沒辦法使用官方的接口了。
最開始我是使用了 <scroll-view>
組件來做滾動柑船,同時使用 scrolltoupper
來觸發(fā)下拉的事件帽撑。內(nèi)部則是使用了 translate 操作來展開下拉卡片。一頓操作之后覺得甚是完美鞍时,但是之后突然發(fā)現(xiàn)官方提示:
因?yàn)檫@幾個組件都是使用 Native 實(shí)現(xiàn)的亏拉,只能是固定在屏幕上的存在,所以沒辦法在 scroll-view
中使用逆巍。同時使用了這個組件之后及塘,外部的其它組件想要修改 scrllTop
的話會變得很麻煩,都需要自維護(hù)一套事件锐极,增加了業(yè)務(wù)的復(fù)雜度笙僚。
3Canvas畫布問題
還有一個就是 Canvas 畫布的問題。這個 Canvas 畫布最大的問題在于小程序內(nèi)部是使用客戶端組件實(shí)現(xiàn)的灵再,但是在開發(fā)者工具中由于是網(wǎng)頁預(yù)覽所以這里的是 HTML 中的 <canvas>
肋层。雖然微信將 HTML 原生的 canvas 大部分接口都實(shí)現(xiàn)了,但是我要說很多不一樣檬嘀,所以這就導(dǎo)致了開發(fā)者工具上看到的效果和客戶端實(shí)際看到的效果有可能會完全不一樣槽驶,給我們開發(fā)過程帶來了無盡的阻撓。
解決方法
1
經(jīng)過我和 tinajs 作者的逐一分析鸳兽,發(fā)現(xiàn)可能是自定義組件的鍋掂铐。因?yàn)槲业牧斜碓赜胁煌臉邮剑晕沂褂昧俗远x組件去定義了不同的樣式類型組件揍异,部分組件又有公共的部分所以又要抽離出來變成組件全陨,也就是說實(shí)際上我的列表是由一個多層嵌套的自定義組件循環(huán)渲染而成的。我們猜測最后小程序渲染的時候衷掷,每一個自定義組件傳入的數(shù)據(jù)都會做一次拷貝辱姨,這樣就導(dǎo)致了我本來 150K 的數(shù)據(jù),瞬間就超過了它們的限制戚嗅。
最后解決的辦法也非常簡單雨涛,由于我其實(shí)大多數(shù)都是純渲染的組件,所以組件內(nèi)部的自定義組件我都是用 <template>
模板去渲染懦胞,這種情況下不會觸發(fā)數(shù)據(jù)的拷貝試了下就沒有問題了替久。當(dāng)然除了我說的減少數(shù)據(jù)體積以及用自定義模板代替自定義組件減少數(shù)據(jù)拷貝層級之外,我們還可以對數(shù)據(jù)進(jìn)行分頁操作來達(dá)到減少一次數(shù)據(jù)渲染的體積躏尉。
2
最終我退回成普通的 view 監(jiān)聽 touchstart
, touchmove
和 touchend
事件蚯根,根據(jù)移動的距離來判斷下拉百分比來實(shí)現(xiàn)這個功能。最終的實(shí)現(xiàn)可以說是異常艱辛的胀糜。不過這個實(shí)現(xiàn)完了之后颅拦,又出現(xiàn)了一個問題蒂誉。在 iOS 中會存在阻尼效果,也就是下拉的時候滾動條會有一個回彈的特效距帅,導(dǎo)致你雖然下拉了但是 touch 事件并沒辦法有效的執(zhí)行右锨。目前這個問題還沒有比較好的解決辦法,這里也有用戶提出了需要提供禁止頁面阻尼效果的參數(shù)锥债,不過目前還沒有官方回應(yīng)陡蝇。
3
由于是客戶端渲染的畫布,所以小程序的畫布有以下幾個比較明顯的特點(diǎn):
小程序的畫布是無限大的哮肚,使用 CSS 的寬高設(shè)置只是影響它的顯示區(qū)域登夫,并不會影像繪制。也就是說你發(fā)現(xiàn)元素繪制超出畫布返回之后允趟,只要設(shè)置畫布的 CSS 寬高即可讓超出區(qū)域顯示出來恼策。如果是 HTML 中的畫布的話應(yīng)該是沒有這個效果的。這樣就導(dǎo)致了我們沒辦法同時設(shè)置繪制區(qū)域和畫布大小這兩個概念潮剪。
小程序的畫布因?yàn)槭强蛻舳虽秩镜幕量运肋h(yuǎn)是置頂?shù)模?code>z-index 屬性是無效的。這個理解起來也非常簡單抗碰,因?yàn)榫W(wǎng)頁是使用客戶端 WebView 組件加載的狮斗,畫布又是另外一個客戶端組件,兩個客戶端組件疊加只能是以層級的關(guān)系疊加弧蝇,沒辦法做成嵌入式的碳褒。
小程序的
ctx.draw()
方法是異步的,而且默認(rèn)是清屏重繪的看疗。這個和原生的畫布是有區(qū)別的沙峻,之前我沒有注意清屏重繪的問題導(dǎo)致調(diào)試了很久。小程序的
ctx.drawImage()
方法只能獲取本地資源的圖片两芳。當(dāng)你想要使用遠(yuǎn)程資源的時候必須先使用wx.getImageInfo()
方法下載下來獲取到路徑之后才能使用ctx.drawImage()
進(jìn)行繪制摔寨。
另外還有一個問題在于,小程序的畫布必須可視才能繪制成功怖辆,也就是說如果你給這個畫布設(shè)置 display:none
然后等它繪制成功之后再顯示出來是不可以的是复。目前我的解決辦法是在頁面用戶不可視區(qū)域內(nèi)先繪制然后再獲取圖片內(nèi)容。
結(jié)束語
目前接觸到的小程序的一些問題大概是這么多竖螃,有些可能在之后的版本中會解決(例如阻尼效果)淑廊,而有些真的就是特性必須去適應(yīng)(例如畫布)。希望我總結(jié)的一些經(jīng)驗(yàn)?zāi)軒椭酱蠹摇?/p>
原文作者:怡紅公子
原文地址: