From f9617b3d52e640c3820a8e8be86bde0fc10630f8 Mon Sep 17 00:00:00 2001 From: Gannon McGibbon Date: Thu, 28 Nov 2024 20:55:35 -0600 Subject: [PATCH] Autoload nested constants Reduces require time from ~125ms to ~5ms. Autoloads all constants under `GraphQL` to optimize boot time. Also autoloads `GraphQL::Types` because they can't be required in sequence.use they can't be required in sequence. --- lib/graphql.rb | 131 +++++++++++------- lib/graphql/railtie.rb | 1 + lib/graphql/schema.rb | 4 + lib/graphql/schema/relay_classic_mutation.rb | 1 - lib/graphql/types.rb | 43 ++++-- spec/graphql/types/iso_8601_date_spec.rb | 2 +- spec/graphql/types/iso_8601_date_time_spec.rb | 2 +- 7 files changed, 123 insertions(+), 61 deletions(-) diff --git a/lib/graphql.rb b/lib/graphql.rb index 63626128bfd..1a7ce3333e2 100644 --- a/lib/graphql.rb +++ b/lib/graphql.rb @@ -74,53 +74,90 @@ class << self end self.reject_numbers_followed_by_names = false -end -# Order matters for these: - -require "graphql/execution_error" -require "graphql/runtime_type_error" -require "graphql/unresolved_type_error" -require "graphql/invalid_null_error" -require "graphql/analysis_error" -require "graphql/coercion_error" -require "graphql/invalid_name_error" -require "graphql/integer_decoding_error" -require "graphql/integer_encoding_error" -require "graphql/string_encoding_error" -require "graphql/date_encoding_error" -require "graphql/duration_encoding_error" -require "graphql/type_kinds" -require "graphql/name_validator" -require "graphql/language" - -require_relative "./graphql/railtie" if defined? Rails::Railtie - -require "graphql/analysis" -require "graphql/tracing" -require "graphql/dig" -require "graphql/execution" -require "graphql/pagination" -require "graphql/schema" -require "graphql/query" -require "graphql/dataloader" -require "graphql/types" -require "graphql/static_validation" -require "graphql/execution" -require "graphql/schema/built_in_types" -require "graphql/schema/loader" -require "graphql/schema/printer" -require "graphql/introspection" -require "graphql/relay" + def self.eager_load! + [ + ExecutionError, + RuntimeTypeError, + UnresolvedTypeError, + InvalidNullError, + AnalysisError, + CoercionError, + InvalidNameError, + IntegerDecodingError, + IntegerEncodingError, + StringEncodingError, + DateEncodingError, + DurationEncodingError, + TypeKinds, + NameValidator, + Language, + Analysis, + Tracing, + Dig, + Execution, + Pagination, + Schema, + Query, + Dataloader, + Types, + *Types.eager_load!, + StaticValidation, + Execution, + Introspection, + Relay, + Subscriptions, + ParseError, + Backtrace, + UnauthorizedError, + UnauthorizedEnumValueError, + UnauthorizedFieldError, + LoadApplicationObjectFailedError, + Testing, + Current, + ] + end + + autoload :ExecutionError, "graphql/execution_error" + autoload :RuntimeTypeError, "graphql/runtime_type_error" + autoload :UnresolvedTypeError, "graphql/unresolved_type_error" + autoload :InvalidNullError, "graphql/invalid_null_error" + autoload :AnalysisError, "graphql/analysis_error" + autoload :CoercionError, "graphql/coercion_error" + autoload :InvalidNameError, "graphql/invalid_name_error" + autoload :IntegerDecodingError, "graphql/integer_decoding_error" + autoload :IntegerEncodingError, "graphql/integer_encoding_error" + autoload :StringEncodingError, "graphql/string_encoding_error" + autoload :DateEncodingError, "graphql/date_encoding_error" + autoload :DurationEncodingError, "graphql/duration_encoding_error" + autoload :TypeKinds, "graphql/type_kinds" + autoload :NameValidator, "graphql/name_validator" + autoload :Language, "graphql/language" + + autoload :Analysis, "graphql/analysis" + autoload :Tracing, "graphql/tracing" + autoload :Dig, "graphql/dig" + autoload :Execution, "graphql/execution" + autoload :Pagination, "graphql/pagination" + autoload :Schema, "graphql/schema" + autoload :Query, "graphql/query" + autoload :Dataloader, "graphql/dataloader" + autoload :Types, "graphql/types" + autoload :StaticValidation, "graphql/static_validation" + autoload :Execution, "graphql/execution" + autoload :Introspection, "graphql/introspection" + autoload :Relay, "graphql/relay" + autoload :Subscriptions, "graphql/subscriptions" + autoload :ParseError, "graphql/parse_error" + autoload :Backtrace, "graphql/backtrace" + + autoload :UnauthorizedError, "graphql/unauthorized_error" + autoload :UnauthorizedEnumValueError, "graphql/unauthorized_enum_value_error" + autoload :UnauthorizedFieldError, "graphql/unauthorized_field_error" + autoload :LoadApplicationObjectFailedError, "graphql/load_application_object_failed_error" + autoload :Testing, "graphql/testing" + autoload :Current, "graphql/current" +end require "graphql/version" -require "graphql/subscriptions" -require "graphql/parse_error" -require "graphql/backtrace" - -require "graphql/unauthorized_error" -require "graphql/unauthorized_enum_value_error" -require "graphql/unauthorized_field_error" -require "graphql/load_application_object_failed_error" -require "graphql/testing" -require "graphql/current" +require "graphql/railtie" if defined? Rails::Railtie diff --git a/lib/graphql/railtie.rb b/lib/graphql/railtie.rb index 9752e4d9dc6..2fdb1dadae4 100644 --- a/lib/graphql/railtie.rb +++ b/lib/graphql/railtie.rb @@ -4,6 +4,7 @@ module GraphQL class Railtie < Rails::Railtie config.graphql = ActiveSupport::OrderedOptions.new config.graphql.parser_cache = false + config.eager_load_namespaces << GraphQL initializer("graphql.cache") do |app| if config.graphql.parser_cache diff --git a/lib/graphql/schema.rb b/lib/graphql/schema.rb index e34c5af2b5c..9dc5818138b 100644 --- a/lib/graphql/schema.rb +++ b/lib/graphql/schema.rb @@ -1802,3 +1802,7 @@ module DefaultTraceClass end end end + +require "graphql/schema/built_in_types" +require "graphql/schema/loader" +require "graphql/schema/printer" diff --git a/lib/graphql/schema/relay_classic_mutation.rb b/lib/graphql/schema/relay_classic_mutation.rb index 3d43f8b1ec6..dca743e0e48 100644 --- a/lib/graphql/schema/relay_classic_mutation.rb +++ b/lib/graphql/schema/relay_classic_mutation.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true -require "graphql/types/string" module GraphQL class Schema diff --git a/lib/graphql/types.rb b/lib/graphql/types.rb index 5d288c96da0..727a9dd3dea 100644 --- a/lib/graphql/types.rb +++ b/lib/graphql/types.rb @@ -1,12 +1,33 @@ # frozen_string_literal: true -require "graphql/types/boolean" -require "graphql/types/big_int" -require "graphql/types/float" -require "graphql/types/id" -require "graphql/types/int" -require "graphql/types/iso_8601_date" -require "graphql/types/iso_8601_date_time" -require "graphql/types/iso_8601_duration" -require "graphql/types/json" -require "graphql/types/string" -require "graphql/types/relay" + +module GraphQL + module Types + def self.eager_load! + [ + Boolean, + BigInt, + Float, + ID, + Int, + JSON, + String, + ISO8601Date, + ISO8601DateTime, + ISO8601Duration, + Relay, + ] + end + + autoload :Boolean, "graphql/types/boolean" + autoload :BigInt, "graphql/types/big_int" + autoload :Float, "graphql/types/float" + autoload :ID, "graphql/types/id" + autoload :Int, "graphql/types/int" + autoload :JSON, "graphql/types/json" + autoload :String, "graphql/types/string" + autoload :ISO8601Date, "graphql/types/iso_8601_date" + autoload :ISO8601DateTime, "graphql/types/iso_8601_date_time" + autoload :ISO8601Duration, "graphql/types/iso_8601_duration" + autoload :Relay, "graphql/types/relay" + end +end diff --git a/spec/graphql/types/iso_8601_date_spec.rb b/spec/graphql/types/iso_8601_date_spec.rb index b7550d9bf9c..536570adb22 100644 --- a/spec/graphql/types/iso_8601_date_spec.rb +++ b/spec/graphql/types/iso_8601_date_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true require "spec_helper" -require "graphql/types/iso_8601_date" + describe GraphQL::Types::ISO8601Date do module DateTest class DateObject < GraphQL::Schema::Object diff --git a/spec/graphql/types/iso_8601_date_time_spec.rb b/spec/graphql/types/iso_8601_date_time_spec.rb index 0d78f33304b..329c8b9f07f 100644 --- a/spec/graphql/types/iso_8601_date_time_spec.rb +++ b/spec/graphql/types/iso_8601_date_time_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true require "spec_helper" -require "graphql/types/iso_8601_date_time" + describe GraphQL::Types::ISO8601DateTime do module DateTimeTest class DateTimeObject < GraphQL::Schema::Object