构建高性能 React Native 跨端应用—图片与内存

简介: 介绍 React Native 跨端应用图片和内存的优化

一 前言

在构建高性能 React Native 跨端应用—引擎与渲染章节中,我们从引擎渲染角度介绍了 React Native 的优化手段,本文我们继续从图片内存角度继续讨论一下如何构建高性能的 React Native 应用。

二 图像层面

在浏览器构建的 web 中开发者可能不用花费太多精力关注图像上,但是在移动应用中,对于图像的关注显得非常重要。因为在 RN 应用中,无论是图片还是动图,或者是视频都是非常耗内存的,内存的暴涨就很容易造成应用的崩溃。

图片合理应用

图片的处理,占 RN 性能优化的大头,在现在的移动端应用中,有很多应用大量图片的场景,加载图片的过程实际是很复杂的,并且图片本身的大小,也不是最后加载到内存中的大小,也就是说最后落实在内存里面的大小,会大于图片本身的大小。

图片的处理在不同平台上表现也不一致,在 iOS 平台上对于图像的加载,加密,到最后的展现,表现还算比较好。但是在安卓平台,就时常会出现幺蛾子。

笔者在开发 RN 应用中,就遇到了这样的场景:我们 RN 只运行在安卓端,一个 RN 页面会加载大量的图片,刚开始我们没有对图片进行任何处理,只是图片的宽度和高度是写死的,那么造成的现象是,所有的图片都展现不出来,并且图片是黑的,接下来就是安卓程序直接崩溃。

后来经过排查我们发现,原来我们给图片的容器特别小,但是图片资源却非常大,由于为了在小容器中呈现大的图片,就比如说一个 100 100 图片容器,加载一个 1000 1000 图片,安卓底层需要对图片源数据进行算法压缩,此时就会让内存暴涨,帧率直接降为个位数,导致黑屏,闪退的情况。笔者还把这种小容器加载大图片的情况,叫做小马拉大车。

那么如何解决这个问题呢? RN 中的 Image 组件有个 resizeMethod 属性,就是解决 Android 图片内存暴涨的问题。当图片实际尺寸和容器样式尺寸不一致时,决定以怎样的策略来调整图片的尺寸。

<Image resizeMethod="resize" source={
   
   {
   
    uri: imageUrl  }} />

resizeMethod 属性有三个可选的值,默认为 auto .

resize:小容器加载大图的场景就应该用这个属性。原理是在图片解码之前,会用算法对其在内存中的数据进行修改,一般图片大小大概会缩减为原图的 1/8。
scale:不改变图片字节大小,通过缩放来修改图片宽高。因为有硬件加速,所以加载速度会更快一些。

auto:使用启发式算法来在resize和scale中自动决定,,如果是本地图片,就会用 resize,其他的一般都是 scale 属性,由于项目运用的是网络图片,所以就按照 scale 处理逻辑。

实际最佳的方案就是,适当的大小的图片容器,加载适当的图片。但是对于一些图片资源的大小是未知的,我们不能直接通过设置宽和高的方式草率的设置图片容器大小,解决方案就是可以通过 api 的方式获取远程图片的大小。如下:

import {
   
    Image } from 'react-native'

/* 使用 */
Image.getSize(imageUrl,(width,height)=>{
   
    
    console.log('宽度:',width,'高度:',height)
})

当然客户端也可以把图片压缩的操作交给服务端去做,目前很多大公司都有自己的内建图床和 CDN 服务,会提供一些自定制图片的功能,在请求图片资源的时候,就把图片的宽和高拼接到 url 中,这样服务器接受到图片请求,会根据路径获取 width 和 height,然后自行的对图片进行压缩。返回给客户端的就已经是处理好的能够适配图片容器大小的图片了。

图片管理优化

上面介绍了图片的合理使用,接下来我们看一下图片的管理优化,在 RN 中有多种多样的类型的图片,比如 png/jpg/base64/gif ,对于 gif 在安卓 build.gradle 中需要添加相关依赖。对于一些动图的处理,比如 svg 和 svga ,RN 也提供了相关的生态去处理这些图像。

对图片的管理可以通过不同的场景,运用更为合理的方案。比如对于一些大量 gif 图片的场景,内存就是一个棘手问题,图片的管理工具就需要均衡好内存缓存和磁盘缓存的策略,一般都会采用三级缓存策略。

对于一些网络加载的图片,在一些网络差或者特殊网络的情况下,可以出现加载慢,丢包的现象,这样就会导致图片一致加载失败。庆幸的是,还有专门的图片管理库来来解决这个问题。那就是 react-native-fast-image。

react-native-fast-image 这个库比较受欢迎的,它对图片的加载和内存优化上都有着不错的表现。这个库在 iOS 和安卓平台上,底层用原理也各不相同。

三 内存层面

清除资源

对于清楚资源,谈不上具体的主流优化手段,确切的说,应该是一个值得关注的细节。

比如当 A 页面中有视频播放的模块,而 B 页面是 A 的二级页面,在融合模式下,进入 A 页面之后会开始播放视频流,但是当从 A 页面进入到 B 页面之后,本质上 A 页面并没有被回收,但是这个时候,还在加载着视频资源。那么这样下去,会让内存越来越大。

那么如何解决这个问题呢? 当 A 跳转到 B 页面之后,应该停止 A 页面加载资源,或者清空视频资源,让内存维护一个健康的水平。

