title: How to improve performance of Watir element.present? method?
body: <p>I experience IMO high delays with the Ruby script using Watir. Here's the problem description: I am testing AJAX based application and I wanted to avoid using of sleep to make sure page gets loaded:</p>
  
  <pre><code>class Page
    attr_accessor :expected_elements
  
    def loaded?
      # code to make sure AJAX page is loaded
    end
  end
  </code></pre>
  
  <p>So instead of this:</p>
  
  <pre><code>def loaded?
    # static delay sufficient to get page loaded
    sleep(MAX_PAGE_LOAD_TIME)
    true
  end
  </code></pre>
  
  <p>I wanted to have something like this:</p>
  
  <pre><code>def loaded?
    Watir::Wait.until(MAX_PAGE_LOAD_TIME) do
      expected_elements.all? do |element|
        element.present?
      end
    end
  end
  </code></pre>
  
  <p>The problem is the evaluation of the block takes too long. The more elements I check for presence the higher this delay gets. I experienced roughly this delay for one iteration:</p>
  
  <pre><code>Firefox -&gt; 130ms
  IE -&gt; 615ms
  Chrome -&gt; 115 ms
  </code></pre>
  
  <p>So to check if N elements are present I get N times corresponding delay... Well the consequence is that eventhough MAX_PAGE_LOAD_TIME expires the Watir::Wait::TimeoutError is not thrown because block evaluation has not been finished yet... So I ended up in the situation where the check for elements presence introduces higher delay than the static delay which is sufficient enough to get page loaded.. I tried to improve performance by locating elements by xpath, but the performance gain was not significant..
  What am I doing wrong? Is there a way to speed-up execution time for present? method?? Do these delays correspond with your experience - or are they high?</p>
  
  <p>I checked if the problem could be in the browser-server communication, but here the delays are very low.. I got 100ms time difference for the server response including backend DB request. Of course it takes some time to render page based on this response, but for sure it does not take seconds.</p>
  
  <p>My configuration: 
  - Win7 OS,
  - Firefox 17.0.1
  - IE 8.0.7601.17514 with IEDriverServer_x64_2.26.2
  - Chrome 23.0.1271.97 m with chromedriver_win_23.0.1240.0,
  - Ruby 1.9.3p125, 
  - watir-webdriver (0.6.1),
  - selenium-webdriver (2.27.2)</p>
  
  <p>Thank you for your help!</p>
  
  <p>Based on the discussion I post a sample of benchmarking code:</p>
  
  <pre><code>Benchmark.bm do |x|
    x.report("text") do
      b.span(:text =&gt; "Search").present?
    end
  end
  Benchmark.bm do |x|
    x.report("xpath") do
      b.span(:xpath =&gt; "/html/body/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/span/span").present?
    end
  end
  
          user     system      total        real
  text   0.000000   0.000000   0.000000 (  0.140405)
  xpath  0.000000   0.000000   0.000000 (  0.120005)
  </code></pre>
  
  <p>Additional benchmarking results:</p>
  
  <pre><code>container_xpath = "/html/body/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div[2]/div/div/div/div[2]/div/div/div"
  Benchmark.bm do |x|
    x.report("cntnr") do
      @c = b.div(:xpath =&gt; container_xpath)
      @c.present?
    end
  end
  Benchmark.bm do |x|
    x.report("lb1") do
      @c.div(:xpath =&gt; "div[1]/div/div").present?
      #@c.div(:text =&gt; "Company:").present?
    end
  end
  Benchmark.bm do |x|
    x.report("lb2") do
      @c.div(:xpath =&gt; "div[3]/div/div").present?
      #@c.div(:text =&gt; "Contact person:").present?
    end
  end
  Benchmark.bm do |x|
    x.report("lb3") do
      @c.div(:xpath =&gt; "div[5]/div/div").present?
      #@c.div(:text =&gt; "Address:").present?
    end
  end
  </code></pre>
  
  <p>And the results were:</p>
  
  <pre><code>Results for container reference and relative xpath:
         user     system      total        real
  cntnr  0.000000   0.000000   0.000000 (  0.156007)
  lb1    0.000000   0.000000   0.000000 (  0.374417)
  lb2    0.000000   0.000000   0.000000 (  0.358816)
  lb3    0.000000   0.000000   0.000000 (  0.358816)
  
  Results for container reference and div's text:
         user     system      total        real
  cntnr  0.000000   0.000000   0.000000 (  0.140402)
  lb1    0.000000   0.000000   0.000000 (  0.358807)
  lb2    0.000000   0.000000   0.000000 (  0.358807)
  lb3    0.000000   0.000000   0.000000 (  0.374407)
  </code></pre>
  
  <p>When absolute xpaths were used:</p>
  
  <pre><code>container_xpath = "/html/body/div/div/div[2]/div[2]/div/div/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div/div/div/div/div/div/div/div/div/div/div/div/div[2]/div/div/div/div[2]/div/div/div"
  Benchmark.bm do |x|
    x.report("cntnr") do
      @c = b.div(:xpath =&gt; container_xpath)
      @c.present?
    end
  end
  
  lb1_xpath = container_xpath + "/div[1]/div/div"
  Benchmark.bm do |x|
    x.report("lb1_x") do
      b.div(:xpath =&gt; lb1_xpath).present?
    end
  end
  
  lb2_xpath = container_xpath + "/div[3]/div/div"
  Benchmark.bm do |x|
    x.report("lb2_x") do
      b.div(:xpath =&gt; lb2_xpath).present?
    end
  end
  
  lb3_xpath = container_xpath + "/div[5]/div/div"
  Benchmark.bm do |x|
    x.report("lb3_x") do
      b.div(:xpath =&gt; lb3_xpath).present?
    end
  end
  </code></pre>
  
  <p>Results were:</p>
  
  <pre><code>       user     system      total        real
  cntnr  0.000000   0.000000   0.000000 (  0.140404)
  lb1_x  0.000000   0.000000   0.000000 (  0.124804)
  lb2_x  0.000000   0.000000   0.000000 (  0.156005)
  lb3_x  0.000000   0.000000   0.000000 (  0.140405)
  </code></pre>