mirror of https://github.com/rails/rails
Cache routes.url_helpers built modules
Previously, every time this was called it would return a new module. Every time a new controller is built, it had one of these module included onto it (see AbstractController::Railties::RoutesHelper). Because each time this was a new module we would end up with a different copy being included on each controller. This would also include a different copy on a controller than on its superclass (ex. ApplicationController). Furthermore, each generated module also extended the url helper modules. +--------------+ +-------------+ | | | | | path_helpers | | url_helpers | (named routes added here) | | | | +------+----+--+ +----+--+-----+ ^ ^ ^ ^ | | | | | +---------------+ | | | | | | | +-----------+ | | | | | +------+--+---+ +--+----+-----+ | | | | | (singleton) +------+ url_helpers | (duplicated for each controller) | | | | +-------------+ +-----+-------+ ^ | | +---------+-------+ | | | UsersController | | | +-----------------+ The result of this is that when named routes were added to the two top-level modules, defining those methods became extremely slow because Ruby has to invalidate the class method caches on all of the generated modules as well as each controller. Furthermore because there were multiple paths up the inheritance chain (ex. one through UsersController's generated module and one through ApplicationController's genereated module) it would end up invaliding the classes multiple times (ideally Ruby would be smarter about this, but it's much easier to solve in Rails). Caching this module means that all controllers should include the same module and defining these named routes should be 3-4x faster. This method can generate two different modules, based on whether supports_path is truthy, so those are cached separately.
This commit is contained in:
parent
4500ebba21
commit
37e778b6b4
|
@ -477,6 +477,14 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
def url_helpers(supports_path = true)
|
||||
if supports_path
|
||||
@url_helpers_with_paths ||= generate_url_helpers(true)
|
||||
else
|
||||
@url_helpers_without_paths ||= generate_url_helpers(false)
|
||||
end
|
||||
end
|
||||
|
||||
def generate_url_helpers(supports_path)
|
||||
routes = self
|
||||
|
||||
Module.new do
|
||||
|
|
Loading…
Reference in New Issue