摘要:圖片資源作為與用戶交互的界面元素,在客戶端產品中起到了非常重要的角色作用。在應用開發中,移動端與的圖片使用策略也有所不同。端較大的內存容量,快速的渲染能力使各類型圖片資源都能得到較好的使用。
圖片資源( jpeg、png、svg、webp ... )作為與用戶交互的界面元素,在客戶端產品中起到了非常重要的角色作用。在應用開發中,移動端與PC的圖片使用策略也有所不同。PC端較大的內存容量,快速的渲染能力使各類型圖片資源都能得到較好的使用。而移動端由于設備內存,GPU渲染都與PC有較大差別,所以在App應用開發中,需要我們多帶帶分析處理。今天我們聊聊在React Native開發中,如何優美的使用圖片資源。 在 React Native 開發中,目前主流的圖標解決方式大概有四種: 基本圖片格式(png、jpeg)基本圖片格式是開發者最常用的一種圖片資源,RN官方提供了在移動端適配的解決方案,直接使用 Image 標簽就可以加載網絡、本地圖片。 ?
【缺點】需要引入多倍圖(@2x / @3x)進行適配,使得 jsBundle 體積增大,內存占用的消耗比較明顯。熱更新時對流量(雖然你不在乎),影響較大。資產變更必須伴隨二進制版本(apk | ipa)
將圖片保存在服務端,客戶端以URL的方式進行加載。客戶端不需要任何處理,例如在RN中加載網絡圖,只需要將URL傳遞給Image 組件的 src props。
【缺點】緩存較為麻煩,可以依賴 react-native-fast-image 庫。
IconFont (react-native-vector-icons)熟悉Web開發的同學,對于 字體圖標 絕對是不陌生的。基于此,開源庫 react-native-vector-icons 實現了在RN平臺的字體圖標解決方案。這種方案簡單,引進庫和 .ttf 文件,就能使用字體圖標了。?
【缺點】需要隨app打包,文件小,使用便利,不用擔心屏幕屏幕尺寸不能熱更新,需要引入額外的庫。
Svg 擁有體積小(Path),可縮放特性,因此不需要適配屏幕的分辨率尺寸,并且有效降低移動端內存占用問題。同時完美支持bundle熱更新
【缺點】RN平臺默認并不支持 Svg,幸運的是 react-native-svg 庫實現了在RN移動應用中渲染 Svg 圖標的能力。
方案分析多倍圖適配,.ttf 文件不能熱更新的問題。現有的字體圖標管理網站(iconfont、icomoo)也能生成svg文件。使得我們最終直接使用Svg。 react-native-svg 能對svg的標簽解析成圖片,如何將圖片渲染成組件呢?第三方庫 react-native-svg-uri 則能把svg文件的xml解析成 Component。迫不及待的集成,引入,運行。iOS完美的顯示出來,而將 Android 進行 Release 打包過程中,Logcat拋出如下錯誤:
原因是在Android平臺不支持直接加載 .svg 后綴的文件格式,只能允許加載 png 和 xml 格式的文件。我們打開.svg文件,可以看到如下內容:
<");xml version="1.0" standalone="no"");
<svg t="1554188197278" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4579" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128">
<defs>
<style type="text/css">style>
defs>
<path d="M790.24975 1.022977H228.123876c-42.453546 0-77.234765 35.292707-77.234765 78.769231v870.553446c39.896104 0 72.11988 33.246753 72.11988 73.654346h35.292707c0-19.948052 15.856144-36.315684 35.804196-36.315684s35.804196 16.367632 35.804196 36.315684h35.804196c0-19.948052 15.856144-36.315684 35.804196-36.315684s35.804196 16.367632 35.804195 36.315684h35.804196c0-19.948052 15.856144-36.315684 35.804196-36.315684s35.804196 16.367632 35.804196 36.315684h35.804196c0-19.948052 15.856144-36.315684 35.804195-36.315684s35.804196 16.367632 35.804196 36.315684h35.292707c0-19.948052 15.856144-36.315684 35.804196-36.315684s35.804196 16.367632 35.804196 36.315684h35.804196c0-40.407592 32.223776-73.142857 71.608391-73.142857V79.280719C867.484515 35.804196 832.703297 1.022977 790.24975 1.022977z m-118.153846 339.628372l-86.953047 88.999001h45.522478c16.879121 0 30.177822 13.298701 30.177822 30.68931s-13.298701 30.689311-30.177822 30.689311h-91.044955v62.401598h91.044955c16.879121 0 30.177822 13.298701 30.177822 30.689311s-13.298701 30.689311-30.177822 30.689311h-91.044955v93.090909c0 17.390609-13.298701 30.689311-30.177823 30.689311s-30.177822-13.298701-30.177822-30.689311v-93.090909H388.21978c-10.22977 0-20.971029-6.649351-26.085914-15.856144s-5.114885-21.482517 0-30.689311c5.114885-10.741259 15.856144-15.856144 26.085914-15.856144h91.044955V489.494505H388.21978c-16.879121 0-30.177822-13.298701-30.177822-30.68931s13.298701-30.689311 30.177822-30.689311h48.07992L345.254745 341.674326c-7.672328-8.183816-10.22977-19.948052-7.672327-30.689311s11.764236-19.948052 21.994006-22.505495c10.22977-4.091908 21.994006 0 30.177822 8.183817l119.688311 122.245754L629.130869 296.663337c7.672328-9.206793 19.436563-11.764236 30.177822-9.206794 10.22977 2.557443 19.436563 11.764236 21.994006 22.505495 2.557443 10.741259-1.022977 22.505495-9.206793 30.689311z" fill="#FF6F5A" p-id="4580">
path>
svg>
可以看到,其實 Svg 文件就是以path路徑來繪制圖標的。所以我們可以放棄 require svg 文件的方式,直接解析 svg 文件中的path 即可。同時也解決了減少 svg 占用空間,頻繁 require 靜態文件減慢速度的問題。 我們可以用腳本來將 svg文件 批量生成 Path 字符串,然后通過 react-native-svg-uri 來解析 Path xml。同時該庫作者也考慮到 Android 的問題,為開發者提供了通過 svg path 字符串渲染圖標的Api: svgXmlData 。?
【注意】react-native-svg-uri 更新太慢,建議不通過 npm 或 yarn 安裝,直接復制文件在項目中使用,避免版本問題。
通過上面的解析,實現流程分為如下三步:
(1)下載Svg文件
(2)解析所有Svg文件,將svg的path統一存放在 js 文件中
(3)封裝 svg 組件,通過 svgXmlData 加載svg path
可以看出第二步的實現起到來承前啟后的重要性,我們來看下核心代碼。
解析/**
* 讀取svg文件
* @param {*} svgFileName svg文件, 例如 home-icon.svg
* @returns { "home-icon": "" }
*/
function readSvgFile(svgFileName) {
return new Promise((resolve, inject) => {
readFile(path.join(svgFileDir, svgFileName), "utf8", (error, svgFile) => {
// eslint-disable-next-line no-useless-escape
const svgPath = svgFile.replace(/<");, "");
if (error) {
inject(error);
}
resolve({
[svgFileName.slice(0, svgFileName.lastIndexOf("."))]: svgPath,
});
});
});
}
/**
* 讀取svg文件夾目錄所有svg文件
* @returns { "home-icon": "... ", "xxx": "... " ... }
*/
function readSvgDir() {
return new Promise((resolve, inject) => {
readdir(svgFileDir, (error, svgFiles) => {
if (error) {
inject(error);
}
// svgFiles: string[]
Promise.all(svgFiles.map((svgFileName) => readSvgFile(svgFileName)))
.then((data) => resolve(data))
.catch((err) => inject(err));
});
});
}
/**
* 生成 .js 文件
*/
readSvgDir().then((data) => {
const svgFile = `export default {
${
data.map((item, index) => `${Object.keys(item)[0]}: "${Object.values(item)[0]}"
`)
}
}`;
writeFile(path.resolve(__dirname, `./${GENERATE_SVG_FILE_NAME}`), svgFile, (err) => {
if (err) {
throw new Error(err);
}
});
}).catch((error) => {
throw new Error(error);
});
從上述代碼可以看到,我們通過讀取遍歷svg文件夾下的所有svg文件,拿到的字符串,并將其生成js文件統一管理。最終生成的文件內容如下
export default { iconImage: "
封裝 SvgIcon 組件
/**
* svg 圖片組件
* @export
* @class SvgIcon
* @extends {PureComponent}
*/
import React, { PureComponent } from "react";
import { View } from "react-native";
import PropTypes from "prop-types";
import SvgUri from "./SvgUri";
import svgXmlData from "./svgXmlData";
export default class SvgIcon extends PureComponent {
static propTypes = {
style: PropTypes.object,
/* eslint-disable react/require-default-props */
color: PropTypes.object,
size: PropTypes.shape(
{
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
}
).isRequired,
icon: PropTypes.string.isRequired,
}
static defaultProps = {
style: {},
}
render() {
const {
size,
color,
style,
icon,
} = this.props;
const svgXmlPath = svgXmlData[icon];
// eslint-disable-next-line no-nested-ternary
return svgXmlData
");
使用
marginRight: 5 }} size={{ width: 26, height: 26 }}/>
通過以上實現,我們就優美的解決了圖片資源加載渲染問題。詳細代碼已上傳到GitHub:react-native-svg-icon
默認情況下 React Native 是不支持 GIF 和 WebP 格式的。Android 需要在android/app/build.gradle文件中根據需要手動添加以下模塊:
dependencies { // 如果你需要支持Android4.0(API level 14)之前的版本 compile "com.facebook.fresco:animated-base-support:1.10.0" // 如果你需要支持GIF動圖 compile "com.facebook.fresco:animated-gif:1.10.0" // 如果你需要支持WebP格式,包括WebP動圖 compile "com.facebook.fresco:animated-webp:1.10.0" compile "com.facebook.fresco:webpsupport:1.10.0" // 如果只需要支持WebP格式而不需要動圖 compile "com.facebook.fresco:webpsupport:1.10.0" }
iOS需要依賴第三方平臺來實現Webp的加載,如:react-native-webp-supprot 。推薦大家看下這篇文章:
React Native + WebP: Reducing bundle + binary sizes, increase speed with .webp image format
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7009.html
摘要:去年年初寫了一個擴展十閱后,一直想寫個十閱出來,奈何懶癌后期,一直拖到最近才完成原型。這次心血來潮閑的蛋疼,想起去年年初就有所耳聞的,于是就打算用它來耍耍。使用鏈接庫在設備上運行用來斷點調試地址學習資源圖圖圖 去年年初寫了一個 chrome 擴展「十閱」后,一直想寫個十閱 app 出來,奈何懶癌后期,一直拖到最近才完成原型。 其實很早之前就已經寫過一個 hybrid app 了,使用了...
摘要:圍觀本文需自備,,以及。使用打開,并點擊,會看到模擬器以及此項目對應的內容,效果如下如果想要修改顯示內容,請打開,里面是一堆模樣的東西。接下來,我們按照教程,來展示一張電影海報,為了方便,我們直接修改。 原文鏈接:http://www.tinghaige.com/ 本著什么都要攙和的原則,一起來看看React Native是如何開發iOS APP。 圍觀本文需自備Mac OSX ,...
摘要:前端每周清單半年盤點之與篇前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。與求同存異近日,宣布將的構建工具由遷移到,引發了很多開發者的討論。 前端每周清單半年盤點之 React 與 ReactNative 篇 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為...
摘要:整理收藏一些優秀的文章及大佬博客留著慢慢學習原文協作規范中文技術文檔協作規范阮一峰編程風格凹凸實驗室前端代碼規范風格指南這一次,徹底弄懂執行機制一次弄懂徹底解決此類面試問題瀏覽器與的事件循環有何區別筆試題事件循環機制異步編程理解的異步 better-learning 整理收藏一些優秀的文章及大佬博客留著慢慢學習 原文:https://www.ahwgs.cn/youxiuwenzhan...
閱讀 2649·2021-09-13 10:26
閱讀 1913·2021-09-03 10:28
閱讀 1983·2019-08-30 15:44
閱讀 800·2019-08-29 14:07
閱讀 392·2019-08-29 13:12
閱讀 2148·2019-08-26 11:44
閱讀 2342·2019-08-26 11:36
閱讀 2011·2019-08-26 10:19