Dancer icon indicating copy to clipboard operation
Dancer copied to clipboard

Speed up Dancer

Open KES777 opened this issue 2 years ago • 0 comments

It seems Dancer do useless things if $content is returned by $self->execute (send_error)

--- a/lib/Dancer/Route.pm
+++ b/lib/Dancer/Route.pm
@@ -200,7 +200,15 @@ sub run {
         Dancer::Factory::Hook->execute_hooks('on_route_exception', $exception);
         die $exception;
     };
-    my $response = Dancer::SharedData->response;
+
+    if( ref($content) eq 'Dancer::Response' ) {
+        # coerce undef content to empty string to
+        # prevent warnings
+        $content = (defined $content) ? $content : '';
+
+        return $content;
+    }
+
 
     if ( $response && $response->is_forwarded ) {
         my $new_req =
@@ -228,10 +236,6 @@ sub run {
         return Dancer::Renderer->render_error(404);
     }
 
-    # coerce undef content to empty string to
-    # prevent warnings
-    $content = (defined $content) ? $content : '';
-
     my $ct =
       ( defined $response && defined $response->content_type )
       ? $response->content_type()
@@ -247,7 +251,6 @@ sub run {
     push(@$headers, 'Content-Type' => $ct)
       unless grep {/Content-Type/} @$headers;
 
-    return $content if ref($content) eq 'Dancer::Response';
     return Dancer::Response->new(
         status       => $st,
         headers      => $headers,

As second round of speed up we can check $response only once

--- a/lib/Dancer/Route.pm
+++ b/lib/Dancer/Route.pm
@@ -210,7 +210,14 @@ sub run {
     }
 
 
-    if ( $response && $response->is_forwarded ) {
+    my $response = Dancer::SharedData->response   or do{
+        return Dancer::Response->new(
+            status  => 200,
+            content => $content,
+        );
+    };
+
+    if ( $response->is_forwarded ) {
         my $new_req =
             Dancer::Request->forward($request, $response->{forward});
         my $marshalled = Dancer::Handler->handle_request($new_req);
@@ -224,7 +231,7 @@ sub run {
         );
     }
 
-    if ($response && $response->has_passed) {
+    if ($response->has_passed) {
         $response->pass(0);
 
         # find the next matching route and run it
@@ -236,23 +243,23 @@ sub run {
         return Dancer::Renderer->render_error(404);
     }
 
+
+    my $headers = [@{ $response->headers_to_array }];
+
+    if( !grep {/Content-Type/} @$headers ){
         my $ct =
-      ( defined $response && defined $response->content_type )
+          ( defined $response->content_type )
           ? $response->content_type()
           : setting('content_type');
 
-    my $st = defined $response ? $response->status : 200;
-
-    my $headers = [];
-    push @$headers, @{ $response->headers_to_array } if defined $response;
-
         # content type may have already be set earlier
         # (eg: with send_error)
         push(@$headers, 'Content-Type' => $ct)
-      unless grep {/Content-Type/} @$headers;
+
+    }
 
     return Dancer::Response->new(
-        status       => $st,
+        status       => $response->status,
         headers      => $headers,
         content      => $content,
     );

I am not so sure about second optimization, but it must be considered at least. Thank you

KES777 avatar Jan 12 '22 19:01 KES777