diff --git a/lib/banzai/filter/abstract_reference_filter.rb b/lib/banzai/filter/abstract_reference_filter.rb
index 63ad8910c0ff31b774051f4e66a4ea145a041a21..230387c8383aacecf2b943f3d601d6b7177e2858 100644
--- a/lib/banzai/filter/abstract_reference_filter.rb
+++ b/lib/banzai/filter/abstract_reference_filter.rb
@@ -47,7 +47,17 @@ module Banzai
         { object_sym => LazyReference.new(object_class, node.attr(data_reference)) }
       end
 
-      delegate :object_class, :object_sym, :references_in, to: :class
+      def object_class
+        self.class.object_class
+      end
+
+      def object_sym
+        self.class.object_sym
+      end
+
+      def references_in(*args, &block)
+        self.class.references_in(*args, &block)
+      end
 
       def find_object(project, id)
         # Implement in child class
diff --git a/lib/banzai/filter/redactor_filter.rb b/lib/banzai/filter/redactor_filter.rb
index f01a32b5ae5e6055f69183e5005f7b08b8062fc7..66f77902319850ba847defb84a8762941e5b3756 100644
--- a/lib/banzai/filter/redactor_filter.rb
+++ b/lib/banzai/filter/redactor_filter.rb
@@ -10,7 +10,7 @@ module Banzai
     #
     class RedactorFilter < HTML::Pipeline::Filter
       def call
-        doc.css('a.gfm').each do |node|
+        Querying.css(doc, 'a.gfm').each do |node|
           unless user_can_see_reference?(node)
             # The reference should be replaced by the original text,
             # which is not always the same as the rendered text.
diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb
index 8ca05ace88cc55ea168935ed7d245b8ba61a7b40..7198a8b03e2bfbf5f73e85e31a8915b92fbf596a 100644
--- a/lib/banzai/filter/reference_filter.rb
+++ b/lib/banzai/filter/reference_filter.rb
@@ -124,7 +124,7 @@ module Banzai
       def replace_link_nodes_with_text(pattern)
         return doc if project.nil?
 
-        doc.search('a').each do |node|
+        doc.xpath('descendant-or-self::a').each do |node|
           klass = node.attr('class')
           next if klass && klass.include?('gfm')
 
@@ -162,7 +162,7 @@ module Banzai
       def replace_link_nodes_with_href(pattern)
         return doc if project.nil?
 
-        doc.search('a').each do |node|
+        doc.xpath('descendant-or-self::a').each do |node|
           klass = node.attr('class')
           next if klass && klass.include?('gfm')
 
diff --git a/lib/banzai/filter/reference_gatherer_filter.rb b/lib/banzai/filter/reference_gatherer_filter.rb
index 12412ff7ea9267bc32244758d76edef439724669..bef041129196a2f6aff811369a245329a12dcc5e 100644
--- a/lib/banzai/filter/reference_gatherer_filter.rb
+++ b/lib/banzai/filter/reference_gatherer_filter.rb
@@ -16,7 +16,7 @@ module Banzai
       end
 
       def call
-        doc.css('a.gfm').each do |node|
+        Querying.css(doc, 'a.gfm').each do |node|
           gather_references(node)
         end
 
diff --git a/lib/banzai/querying.rb b/lib/banzai/querying.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1e1b51e683e0f56ad391d94c00f9c762124581c7
--- /dev/null
+++ b/lib/banzai/querying.rb
@@ -0,0 +1,18 @@
+module Banzai
+  module Querying
+    # Searches a Nokogiri document using a CSS query, optionally optimizing it
+    # whenever possible.
+    #
+    # document - A document/element to search.
+    # query    - The CSS query to use.
+    #
+    # Returns a Nokogiri::XML::NodeSet.
+    def self.css(document, query)
+      # When using "a.foo" Nokogiri compiles this to "//a[...]" but
+      # "descendant::a[...]" is quite a bit faster and achieves the same result.
+      xpath = Nokogiri::CSS.xpath_for(query)[0].gsub(%r{^//}, 'descendant::')
+
+      document.xpath(xpath)
+    end
+  end
+end
diff --git a/spec/lib/banzai/querying_spec.rb b/spec/lib/banzai/querying_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..27da2a7439c53546ba0400ee3d0613594474cf07
--- /dev/null
+++ b/spec/lib/banzai/querying_spec.rb
@@ -0,0 +1,13 @@
+require 'spec_helper'
+
+describe Banzai::Querying do
+  describe '.css' do
+    it 'optimizes queries for elements with classes' do
+      document = double(:document)
+
+      expect(document).to receive(:xpath).with(/^descendant::a/)
+
+      described_class.css(document, 'a.gfm')
+    end
+  end
+end