我們如何將 Pinterest 的 iOS 應用大小減少 30% 以上

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"衆所周知,應用程序的大小(下載大小 [1] [2])是非常重要的,並且在應用程序的大小和客戶參與度之間存在關聯。通常,人們會根據大小來決定是否使用軟件,甚至以兆字節來支付帶寬。更不用說,隨着應用程序大小的增加,卸載率也會上升,這會導致用戶試圖釋放設備上的磁盤空間。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"近來,我們對 Pinterest 的 iOS 版 v9.1 進行了改進,使其體積大大減少:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/7f\/0d\/7f0823785f961db79c7489be6905270d.jpg","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#000000","name":"black"}}],"text":"表 1:iPhone 11 Pro 是我們的目標機型。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"結果,自從發佈以來,我們發現新版本(用戶從 App Store 下載)的應用程序安裝量有所增加。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"問題是什麼?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"關於 Pinterest 的背景,我們使用 "},{"type":"link","attrs":{"href":"https:\/\/medium.com\/pinterest-engineering\/developing-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92","title":null,"type":null},"content":[{"type":"text","text":"Bazel"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 進行 iOS 版本構建。加入你不熟悉 Bazel,這篇"},{"type":"link","attrs":{"href":"https:\/\/github.com\/pinterest\/xchammer\/blob\/master\/Docs\/BazelForiOSDevelopers.md","title":null,"type":null},"content":[{"type":"text","text":"文章"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"值得一讀。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"要創建本地化文件,我們有一個 CI 作業,它在應用程序(通過 Bazel 查詢)中自動掃描所有源代碼,並將其發送給 "},{"type":"link","attrs":{"href":"https:\/\/github.com\/box\/mojito","title":null,"type":null},"content":[{"type":"text","text":"Mojito"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 進行翻譯。這在我們添加一些擴展之前一直運行良好。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"每個"},{"type":"link","attrs":{"href":"https:\/\/developer.apple.com\/app-extensions\/","title":null,"type":null},"content":[{"type":"text","text":"擴展"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"都是具有自己 "},{"type":"link","attrs":{"href":"https:\/\/docs.bazel.build\/versions\/master\/build-ref.html#BUILD_files","title":null,"type":null},"content":[{"type":"text","text":"BUILD"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 文件的模塊。在 Bazel 構建後,它將本地化字符串從主應用包複製到每個擴展包。但是,這會通過複製每個擴展中的 Localizable.strings 文件來擴展整個應用包。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"因此,我們決定刪除擴展中的本地化副本。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"修復"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"第一,我們更新了 BUILD 文件,這樣擴展程序就不會從主應用包複製本地化字符串了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"但是,使用這個更改,NSLocalizedString 無法正確加載本地化字符串。在進一步研究之後,我們發現這些宏都使用 +[NSBundle mainBundle],但是 [NSBundle mainBundle] 實際上會返回一個包含“當前應用程序可執行文件”的包,當從擴展中調用該包時,該包將作爲你的應用程序的子文件夾。舉例來說,它是 "},{"type":"codeinline","content":[{"type":"text","text":"\/path\/to\/Pinterest.app\/PlugIns\/SiriExtension.appex\/"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" 而非 "},{"type":"codeinline","content":[{"type":"text","text":"\/path\/to\/Pinterest.app\/"}],"marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}]},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"。爲了使 NSLocalizedStringWithDefaultValue 能夠從"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"主應用包"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"中讀取本地化字符串,我們進行了更改來對路徑進行設置。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"這些全部已保存更改((所有 Localizable.strings 的"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"大小"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":")*(具有這種本地化重複的擴展的"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"數量"},{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":")),大約佔全部應用程序大小的 30%。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"長遠規劃"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"接下來,我們計劃將本地化資源放入各自的 SDK\/ 擴展中,而非依賴於應用包,這樣做有以下好處:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"每個包都將是自包含的,所以它不需要主應用程序包就能運行或測試本地化,並且可以被綁定到一個單獨的應用程序中。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"在擴展代碼中,NSLocalizedString 和本地化 API 按照自己的方式工作。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"讓包開源。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"此外,還可以進行其他可能的改進,例如,刪除不必要的非面向消費者的代碼本地化,研究更大尺寸的圖像格式,以及其他編譯器級的優化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[1] 下載大小是指從 App Store 下載時傳輸的實際大小,只有當應用超出蘋果確定的 200 MB 的限制,且用戶沒有使用 Wi-Fi 時纔會顯示,除非用戶更改默認設置。由於它被壓縮,所以比通常的安裝體積要小。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[2] 本地安裝大小是指實際應用在你的手機磁盤上的大小(設置應用→iPhone 存儲→Pinterest→應用大小)。它是爲你的手機型號瘦身的,所以通常比通用體積小。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"作者介紹:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":"Liang Ma,Pinterest Engineering 團隊應用基礎軟件工程師。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}}],"text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#494949","name":"user"}},{"type":"strong"}],"text":"英文原文鏈接:"},{"type":"link","attrs":{"href":"https:\/\/medium.com\/pinterest-engineering\/how-we-reduced-pinterests-ios-app-size-by-30-50mb-68d7f8425882","title":"xxx","type":null},"content":[{"type":"text","text":"https:\/\/medium.com\/pinterest-engineering\/how-we-reduced-pinterests-ios-app-size-by-30-50mb-68d7f8425882"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章