对于一些超多 gif 图片的页面,并还有列表加载功能,这样在向下加载数据的过程中,会渲染更多的 gif 组件,这样就会让内存越来越大,并且不容易下来,或者一些低端的机型,根本无法渲染太多的 gif 图片,那么此时应该如何解决呢?

这个时候可以做一个优化,就是只有在视图范围内的元素才渲染真正的 gif 图片,而其他看不见的直接渲染图片或者是占位图。如下所示:

WechatIMG2339.png

清除状态

对于一些全局的状态,比如存在 Redux 中的数据源,或者是全局绑定的监听事件,setTimeout 延时器

四 总结

本文从图像与内存两个方面介绍了 RN 优化手段,希望这篇文章的能给 React Native 开发同学一个性能优化上启发。

参考

相关文章
|
17天前
|
移动开发 前端开发 JavaScript
构建高效跨平台移动应用:React Native入门指南
【8月更文挑战第47天】在移动开发领域,React Native凭借其跨平台特性和高效的开发模式赢得了开发者的青睐。本文将通过一个简易的待办事项应用实例,带领读者快速入门React Native,并展示如何利用JavaScript和React框架构建具有原生性能的应用。我们将探讨环境配置、界面布局、状态管理和数据流,以及如何打包和发布您的应用。准备好,让我们开始React Native之旅!
56 20
|
2月前
|
数据采集 Rust 安全
Rust在网络爬虫中的应用与实践:探索内存安全与并发处理的奥秘
【8月更文挑战第31天】网络爬虫是自动化程序,用于从互联网抓取数据。随着互联网的发展,构建高效、安全的爬虫成为热点。Rust语言凭借内存安全和高性能特点,在此领域展现出巨大潜力。本文探讨Rust如何通过所有权、借用及生命周期机制保障内存安全;利用`async/await`模型和`tokio`运行时处理并发请求;借助WebAssembly技术处理动态内容;并使用`reqwest`和`js-sys`库解析CSS和JavaScript,确保代码的安全性和可维护性。未来,Rust将在网络爬虫领域扮演更重要角色。
58 1
|
19天前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
38 0
|
2月前
|
移动开发 前端开发 JavaScript
构建高效跨平台移动应用:React Native入门指南
【8月更文挑战第31天】 在移动开发领域,React Native凭借其跨平台特性和高效的开发模式赢得了开发者的青睐。本文将通过一个简易的待办事项应用实例,带领读者快速入门React Native,并展示如何利用JavaScript和React框架构建具有原生性能的应用。我们将探讨环境配置、界面布局、状态管理和数据流,以及如何打包和发布您的应用。准备好,让我们开始React Native之旅!
|
2月前
|
前端开发 Java UED
瞬间变身高手!JSF 与 Ajax 强强联手,打造极致用户体验的富客户端应用,让你的应用焕然一新!
【8月更文挑战第31天】JavaServer Faces (JSF) 是 Java EE 标准的一部分,常用于构建企业级 Web 应用。传统 JSF 应用采用全页面刷新方式,可能影响用户体验。通过集成 Ajax 技术,可以显著提升应用的响应速度和交互性。本文详细介绍如何在 JSF 应用中使用 Ajax 构建富客户端应用,并通过具体示例展示 Ajax 在 JSF 中的应用。首先,确保安装 JDK 和支持 Java EE 的应用服务器(如 Apache Tomcat 或 WildFly)。
32 0
|
2月前
|
前端开发 JavaScript UED
🎬JSF 与 Ajax:打造瞬间响应的魔法界面!🚀 用户输入即刻,数据交互如梦幻泡影般呈现!
【8月更文挑战第31天】在现代Web应用中,异步数据交互是提升用户体验的关键。JavaServer Faces (JSF) 作为标准Java Web框架,结合Ajax技术,可轻松实现页面异步更新与数据交互。本文通过示例代码介绍如何在JSF中使用Ajax组件(如`f:ajax`)及后端处理方法实现异步功能,并结合JavaScript处理复杂交互,帮助开发者提升Web应用体验。
33 0
|
2月前
|
前端开发 JavaScript Android开发
React Native 快速入门简直太棒啦!构建跨平台移动应用的捷径,带你开启高效开发之旅!
【8月更文挑战第31天】React Native凭借其跨平台特性、丰富的生态系统及优异性能,成为移动应用开发的热门选择。它允许使用JavaScript和React语法编写一次代码即可在iOS和Android上运行,显著提升开发效率。此外,基于React框架的组件化开发模式使得代码更加易于维护与复用,加之活跃的社区支持与第三方库资源,加速了应用开发流程。尽管作为跨平台框架,React Native在性能上却不输原生应用,支持原生代码优化以实现高效渲染与功能定制。对于开发者而言,React Native简化了移动应用开发流程,是快速构建高质量应用的理想之选。
34 0
|
2月前
|
Rust 安全 程序员
揭秘Rust语言的内存安全秘籍:如何构建坚不可摧的系统级应用?
【8月更文挑战第31天】Rust语言凭借其独特内存安全机制在编程领域脱颖而出,通过所有权、借用与生命周期等概念,在保证高性能的同时避免了缓冲区溢出等常见错误。本文深入探讨Rust的内存安全机制,并通过示例代码展示如何利用这些机制构建高效且可靠的系统。尽管这些机制增加了学习难度,但为软件开发奠定了坚实基础,使Rust成为系统、嵌入式及网络编程的理想选择。随着社区的发展,Rust将在未来软件开发中扮演更重要角色。
36 0
|
2月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
下一篇
无影云桌面