整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          都在唱衰Android,事實真的是這樣嗎?

          都在唱衰Android,事實真的是這樣嗎?



          發現狀

          目前,移動開發已經處于飽和的階段,Android開發也不如當年盛況,已經不再像前幾年前那么火爆。以前是只要你會Android四大組件的都是個香餑餑,那樣的時代已經過去了,隨著人機交互的體驗要求,App的用戶體驗的要求、流暢度等等,已經不可同日而語。在這樣的大環境下,那么對我們的Android開發工程師也是同樣的改變。

          在這樣的情況下,由于飽和,隨處都能招到初級的工程師,公司有了選擇的余地,所以肯定會去選擇更加優秀的,這就必然導致了我們經常說的,Android開發者已經爛大街了,其實不然,只是公司的要求變高,市場飽和,門檻變高而已。所以這就要求我們更加的精于技術,據我了解,中、高級的工程師還是很受歡迎的。

          職業發展

          隨著Android的發展,有些人對Android未來感到茫然,經常有人問,“從事Android是不是沒有前途,找工作困難,希望能給點建議?”。早在2010年市場上有大量Android招聘,基本懂一點Java基礎的就可以搞Android,當時是移動互聯網創業的高峰期,號稱只要做個App就可以創業。“風來了豬都能找到工作,風停了最先摔死的都是豬”,如果你覺得找工作難,那一定是你在混日子,Android中高級以上的人才一直都非常稀缺

          只要在Android領域深耕,做到極致,努力成為這個方向的專家,有精力再提升工程架構思維,軟件工程思想都是相通的,境界會得到提升,即便再學習新東西也會非常快。只要一個領域做到極致,即便Android被淘汰了,換新領域面試官依然會相信你也能做到極致。千萬不能用一年的工作能力混十年工作經歷,否則你的市場價格連一年都不如,成為工作困難戶。

          跨平臺開發

          目前移動端跨平臺開發中,大致歸納為以下幾種情況:

          1.react nativeweex均使用JavaScript作為編程語言,目前JavaScript在跨平臺開發中,可謂占據半壁江山,大有“一統天下”的趨勢。react native 用了 react 的設計模式,但UI渲染、動畫效果、網絡請求等均由原生端實現。開發者編寫的js代碼,通過 react native 的中間層轉化為原生控件和操作,比ionic等跨平臺應用,大大提高了的用戶體驗。weex基于 Vue 設計模式,支持 web、android、ios 三端,原生端同樣通過中間層轉化,將控件和操作轉化為原生邏輯來提高用戶體驗。

          2.Flutter 是 Google 力推的跨平臺框架,將是未來的 Google Fuchsia OS 下開發應用的主要技術框架。谷歌對 Flutter 的投入非常大,SDK 的更新頻率也很高。2019 年 5 月 8 號,谷歌剛剛發布了 Flutter 1.5 穩定版。Flutter 的開發將不僅僅局限于移動跨平臺,目前已經支持 Web 開發、后端開發、PC 桌面應用開發(內測中)、嵌入式開發(內測中)。其實,撇開個人開發者,許多大公司早就率先嘗試了 Flutter。國內的阿里巴巴、騰訊、愛奇藝等大公司已經把 Flutter 應用在實際開發中,例如閑魚團隊已經把 Flutter 技術應用在閑魚應用上。

          學習的方向

          • Kotlin

          Kotlin 作為 Android 開發語言是大勢所趨。在此之前很早,Kotlin 就有“Android 世界的 Swift ”的稱號。當然在這之前大家這樣說難免有些底氣不足,與其說是一種事實不如說是一種愿望。而現在這么說就理直氣壯多了。Kotlin 語言相對 Java有很多優勢,比如官網介紹的簡潔、安全。Kotlin具有現代靜態編程語言的很多特點,如類型推斷、多范式支持、可空性表達、擴展函數、DSL支持等。另外對于安卓開發還提供了 Kotlin 安卓擴展和 Anko 庫,參見 Kotlin 用于 Android 。關于與 Java 互操作,尤其是 Java 調用 Kotlin 是大家普遍覺得坑的地方,除了默認 final外,還有一個主要原因應該就是名字修飾,解決方式可以按照它修飾后名字去引用,或者在 Kotlin 端使用 @JvmName 注解來生成便于 Java 使用的名字。具體參見 Java 中調用 Kotlin 。

          • Jetpack

          Jetpack 是一套庫、工具和指南,可幫助開發者更輕松地編寫優質應用。這些組件可幫助您遵循最佳做法、讓您擺脫編寫樣板代碼的工作并簡化復雜任務,以便您將精力集中放在所需的代碼上。

          組件可以單獨采用(不過這些組件是為協同工作而構建的),同時利用 Kotlin 語言功能幫助您提高工作效率。

          Android Jetpack 可管理繁瑣的 Activity(如后臺任務、導航和生命周期管理),以便您可以專注于如何讓自己的應用出類拔萃。

          Android Jetpack 組件圍繞現代化設計實踐構建而成,具有向后兼容性,可以減少崩潰和內存泄漏。

          • 組件化設計



          將一個app分成多個模塊,每個模塊都是一個組件(Module),開發的過程中我們可以讓這些組件相互依賴或者單獨調試部分組件等,但是最終發布的時候是將這些組件合并統一成一個apk,這就是組件化開發。組件化開發中認為組件作為系統的一部分,是可獨立運行的服務。

          現在很多公司面試都會問到組件化的問題,因為很多公司前期在做app的時候都沒有考慮過在業務量發展到一定的瓶頸的時候,app會變得十分臃腫,難以維護,又或者公司有其他的發展方向,需要做一個新的app,但是需要用到現有app的一部分業務功能,隨著公司發展,可能兩個app互相引用的業務模塊會越來越多,為了適應公司未來的發展,加快開發速度,組件化是不得不進行的一步。

          • 音視頻方向



          這個一個很不錯的方向,特別是在直播、短視頻等風口讓這個方向變得很火熱,我算是半個音視頻開發的從業者,因為 GitHub 開源的 CarGuo/GSYVideoPlayer 用戶還不少,所以被逼著成了半桶水的音視頻開發。

          未來 5G 時代音視頻方向肯定會繼續紅火。然而事實上一旦做了音視頻開發,你就會發現音視頻方向其實和 Android 沒有太大的必然聯系,因為音視頻開發是服務于 Android ,而非用 Android 去開發音視頻。

          音視頻開發首要的是需要學習C++,學習FFMpeg開源項目,了解音視頻的編碼協議、容器封裝和網絡協議,最后對于 Android來說就是NDK開發,然后還需要給iOS等其他平臺音視頻服務,因為如果音視頻項目只服務于Android是不現實的,所以選擇音視頻開發就要讓自己不局限于 Android ,并且這個方向會是偏低層的學習,所以會比較累但是技術會相對穩定。

          感想

          行情好不好,還是靠自己的能力說話。Android開發人員要想邁向光明之路,必須得苦練內功,把自己從菜鳥修煉成大佬、甚至神仙,到時候自然會有大批公司搶著要。有一句老話說的好:“比你優秀的對手在學習,你的仇人在磨刀,你的閨蜜在減肥,隔壁老王在練腰,我們必須不斷學習,否則我們將被學習者超越。”

          少白屏,我們常使用的有ssr,loading(卸載vue掛載的例如app dom id節點內,渲染后會覆蓋),組件內骨架屏,另外還有cdn,cache,lazyload(圖片、模塊)等,下面這篇文章雖然發表較早,但分析的較為全面,大家可以一起研讀學習一番

          導語

          隨著移動設備性能不斷增強,web 頁面的性能體驗逐漸變得可以接受,又因為 web 開發模式的諸多好處(跨平臺,動態更新,減體積,無限擴展),APP 客戶端里出現越來越多內嵌 web 頁面(為了配上當前流行的說法,以下把所有網頁都稱為 H5 頁面,雖然可能跟 H5 沒關系),很多 APP 把一些功能模塊改成用 H5 實現。

          雖然說 H5 頁面性能變好了,但如果沒針對性地做一些優化,體驗還是很糟糕的,主要兩部分體驗:

          1. 頁面啟動白屏時間:打開一個 H5 頁面需要做一系列處理,會有一段白屏時間,體驗糟糕。
          2. 響應流暢度:由于 webkit 的渲染機制,單線程,歷史包袱等原因,頁面刷新/交互的性能體驗不如原生。

          本文先不討論第二點,只討論第一點,怎樣減少白屏時間。對 APP 里的一些使用 H5 實現的功能模塊,怎樣加快它們的啟動速度,讓它們啟動的體驗接近原生。

          過程

          為什么打開一個 H5 頁面會有一長段白屏時間?因為它做了很多事情,大概是:

          初始化 webview -> 請求頁面 -> 下載數據 -> 解析HTML -> 請求 js/css 資源 
            -> dom 渲染 -> 解析 JS 執行 
            -> JS 請求數據 -> 解析渲染 -> 下載渲染圖片


          一些簡單的頁面可能沒有 JS 請求數據 這一步,但大部分功能模塊應該是有的,根據當前用戶信息,JS 向后臺請求相關數據再渲染,是常規開發方式。

          一般頁面在 dom 渲染后能顯示雛形,在這之前用戶看到的都是白屏,等到下載渲染圖片后整個頁面才完整顯示,首屏秒開優化就是要減少這個過程的耗時。

          前端優化

          上述打開一個頁面的過程有很多優化點,包括前端和客戶端,常規的前端和后端的性能優化在桌面時代已經有最佳實踐,主要的是:

          1. 降低請求量:合并資源,減少 HTTP 請求數,minify / gzip 壓縮,webP,lazyLoad。
          2. 加快請求速度:預解析DNS,減少域名數,并行加載,CDN 分發。
          3. 緩存:HTTP 協議緩存請求,離線緩存 manifest,離線數據緩存localStorage。
          4. 渲染:JS/CSS優化,加載順序,服務端渲染,pipeline。

          其中對首屏啟動速度影響最大的就是網絡請求,所以優化的重點就是緩存,這里著重說一下前端對請求的緩存策略。我們再細分一下,分成 HTML 的緩存,JS/CSS/image 資源的緩存,以及 json 數據的緩存。

          HTML 和 JS/CSS/image 資源都屬于靜態文件,HTTP 本身提供了緩存協議,瀏覽器實現了這些協議,可以做到靜態文件的緩存,具體可以參考這里(https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching ),總的來說,就是兩種緩存:

          1. 詢問是否有更新:根據 If-Modified-Since / ETag 等協議向后端請求詢問是否有更新,沒有更新返回304,瀏覽器使用本地緩存。
          2. 直接使用本地緩存:根據協議里的 Cache-Control / Expires 字段去確定多長時間內可以不去發請求詢問更新,直接使用本地緩存。

          前端能做的最大限度的緩存策略是:HTML 文件每次都向服務器詢問是否有更新,JS/CSS/Image資源文件則不請求更新,直接使用本地緩存。那 JS/CSS 資源文件如何更新?常見做法是在在構建過程中給每個資源文件一個版本號或hash值,若資源文件有更新,版本號和 hash 值變化,這個資源請求的 URL 就變化了,同時對應的 HTML 頁面更新,變成請求新的資源URL,資源也就更新了。

          json 數據的緩存可以用 localStorage 緩存請求下來的數據,可以在首次顯示時先用本地數據,再請求更新,這都由前端 JS 控制。

          這些緩存策略可以實現 JS/CSS 等資源文件以及用戶數據的緩存的全緩存,可以做到每次都直接使用本地緩存數據,不用等待網絡請求。但 HTML 文件的緩存做不到,對于 HTML 文件,如果把 Expires / max-age 時間設長了,長時間只使用本地緩存,那更新就不及時,如果設短了,每次打開頁面都要發網絡請求詢問是否有更新,再確定是否使用本地資源,一般前端在這里的策略是每次都請求,這在弱網情況下用戶感受到的白屏時間仍然會很長。所以 HTML 文件的“緩存”和跟“更新”間存在矛盾。

          客戶端優化

          接著輪到客戶端出場了,桌面時代受限于瀏覽器,H5 頁面無法做更多的優化,現在 H5 頁面是內嵌在客戶端 APP 上,客戶端有更多的權限,于是客戶端上可以超出瀏覽器的范圍,做更多的優化。

          HTML 緩存

          先接著緩存說,在客戶端有更自由的緩存策略,客戶端可以攔截 H5 頁面的所有請求,由自己管理緩存,針對上述 HTML 文件的“緩存”和“更新”之間的矛盾,我們可以用這樣的策略解決:

          1. 在客戶端攔截請求,首次請求 HTML 文件后緩存數據,第二次不發請求,直接使用緩存數據。
          2. 什么時候去請求更新?這個更新請求可以客戶端自由控制策略,可以在使用本地緩存打開本地頁面后再在后臺發起請求詢問更新緩存,下次打開時生效;也可以在 APP 啟動時或某個時機在后臺去發起請求預更新,提升用戶訪問最新代碼的幾率。

          這樣看起來已經比較完美了,HTML 文件在用客戶端的策略緩存,其余資源和數據沿用上述前端的緩存方式,這樣一個 H5 頁面第二次訪問從 HTML 到 JS/CSS/Image 資源,再到數據,都可以直接從本地讀取,無需等待網絡請求,同時又能保持盡可能的實時更新,解決了緩存問題,大大提升 H5 頁面首屏啟動速度。

          問題

          上述方案似乎已完整解決緩存問題,但實際上還有很多問題:

          1. 沒有預加載:第一次打開的體驗很差,所有數據都要從網絡請求。
          2. 緩存不可控:緩存的存取由系統 webview 控制,無法控制它的緩存邏輯,帶來的問題包括: i. 清理邏輯不可控,緩存空間有限,可能緩存幾張大圖片后,重要的 HTML/JS/CSS 緩存就被清除了。 ii.磁盤 IO 無法控制,無法從磁盤預加載數據到內存。
          3. 更新體驗差:后臺 HTML/JS/CSS 更新時全量下載,數據量大,弱網下載耗時長。
          4. 無法防劫持:若 HTML 頁面被運營商或其他第三方劫持,將長時間緩存劫持的頁面。

          這些問題在客戶端上都是可以被解決的,只不過有點麻煩,簡單描述下:

          1. 可以配置一個預加載列表,在APP啟動或某些時機時提前去請求,這個預加載列表需要包含所需 H5 模塊的頁面和資源,還需要考慮到一個H5模塊有多個頁面的情況,這個列表可能會很大,也需要工具生成和管理這個預加載列表。
          2. 客戶端可以接管所有請求的緩存,不走 webview 默認緩存邏輯,自行實現緩存機制,可以分緩存優先級以及緩存預加載。
          3. 可以針對每個 HTML 和資源文件做增量更新,只是實現和管理起來比較麻煩。
          4. 在客戶端使用 httpdns + https 防劫持。

          上面的解決方案實現起來十分繁瑣,原因就是各個 HTML 和資源文件很多很分散,管理困難,有個較好的方案可以解決這些問題,就是離線包。

          離線包

          既然很多問題都是文件分散管理困難引起,而我們這里的使用場景是使用 H5 開發功能模塊,那很容易想到把一個個功能模塊的所有相關頁面和資源打包下發,這個壓縮包可以稱為功能模塊的離線包。使用離線包的方案,可以相對較簡單地解決上述幾個問題:

          1. 可以預先下載整個離線包,只需要按業務模塊配置,不需要按文件配置,離線包包含業務模塊相關的所有頁面,可以一次性預加載。
          2. 離線包核心文件和頁面動態的圖片資源文件緩存分離,可以更方便地管理緩存,離線包也可以整體提前加載進內存,減少磁盤 IO 耗時。
          3. 離線包可以很方便地根據版本做增量更新。
          4. 離線包以壓縮包的方式下發,同時會經過加密和校驗,運營商和第三方無法對其劫持篡改。

          到這里,對于使用 H5 開發功能模塊,離線包是一個挺不錯的方案了,簡單復述一下離線包的方案:

          1. 后端使用構建工具把同一個業務模塊相關的頁面和資源打包成一個文件,同時對文件加密/簽名。
          2. 客戶端根據配置表,在自定義時機去把離線包拉下來,做解壓/解密/校驗等工作。
          3. 根據配置表,打開某個業務時轉接到打開離線包的入口頁面。
          4. 攔截網絡請求,對于離線包已經有的文件,直接讀取離線包數據返回,否則走 HTTP 協議緩存邏輯。
          5. 離線包更新時,根據版本號后臺下發兩個版本間的 diff 數據,客戶端合并,增量更新。

          更多優化

          離線包方案在緩存上已經做得差不多了,還可以再配上一些細節優化:

          公共資源包

          每個包都會使用相同的 JS 框架和 CSS 全局樣式,這些資源重復在每一個離線包出現太浪費,可以做一個公共資源包提供這些全局文件。

          預加載 webview

          無論是 iOS 還是 Android,本地 webview 初始化都要不少時間,可以預先初始化好 webview。這里分兩種預加載:

          1. 首次預加載:在一個進程內首次初始化 webview 與第二次初始化不同,首次會比第二次慢很多。原因預計是 webview 首次初始化后,即使 webview 已經釋放,但一些多 webview 共用的全局服務或資源對象仍沒有釋放,第二次初始化時不需要再生成這些對象從而變快。我們可以在 APP 啟動時預先初始化一個 webview 然后釋放,這樣等用戶真正走到 H5 模塊去加載 webview時就變快了。
          2. webview 池:可以用兩個或多個 webview 重復使用,而不是每次打開 H5 都新建 webview。不過這種方式要解決頁面跳轉時清空上一個頁面,另外若一個 H5 頁面上 JS 出現內存泄漏,就影響到其他頁面,在 APP 運行期間都無法釋放了。

          可以參考美團點評的這篇文章(https://tech.meituan.com/WebViewPerf.html )。

          預加載數據

          理想情況下離線包的方案第一次打開時所有 HTML/JS/CSS 都使用本地緩存,無需等待網絡請求,但頁面上的用戶數據還是需要實時拉,這里可以做個優化,在 webview 初始化的同時并行去請求數據,webview 初始化是需要一些時間的,這段時間沒有任何網絡請求,在這個時機并行請求可以節省不少時間。

          具體實現上,首先可以在配置表注明某個離線包需要預加載的 URL,客戶端在 webview 初始化同時發起請求,請求由一個管理器管理,請求完成時緩存結果,然后 webview 在初始化完畢后開始請求剛才預加載的 URL,客戶端攔截到請求,轉接到剛才提到的請求管理器,若預加載已完成就直接返回內容,若未完成則等待。

          Fallback

          如果用戶訪問某個離線包模塊時,這個離線包還沒有下載,或配置表檢測到已有新版本但本地是舊版本的情況如何處理?幾種方案:

          1. 簡單的方案是如果本地離線包沒有或不是最新,就同步阻塞等待下載最新離線包。這種用戶打開的體驗更差了,因為離線包體積相對較大。
          2. 也可以是如果本地有舊包,用戶本次就直接使用舊包,如果沒有再同步阻塞等待,這種會導致更新不及時,無法確保用戶使用最新版本。
          3. 還可以對離線包做一個線上版本,離線包里的文件在服務端有一一對應的訪問地址,在本地沒有離線包時,直接訪問對應的線上地址,跟傳統打開一個在線頁面一樣,這種體驗相對等待下載整個離線包較好,也能保證用戶訪問到最新。

          第三種 Fallback 的方式還帶來兜底的好處,在一些意外情況離線包出錯的時候可以直接訪問線上版本,功能不受影響,此外像公共資源包更新不及時導致版本沒有對應上時也可以直接訪問線上版本,是個不錯的兜底方案。

          上述幾種方案策略也可以混著使用,看業務需求。

          使用客戶端接口

          網路和存儲接口如果使用 webkit 的 ajax 和 localStorage 會有不少限制,難以優化,可以在客戶端提供這些接口給 JS,客戶端可以在網絡請求上做像 DNS 預解析/IP直連/長連接/并行請求等更細致的優化,存儲也使用客戶端接口也能做讀寫并發/用戶隔離等針對性優化。

          服務端渲染

          早期 web 頁面里,JS 只是負責交互,所有內容都是直接在 HTML 里,到現代 H5 頁面,很多內容已經依賴 JS 邏輯去決定渲染什么,例如等待 JS 請求 JSON 數據,再拼接成 HTML 生成 DOM 渲染到頁面上,于是頁面的渲染展現就要等待這一整個過程,這里有一個耗時,減少這里的耗時也是白屏優化的范圍之內。

          優化方法可以是人為減少 JS 渲染邏輯,也可以是更徹底地,回歸到原始,所有內容都由服務端返回的 HTML 決定,無需等待 JS 邏輯,稱之為服務端渲染。是否做這種優化視業務情況而定,畢竟這種會帶來開發模式變化/流量增大/服務端開銷增大這些負面影響。手Q的部分頁面就是使用服務端渲染的方式,稱為動態直出,見文章:70%以上業務由H5開發,手機QQ Hybrid 的架構如何優化演進?

          最后

          從前端優化,到客戶端緩存,到離線包,到更多的細節優化,做到上述這些點,H5 頁面在啟動上差不多可以媲美原生的體驗了。

          總結起來,大體優化思路就是:緩存/預加載/并行,緩存一切網絡請求,盡量在用戶打開之前就加載好所有內容,能并行做的事不串行做。這里有些優化手段需要做好一整套工具和流程支持,需要跟開發效率權衡,視實際需求優化。

          另外上述討論的是針對功能模塊類的 H5 頁面秒開的優化方案,客戶端 APP 上除了功能模塊,其他一些像營銷活動/外部接入的 H5 頁面可能有些優化點就不適用,還需要視實際情況和需求而定。另外微信小程序就是屬于功能模塊的類別,差不多是這個套路。

          這里討論了 H5 頁面首屏啟動時間的優化,上述優化過后,基本上耗時只剩 webview 本身的啟動/渲染機制問題了,這個問題跟后續的響應流暢度的問題一起屬于另一個優化范圍,就是類 RN / Weex 這樣的方案,有機會再探討。


          如果您覺得我們的內容還不錯,就請轉發到朋友圈,和小伙伴一起分享吧~

          原始發表:https://cloud.tencent.com/developer/article/1071723

          ,是MARVIS!它出生于意大利,是大英航空頭等艙客人專用的護理產品。據說是一直使用最初的制造工藝,工序復雜,一絲不茍,具有美容保濕的功效。而國人盛傳它為牙膏種族中的“愛馬仕”


          外包裝實拍

          我入手了全款(用都用不完),接下來說一下我自己的使用感受吧!

          七款的外包裝,例外顏色都是一樣的!

          包裝外面都是英文,嗯~~反正我看不懂!

          里面也全是英文,還有品牌特有的LOGO!


          真偽鑒別

          以下的五種鑒別方法,能準確的幫你區別MARVIS牙膏真偽!

          1:瓶蓋的區別。

          2:瓶口螺紋區別。

          3:尾部批次區別。

          4:包裝顏色區別。

          5:牙膏膏體區別。


          各款牙膏解讀

          名稱:MARVIS強力薄荷味牙膏

          主要成分:薄荷提取精華、水、山梨醇、甘油、薄荷香精、檸檬油精、肉貴醇、丁香酚。

          功效:強力薄荷,強烈去除煙漬、茶漬、咖啡漬,潔白牙齒。

          適合人群:常抽煙的人士,男士。

          http://h5.m.taobao.com/need/weex/container.html?_wx_tpl=http://g.alicdn.com/mtb/need-weex/p/bpu/entry-min.js&bpuId=827148031

          名稱:MARVIS 肉桂薄荷牙膏

          主要成分: 肉桂 提取精華、水、山梨醇、甘油、薄荷香精、肉貴醇、丁香酚。

          功效:防止牙齦出血,有助于預防牙結石和牙菌斑,提升牙齒的保護力和抵抗力。

          適合人群:口腔敏感人士。

          名稱:MARVIS 生姜薄荷牙膏

          主要成分:生姜提取精華、水、山梨醇、甘油、薄荷香精、肉貴醇、丁香酚。

          功效:解熱鎮痛,預防牙周炎,有助于預防蛀牙,牙結石和牙菌斑。

          適合人群:牙周炎患者。

          名稱:MARVIS 海洋薄荷牙膏

          主要成分:薄荷提取精華、水、山梨醇、甘油、香茅苯

          功效:清新口氣,預防牙齦上火出血,有助于預防蛀牙,牙結石和牙菌斑。

          適合人群:牙齦出血上火人士。

          名稱:MARVIS茉莉花薄荷味牙膏

          主要成分:茉莉花提取精華、 薄荷提取精華 、甘油、茉莉花香精、芳樟醇。

          功效:清新口氣,芬芳潔凈,有助于預防蛀牙,牙結石和菌斑。

          適合人群:白領愛美人士。

          名稱:MARVIS美白薄荷味牙膏

          主要成分:薄荷提取精華、水、甘油。

          功效:強效美白薄荷、持久潔凈、酷爽清新、有助于預防蛀牙,牙結石和菌斑。

          適合人群:需要提高牙齒美白度的人。

          http://h5.m.taobao.com/need/weex/container.html?_wx_tpl=http://g.alicdn.com/mtb/need-weex/p/bpu/entry-min.js&bpuId=826555020

          名稱:MARVIS甘草薄荷味牙膏

          主要成分:溫和甘草提取物、 薄荷提取精華、水、甘油、月桂基、檸檬酸、肉貴醇。

          功效:清火、緩解牙齦腫痛,有助于預防蛀牙,牙結石和菌斑。

          適合人群:老師、律師、播音員、記者等。


          使用感受及評測

          以上是這7款牙膏的評測結果,這些數據都是代表著個人的意見!5分為滿分,僅供參考。

          使用感受: MARVIS牙膏是專供大英航空頭等艙客人專用的護理產品。 MARVIS牙膏被稱為藝術品。我們不得不佩服MARVIS的專業性。 清涼薄荷的冰爽快感, 豐富的乳狀質地令您的齒頰留香, 帶來持久味覺的刺激,并且發揮強效美白功效,令笑容倍添動人。 能提升牙齒琺瑯質的抵抗力及保護力,有助預防蛀牙。

          https://mp.weixin.qq.com/s?__biz=MzI0OTQ3NDU5NA==&mid=2247483656&idx=1&sn=cc3862db812080423784a749e87764d4&chksm=e991ba45dee63353cde5557e25b230fd0150e317c82f7a61a452b0395821bec7f2a1b5670d7d&mpshare=1&scene=23&srcid=0622Xopd1MBqjYd35x5rJCIH#rd


          主站蜘蛛池模板: 无码国产精品一区二区免费16 | 国产亚洲福利精品一区| 亚欧在线精品免费观看一区| 午夜福利一区二区三区高清视频| 无码一区二区三区AV免费| 国产一区二区三区福利 | 亚洲日韩中文字幕一区| 人妻免费一区二区三区最新| 亚洲国产欧美国产综合一区| 中文字幕一区二区人妻| 国产精品一区二区香蕉| 久久精品午夜一区二区福利| 亚洲国产精品一区二区第一页免| 日本一区二区三区精品中文字幕| 日韩精品一区二区三区在线观看l| 中文字幕日韩一区二区三区不| 无码人妻精品一区二区蜜桃 | 亚洲第一区在线观看| 亚洲一区二区观看播放| 成人精品视频一区二区三区不卡| 久久亚洲日韩精品一区二区三区| 在线精品亚洲一区二区三区| 欧美日韩精品一区二区在线视频 | 午夜影视日本亚洲欧洲精品一区 | 亚洲视频一区在线| 国产成人高清精品一区二区三区 | 国产精品无圣光一区二区| 国产91精品一区| 国产乱人伦精品一区二区在线观看 | 久久久国产一区二区三区| 无码一区二区三区在线| 中文字幕无线码一区二区| 亚洲国产精品一区第二页| 国偷自产av一区二区三区| 亚洲国产AV无码一区二区三区| 精品无码一区二区三区爱欲九九| 中文字幕av无码一区二区三区电影| 国产成人精品一区二三区 | 一区二区高清在线观看| 国产主播一区二区三区| 日韩aⅴ人妻无码一区二区|