Files
react-native/packages/react-native/ReactCommon/React-Fabric.podspec
T
Eric Rozell d9823d80bb Delete ShadowTreeRevision on background thread (#50997)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/50997

In some apps, we spend a non-trivial amount of time calling ShadowNode destructors on the UI thread.

A simple way to avoid stalling the UI thread is to move the `baseRevision_` instance to a data structure that is cleared on a background thread, so it's tree of ShadowNode shared_ptrs are released (and in most cases destroyed) on the background thread.

Rather than using std::thread, this change introduces the LowPriorityExecutor abstraction that should be supplied by host platforms. The implementation of this LowPriorityExecutor for each platform is as follows:
- iOS: uses dispatch_async to a low priority dispatch queue
- Android: uses a pthread with SCHED_OTHER and priority = 19

Moving the ShadowTreeRevision into a lambda capture and punting the lambda to the LowPriorityExecutor moves the destructor calls of the ShadowNodes to the host platform implementation of the LowPriorityExecutor.

This change is also guarded by a feature flag so we can keep an eye out for potential memory leaks.

## Changelog

[Internal]

Reviewed By: NickGerleman

Differential Revision: D73688009

fbshipit-source-id: 6a66da248e6fe5c38375bf026499346e8381e75a
2025-05-05 07:44:02 -07:00

222 lines
8.5 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
require "json"
package = JSON.parse(File.read(File.join(__dir__, "..", "package.json")))
version = package['version']
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
react_native_path = ".."
Pod::Spec.new do |s|
s.name = "React-Fabric"
s.version = version
s.summary = "Fabric for React Native."
s.homepage = "https://reactnative.dev/"
s.license = package["license"]
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.source_files = "dummyFile.cpp"
s.pod_target_xcconfig = { "USE_HEADERMAP" => "YES",
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"DEFINES_MODULE" => "YES" }
if ENV['USE_FRAMEWORKS']
s.header_mappings_dir = './'
s.module_name = 'React_Fabric'
end
s.dependency "React-jsiexecutor"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-jsi"
s.dependency "React-logger"
s.dependency "React-Core"
s.dependency "React-debug"
s.dependency "React-featureflags"
s.dependency "React-runtimescheduler"
s.dependency "React-cxxreact"
add_dependency(s, "React-rendererdebug")
add_dependency(s, "React-graphics", :additional_framework_paths => ["react/renderer/graphics/platform/ios"])
add_dependency(s, "React-utils", :additional_framework_paths => ["react/utils/platform/ios"])
depend_on_js_engine(s)
add_rn_third_party_dependencies(s)
s.subspec "animations" do |ss|
ss.source_files = "react/renderer/animations/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/renderer/animations/tests"
ss.header_dir = "react/renderer/animations"
end
s.subspec "attributedstring" do |ss|
ss.source_files = "react/renderer/attributedstring/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/renderer/attributedstring/tests"
ss.header_dir = "react/renderer/attributedstring"
end
s.subspec "core" do |ss|
header_search_path = [
"\"$(PODS_TARGET_SRCROOT)/ReactCommon\"",
"\"$(PODS_ROOT)/Headers/Private/Yoga\"",
"\"$(PODS_TARGET_SRCROOT)\""
]
if ENV['USE_FRAMEWORKS']
header_search_path = header_search_path + [
"\"$(PODS_TARGET_SRCROOT)/react/renderer/textlayoutmanager/platform/ios\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/text/platform/cxx\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/textinput/platform/ios\"",
"\"$(PODS_TARGET_SRCROOT)/react/renderer/components/view/platform/cxx\"",
]
end
ss.source_files = "react/renderer/core/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/renderer/core/tests"
ss.header_dir = "react/renderer/core"
ss.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => header_search_path.join(" ")
}
end
s.subspec "componentregistry" do |ss|
ss.source_files = "react/renderer/componentregistry/*.{m,mm,cpp,h}"
ss.header_dir = "react/renderer/componentregistry"
end
s.subspec "componentregistrynative" do |ss|
ss.source_files = "react/renderer/componentregistry/native/**/*.{m,mm,cpp,h}"
ss.header_dir = "react/renderer/componentregistry/native"
end
s.subspec "components" do |ss|
ss.subspec "root" do |sss|
sss.source_files = "react/renderer/components/root/**/*.{m,mm,cpp,h}"
sss.exclude_files = "react/renderer/components/root/tests"
sss.header_dir = "react/renderer/components/root"
end
ss.subspec "view" do |sss|
sss.dependency "React-renderercss"
sss.dependency "Yoga"
sss.source_files = "react/renderer/components/view/**/*.{m,mm,cpp,h}"
sss.exclude_files = "react/renderer/components/view/tests", "react/renderer/components/view/platform/android", "react/renderer/components/view/platform/windows"
sss.header_dir = "react/renderer/components/view"
sss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/Yoga\"" }
end
ss.subspec "scrollview" do |sss|
sss.source_files = "react/renderer/components/scrollview/*.{m,mm,cpp,h}"
sss.header_dir = "react/renderer/components/scrollview"
ss.exclude_files = "react/renderer/components/scrollview/tests"
end
ss.subspec "legacyviewmanagerinterop" do |sss|
sss.source_files = "react/renderer/components/legacyviewmanagerinterop/**/*.{m,mm,cpp,h}"
sss.exclude_files = "react/renderer/components/legacyviewmanagerinterop/tests"
sss.header_dir = "react/renderer/components/legacyviewmanagerinterop"
sss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\"" }
end
end
s.subspec "dom" do |ss|
ss.dependency "React-graphics"
ss.source_files = "react/renderer/dom/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/renderer/dom/tests"
ss.header_dir = "react/renderer/dom"
end
s.subspec "scheduler" do |ss|
ss.source_files = "react/renderer/scheduler/**/*.{m,mm,cpp,h}"
ss.header_dir = "react/renderer/scheduler"
ss.dependency "React-performancetimeline"
ss.dependency "React-Fabric/observers/events"
end
s.subspec "imagemanager" do |ss|
ss.source_files = "react/renderer/imagemanager/*.{m,mm,cpp,h}"
ss.header_dir = "react/renderer/imagemanager"
end
s.subspec "mounting" do |ss|
ss.source_files = "react/renderer/mounting/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/renderer/mounting/tests"
ss.header_dir = "react/renderer/mounting"
end
s.subspec "observers" do |ss|
ss.subspec "events" do |sss|
sss.source_files = "react/renderer/observers/events/**/*.{m,mm,cpp,h}"
sss.exclude_files = "react/renderer/observers/events/tests"
sss.header_dir = "react/renderer/observers/events"
end
end
s.subspec "templateprocessor" do |ss|
ss.source_files = "react/renderer/templateprocessor/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/renderer/templateprocessor/tests"
ss.header_dir = "react/renderer/templateprocessor"
end
s.subspec "telemetry" do |ss|
ss.source_files = "react/renderer/telemetry/**/*.{m,mm,cpp,h}"
ss.exclude_files = "react/renderer/telemetry/tests"
ss.header_dir = "react/renderer/telemetry"
end
s.subspec "consistency" do |ss|
ss.source_files = "react/renderer/consistency/**/*.{m,mm,cpp,h}"
ss.header_dir = "react/renderer/consistency"
end
s.subspec "uimanager" do |ss|
ss.subspec "consistency" do |sss|
sss.source_files = "react/renderer/uimanager/consistency/*.{m,mm,cpp,h}"
sss.header_dir = "react/renderer/uimanager/consistency"
end
ss.dependency "React-rendererconsistency"
ss.source_files = "react/renderer/uimanager/*.{m,mm,cpp,h}"
ss.header_dir = "react/renderer/uimanager"
end
s.subspec "leakchecker" do |ss|
ss.source_files = "react/renderer/leakchecker/**/*.{cpp,h}"
ss.exclude_files = "react/renderer/leakchecker/tests"
ss.header_dir = "react/renderer/leakchecker"
ss.pod_target_xcconfig = { "GCC_WARN_PEDANTIC" => "YES" }
end
s.script_phases = [
{
:name => '[RN]Check rncore',
:execution_position => :before_compile,
:always_out_of_date => '1',
:script => <<-EOS
echo "Checking whether Codegen has run..."
rncorePath="$REACT_NATIVE_PATH/ReactCommon/react/renderer/components/rncore"
if [[ ! -d "$rncorePath" ]]; then
echo 'error: Codegen did not run properly in your project. Please reinstall cocoapods with `bundle exec pod install`.'
exit 1
fi
EOS
}
]
end