AM generates a second page request for every page. Is this necessary?

Apart from performance issues, it interferes with other modules.
Here is my case:
- enable AM module
- enable Devel module
- go to admin/config/development/devel
- enabled one/more of those: Display query log, Display page timer, Display memory usage

Now open a page, and you'll see the Devel output (at the bottom of the page) twice.
Now, disable admin_menu, and the Devel output is shown only once per page.

Coming from #1805772: 3 errors in AJAX callback: devel_querylog_arguments() on pages with multiple blocks/views.

Comments

johnv’s picture

Title: Aadmin_menu generating a second page request. » Admin_menu 'Cache menu in client-side browser' generates a second page request.

This can be toggled with the admin_menu setting 'Cache menu in client-side browser'.

sun’s picture

Status: Active » Closed (works as designed)

The response of the second request is cached (forever) in the client-side browser.

johnv’s picture

Category: bug » support
Status: Closed (works as designed) » Active

Then I need some explanation,
OI guess is caches the admin_menu menu structure. What use has the cache if it must be set every page request (even if no dta has changed)?
Also, I see no noticable acceleration of the main-request, when toggling the client-side caching.

sun’s picture

No, the cache is not reset on every page request.

1) The actual admin menu is not contained in the server-side HTML page output.

2) The JS requests the admin menu output from the server. The HTTP response tells the browser to effectively not expire its cache.

3) Subsequent page requests will show the JS requests to the server (e.g., in the browser's JS console), but the request never ends up on the server, because the response is delivered by the browser cache.

johnv’s picture

Status: Active » Closed (works as designed)

Hmm,
all I see is extra overhead, without fastening my page load.
For now, I'll just leave the option unticked.

Thanks.

Elijah Lynn’s picture

Version: 7.x-3.0-rc3 » 7.x-3.0-rc5
Issue summary: View changes

Just want to say that I am experiencing a 2nd request also. It makes it to the server and does a full Drupal bootstrap. I have the cache option checked. So I am guessing some browser internals may have changed. I am using Chrome 47. Hitting this on 7.x-3.0-rc5.

Elijah Lynn’s picture

Elijah Lynn’s picture

Status: Closed (works as designed) » Active

I do get a 304 Not Modified on the cached admin_menu js request. I do think we could improve the comments on this getCache() block though. It isn't clear from reading the code that an XHR will come from the browser and not actually make a request if it is in local cache.

Also, we could add a @return and explain why the first if {} is just returning a hash and what that is supposed to mean.

/**
 * Retrieve content from client-side cache.
 *
 * @param hash
 *   The md5 hash of the content to retrieve.
 * @param onSuccess
 *   A callback function invoked when the cache request was successful.
 */
Drupal.admin.getCache = function (hash, onSuccess) {
  if (Drupal.admin.hashes.hash !== undefined) {
    return Drupal.admin.hashes.hash;
  }
  $.ajax({
    cache: true,
    type: 'GET',
    dataType: 'text', // Prevent auto-evaluation of response.
    global: false, // Do not trigger global AJAX events.
    url: Drupal.settings.admin_menu.basePath.replace(/admin_menu/, 'js/admin_menu/cache/' + hash),
    success: onSuccess,
    complete: function (XMLHttpRequest, status) {
      Drupal.admin.hashes.hash = status;
    }
  });
};
Elijah Lynn’s picture

Status: Active » Closed (works as designed)

Looks like this may be in some custom code we have. Just tested on a vanilla D7 install and it is actually skipping the getCache() even when the option is checked because the menu is in the output. That is a different issue though. Reclosing.

Elijah Lynn’s picture

Status: Closed (works as designed) » Active

Okay, vanilla D7 is also making the second request. Turns out that if you are on admin/config/administration/admin_menu it skips cache.

// Determine whether we need to show all components and disable all caches.
$complete = FALSE;
if (current_path() == 'admin/config/administration/admin_menu' && $_SERVER['REQUEST_METHOD'] == 'GET') {
  $complete = TRUE;
}

So, still valid it appears.

Elijah Lynn’s picture

Status: Active » Closed (works as designed)

So doing some research I see now that the cache: true parameter in jQuery we have set just let's the browser do it's own thing. Setting it to false adds a cachebusting timestamp. But cache: true isn't actually anything special with jQuery, just native browser caching. Which would then mean it would just honor normal cache headers. Which in my case are:

Cache-Control:private, max-age=31536000

Private should just mean not to cache in a shared proxy but do cache in local browser and then max-age is set to 1 year. So it seems the browser still wants to do a validation check and not serve straight from cache.

Oh, oh, oh, I just realized that F5/refresh forces the browser to do a cache validation check and sends a request to the server. If you do a actual 'enter' on the address bar it doesn't do that and gives a 200 OK (from cache).

Btw, I initially came across this because I am doing XHProf reports and every request was giving me one for the HTTP response and another for the admin menu cache.

tldr; Don't hit F5, just do a 'enter' in the address bar and you will get response from cache, no bootstrap.

jeff h’s picture

Status: Closed (works as designed) » Active

I don't think this should be closed. The caching mechanism seems unreliable.

I got here after spending about an hour wondering why my hook_init()'s were running twice on every page load other than the first one after a cache-clear.

With the "Cache menu in client-side browser" config option ticked, admin_menu is causing a double request situation.

Mine is requesting "js/admin_menu/cache/1b7e123eaa9d2adf6a9ec146c9f241e3" with a "Cache-Control: no-cache" request header, on every page load.

It feels to me like relying on the browser's built-in cache mechanism is too reliant on request headers and possibly browser implementations of cache, and it simply isn't always working. A solution like local storage or such would be more reliable IMO, albeit more messing around with code, particularly to deal with various browser issues. I'd have to question the need though — has it ever been benchmarked, even simplistically?

I'm willing to debug this further if others have the same issue. If not, I'm content to simply turn this option off on my site.

phubear’s picture

This issue is creating problems for other modules as well. I've come across the problem of using force password change, password policy modules and this for users who would use the admin toolbar. On force changing password, the user is presented with multiple requests and displays of the page (and form). I recommend setting the caching checkbox to no as opposed to the default yes until it is further developed and fixed.

diamondsea’s picture

You can update this quickly on your sites with:

drush vset admin_menu_cache_client 0

Elijah Lynn’s picture

Just want to throw this out there...

If you Ctrl+R the page, F5 the page, press refresh button in the browser or have network tools open with "disable cache" checked your browser will send a request header with 'cache-control: no-cache' and it will make that second Drupal request.

To properly test, you can either click links or enter the URL in the browser and press enter to make a normal request that should load the resource directly from the browser cache.

markhalliwell’s picture

Status: Active » Closed (duplicate)
Related issues: +#2219467: Fix client side caching

Closing as a dup of this related issue (which likely fixes this).

rimu’s picture

Version: 7.x-3.0-rc5 » 7.x-3.0-rc6

This bug has started happening for me on 3.0-rc6. Anyone else?

rimu’s picture

Status: Closed (duplicate) » Active