Skip to content

pref(rn): 优化全尺寸 linear-gradient 背景渲染时机 - #2521

Open
dos1in wants to merge 11 commits into
didi:masterfrom
dos1in:pref/rn-gradient-image
Open

pref(rn): 优化全尺寸 linear-gradient 背景渲染时机#2521
dos1in wants to merge 11 commits into
didi:masterfrom
dos1in:pref/rn-gradient-image

Conversation

@dos1in

@dos1in dos1in commented Jun 11, 2026

Copy link
Copy Markdown
Member

改动说明

优化 RN 全尺寸 linear-gradient 背景的首次渲染,避免无差别等待 onLayout

  • 仅对无偏移、非对角方向的 100% 100% 渐变使用四边撑满布局,直接渲染。
  • 存在背景偏移、非全尺寸或需计算对角方向时,保留 master 的布局路径和零尺寸保护。
  • 布局判断与样式生成共用优化条件,避免两者不一致;保留 master 的尺寸缓存和固定尺寸对角渐变处理。

例如容器宽度为 200background-position: 20px 0 时,渐变仍保持宽度 200,向右偏移并裁剪,不会被 left: 20; right: 0 压缩成 180

验证

  • RN 运行时 Jest:14 个测试套件、183 项测试通过;相关 ESLint 和 diff 检查通过。
  • 新增组件测试覆盖全尺寸直接渲染、正负偏移、零尺寸恢复及全尺寸与百分比尺寸切换。
平台 验证结果与范围
Android 15 模拟器 前一版修复方案的原生绘制专项:使用 react-native-linear-gradient 2.8.3 原生源码和 Yoga 布局输出验证偏移;7 个用例归零、更新颜色后恢复像素一致。包含 1 个原 PR 对照用例,其恢复成功不代表偏移布局正确。
iOS 18.4 模拟器 同上,7 个用例恢复像素一致。
鸿蒙真机 Harmony 6.1.1.120 在RN 容器运行从当前提交提取的渐变解析、布局和 useWrapImage Hook,检查全尺寸、正负偏移、居中、对角及半尺寸等 7 种布局;自动和手动归零后均恢复显示。

鸿蒙验证使用真实 React Hooks、RN 布局回调及宿主原生渐变组件,但不包含完整 .mpx 页面编译和业务生命周期。三端验证均不作为首帧性能量化结果。

平台截图

Android iOS 鸿蒙
Android 15:偏移布局与恢复验证 iOS 18.4:偏移布局与恢复验证 鸿蒙真机:当前修复版本恢复后的七种渐变布局

实际业务运行效果:

before.mp4
after.mp4

Comment thread packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx
@dos1in

dos1in commented Jul 1, 2026

Copy link
Copy Markdown
Member Author
valid-show-hide.mp4

验证看起没问题,验证逻辑如下:

<template>
  <view class="page">
    <view class="stage">
      <view
        key="bg-wx-show-linear-1"
        enable-background="{{ true }}"
        wx:show="{{ showGradient }}"
        class="gradient"
      >
        <text class="text">wx:show false -> true</text>
      </view>
    </view>

    <view class="button" bindtap="replay">
      <text class="button-text">重放</text>
    </view>
  </view>
</template>

<script>
  import { createPage } from '@mpxjs/core'

  createPage({
    data: {
      showGradient: false,
    },

    onReady() {
      this.replay()
    },

    methods: {
      replay() {
        this.setData({ showGradient: false })

        setTimeout(() => {
          this.setData({ showGradient: true })
        }, 800)
      },
    },
  })
</script>

<style lang="stylus" scoped>
  .page
    padding 32rpx
    background-color #f5f6f8
    min-height 100vh

  .stage
    position relative
    border-radius 18rpx
    overflow hidden
    background-color #e9edf2

  .gradient
    height 220rpx
    display flex
    align-items center
    justify-content center
    background-image linear-gradient(90deg, #00e1bf 0%, #00bed3 100%)
    background-repeat no-repeat
    background-size 100% 100%

  .text
    color #fff
    font-size 30rpx
    font-weight 600

  .button
    margin-top 24rpx
    height 72rpx
    display flex
    align-items center
    justify-content center
    background-color #14d0b4

  .button-text
    color #fff
    font-size 26rpx
</style>

Comment thread packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx Outdated
@dos1in
dos1in marked this pull request as draft July 9, 2026 09:04
@dos1in

dos1in commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

ios 平台兼容性有问题,处理中。

@dos1in
dos1in marked this pull request as ready for review September 9, 2026 03:31
@hiyuki

hiyuki commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

上面说的这个case确认过了吗?iOS下wx:show由false变为true后是否能够正常撑开渲染?

@dos1in

dos1in commented Sep 9, 2026

Copy link
Copy Markdown
Member Author

上面说的这个case确认过了吗?iOS下wx:show由false变为true后是否能够正常撑开渲染?

iOS 渐变绘制链路存在问题,mpx层目前无法处理,现在方案是根据平台只给android/harmony 优化,验证 demo 如下:

父节点 wx:show + 子节点渐变背景、background-size: 100% 100% 的场景

<template>
  <view class="page">
    <view bindtap="pageTap">tap me</view>
    <view wx:show="{{show}}">
      <view class="panel-wrapper" enable-background="{{true}}">
        3333
      </view>
    </view>
  </view>
</template>

<script>
  import { createPage } from '@mpxjs/core'

  createPage({
    data: {
      show: false
    },
    methods: {
      pageTap () {
        this.show = !this.show
      }
    }
  })
</script>

<style lang="stylus">
  .page
    width 100vw
    height 100vh
    padding-top 200px

  .panel-wrapper
    width 100px
    height 100px
    background-image linear-gradient(179deg, #fff 0%, #000 76%)
    background-size 100% 100%
    border 1px solid #fff
    box-shadow 0px 2px 6px 0px rgba(0, 49, 99, 0.08)
    border-radius 12px
    overflow hidden
    display flex
    flex-direction column
    color red
</style>

<script type="application/json">
  {
    "usingComponents": {}
  }
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants