Problem/Motivation

#2381277: Make Views use render caching and remove Views' own "output caching" replaces output caching with render caching.
Render caching though is disabled on POST requests, so that ajax requests aren't cacheable.

We need to get #956186: Allow AJAX to use GET requests in, to be able to get render caching done.

Proposed resolution

- Add setting for query type to views pagers
- Make views pager respect that setting so that it uses the correct protocol
- Get render caching to work on views AJAX paging responses

Remaining tasks

- Fix broken tests on 8.3 re-roll.
- Get #956186: Allow AJAX to use GET requests committed
- Verify that we have enough test coverage on this issue
- QA testing to get to RBTC

User interface changes

I added a "pager query type" selector to sql-base pagers which becomes active if you set the view to use AJAX.

API changes

- Added a "getParam" method to ViewAjaxController to make it easier to get parameters off of a request.

How to test

- Install a new site
- Apply most recent patch from this issue (currently: https://www.drupal.org/files/issues/2500313--views-get-paging-support-83...)
- Apply https://www.drupal.org/files/issues/ajax-956186-65_2x_1.patch from #956186: Allow AJAX to use GET requests
- Create at least five articles
- Create two views as follows

View 1
- Add a block display
- Call it "GET pager view"
- List all nodes
- Turn on AJAX for the view
- Use a pager (try them all if you can); 2 per page, set query type to GET

View 2
Same as View 1, except:
- Call it "POST pager view"
- Set query type on the pager settings to POST

Now:
- Place both blocks somewhere on the page
- Start using the pager, and use the network tab (helpful to filter by XHR) to ensure that the views are using the correct protocol for their requests.

Some other things to try:
- Using a table display, ensure that column sorting is respected after paging back and forth.
- Add an exposed filter and make sure paging works after the setting the filter value.
- Test the render caching somehow. Make sure page cache is turned on, and put a breakpoint or something inside a function that runs when rendering a row. The breakpoint should hit a) when the cache is first populated and b) if something invalidates the cache (i.e. that node is updated).

CommentFileSizeAuthor
#92 2500313-92.patch15.18 KB_utsavsharma
#92 interdiff_91-92.txt830 bytes_utsavsharma
#91 views-render_caching_ajax_requests-2500313-89.patch15.19 KBmichelle
#87 2500313-87.patch15.13 KBsupreetam09
#85 2500313-85.patch15.27 KBsupreetam09
#82 views-render_caching_ajax_requests-2500313-81.patch15.56 KBmelvinlouwerse
#80 views-render_caching_ajax_requests-2500313-80.patch15.46 KBmr.york
#80 interdiff-79-80.txt810 bytesmr.york
#78 interdiff-2500313-75-78.txt3.79 KBhuzooka
#78 core-views_render_caching_ajax-2500313-78.patch14.67 KBhuzooka
#75 views-render_caching_ajax_requests-2500313-75.patch14.7 KBmr.york
#74 views-render_caching_ajax_requests-2500313-74-91x.patch14.7 KBmr.york
#74 interdiff-72-74.txt3.12 KBmr.york
#72 interdiff_70-72.txt2.62 KBmr.york
#72 views-render_caching_ajax_requests-2500313-72-92x.patch13.9 KBmr.york
#72 views-render_caching_ajax_requests-2500313-72-91x.patch13.9 KBmr.york
#70 interdiff_68_70.txt2.03 KBanmolgoyal74
#70 views-render_caching_ajax_requests-2500313-70-92x.patch11.28 KBanmolgoyal74
#70 views-render_caching_ajax_requests-2500313-70-89x.patch12.63 KBanmolgoyal74
#68 views-render_caching_ajax_requests-2500313-68-92x.patch14.06 KBmr.york
#67 views-render_caching_ajax_requests-2500313-67-92x.patch13.92 KBmr.york
#67 interdiff_62-67.txt3.94 KBmr.york
#63 views-render_caching_ajax_requests-2500313-63-89x.patch12.66 KBarunthampiklm
#62 views-render_caching_ajax_requests-2500313-62-90x.patch12.49 KBolivier.br
#61 views-render_caching_ajax_requests-2500313-60-90x.patch11.85 KBolivier.br
#59 views-render_caching_ajax_requests-2500313-59-88x.patch12.07 KBpdenooijer
#59 interdiff_58-59.txt3.35 KBpdenooijer
#58 views-render_caching_ajax_requests-2500313-58-88x.patch12.96 KBpdenooijer
#58 interdiff_54-58.txt512 bytespdenooijer
#54 views-render_caching_ajax_requests-2500313-54-88x.patch12.62 KBpdenooijer
#54 interdiff_49-54.txt2.05 KBpdenooijer
#49 views-render_caching_ajax_requests-2500313-49-87x.patch12.41 KBpiyuesh23
#44 views-render_caching_ajax_requests-2500313-44-85x.patch12.74 KBmerauluka
#42 views-render_caching_ajax_requests-2500313-42-85x.patch12.85 KBmerauluka
#39 add_views_render-2500313-39.patch12.95 KBmerauluka
#36 interdiff-83x_2-3.txt748 bytesnikunjkotecha
#36 2500313--views-get-paging-support-83x-3.patch13.04 KBnikunjkotecha
#5 2500313--views-get-paging-support.patch7.09 KBdpolant
#7 2500313--views-get-paging-support-1.patch7.6 KBdpolant
#11 2500313--views-get-paging-support-2.patch12.85 KBdpolant
#21 2500313--views-get-paging-support-83x.patch12.75 KBdpolant
#24 2500313--views-get-paging-support-83x-1.patch12.75 KBdpolant
#35 2500313--views-get-paging-support-83x-2.patch12.78 KBpetermallett
#33 add_views_render-2500313-33.patch12.99 KBedurenye

Comments

wim leers’s picture

Issue tags: +D8 cacheability
wim leers’s picture

mgifford’s picture

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dpolant’s picture

Status: Postponed » Needs review
StatusFileSize
new7.09 KB

I have a first pass at this ready. It depends on the patch from https://www.drupal.org/node/956186#comment-11498819.

Here's what I did:

1) Made a SqlBase pager setting that lets you choose GET or POST.
2) Fixed ViewAjaxController so that it gets query parameters in a way that respects request method.
3) Changed the way that it renders the view so that render caching works.

Let me know what you think. This should work on 8.1 stable if you get the 8.1.8 version of the patch from that other core issue.

Status: Needs review » Needs work

The last submitted patch, 5: 2500313--views-get-paging-support.patch, failed testing.

dpolant’s picture

Status: Needs work » Needs review
StatusFileSize
new7.6 KB

I'm going to need to look at some of those tests. We probably need to wait until https://www.drupal.org/node/956186 is committed to get past some of the AJAX paging related ones, but here is a diff that should fix the schema errors.

Status: Needs review » Needs work

The last submitted patch, 7: 2500313--views-get-paging-support-1.patch, failed testing.

dpolant’s picture

I'm very interested in getting these tests to pass. Can anyone point me in the right direction for how to move forward with this?

I've gotten to the point where it's failing because the $view->display_handler is empty in ViewAjaxController::ajaxView. I'm thinking this has something to do with the mock view not being built correctly under the new conditions.

Anyone have a guess about this, or some advice?

dpolant’s picture

Actually I figured it out. I needed to a) set the query params in a different way for GET and b) set up a mock expectation for buildRenderable instead of preview. It will take a bit more legwork but I should have these tests passing soon ...

dpolant’s picture

Status: Needs work » Needs review
StatusFileSize
new12.85 KB

All tests should be green now. I added separate tests for paging via post vs. via get.

dawehner’s picture

Nice work @dpolant!

dawehner’s picture

I'm a bit confused how this patch is related to the title of this issue. You seemed to have done something different :)

dpolant’s picture

You're right. Here's a summary of what I did:

1) Added render caching to ajax views
2) Added support for GET requests for ajax views
3) Added tests

dawehner’s picture

Title: Add test coverage for views render caching on views ajax requests. » Add views render caching on views ajax requests.

I think this title is more fair then :)

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

damienmckenna’s picture

How testable is this with our current testing suite? Could one of the VDC maintainers please chime in to clarify what sort of tests they would like to see? Thanks.

dawehner’s picture

Well, similar to the way how we test REST requests we could also tests those views ajax requests. Sending the right response and ensure the right headers are send.

shrop’s picture

@dpolant: Do you have any manual testing instructions?

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dpolant’s picture

StatusFileSize
new12.75 KB

Re-rolled against 8.3x

Status: Needs review » Needs work

The last submitted patch, 21: 2500313--views-get-paging-support-83x.patch, failed testing.

dpolant’s picture

Issue summary: View changes
dpolant’s picture

Status: Needs work » Needs review
StatusFileSize
new12.75 KB

Fixed JS coding standards error.

dpolant’s picture

Issue summary: View changes
dpolant’s picture

Issue summary: View changes
dpolant’s picture

Issue summary: View changes
dpolant’s picture

Do we need more tests for this? See Drupal\Tests\views\Unit\Controller\testAjaxViewWithPager - this will now test the page endpoint as a GET request and it is pass.

dpolant’s picture

Issue summary: View changes
dpolant’s picture

Issue summary: View changes
dpolant’s picture

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

edurenye’s picture

StatusFileSize
new12.99 KB

Rerolled.

Status: Needs review » Needs work

The last submitted patch, 33: add_views_render-2500313-33.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

petermallett’s picture

StatusFileSize
new12.78 KB

There's already a patch for 8.4.x, but I still needed one for 8.3.x as of 8.3.7 & figured someone else might, as well; so here's the patch from #24 re-rolled for 8.3.7.

nikunjkotecha’s picture

I used the patch and still was not able to see the headers properly set, I then checked the module ajax_cached_get but no luck, I than checked the differences in use of CacheableResponseTrait and it seemed that all the conditions were failing as response object was not instance of CacheableResponseInterface.

Updated the patch, now ViewAjaxResponse implements CacheableResponseInterface and CacheableResponseTrait was already used. Confirmed for my case the headers are properly set now.

Patch is only for 8.3.x as of now and once I confirm it on Acquia cloud I will work on 8.4.x

nikunjkotecha’s picture

And now I've run into real issues, ViewExecutable->unserialize requires \Drupal::request() which is null as Drupal is trying to render from cache

Bottom line - don't use my patch till further notice.

nikunjkotecha’s picture

merauluka’s picture

Status: Needs work » Needs review
StatusFileSize
new12.95 KB

After updating to 8.4.2, the patch from 33 no longer appears to apply cleanly due to a small code change in core. This is a reroll of 33 against 8.4.2.

Status: Needs review » Needs work

The last submitted patch, 39: add_views_render-2500313-39.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

merauluka’s picture

Status: Needs work » Needs review
StatusFileSize
new12.85 KB

Here is a new re-roll of the patch for 8.5.x.

Status: Needs review » Needs work
merauluka’s picture

Status: Needs work » Needs review
StatusFileSize
new12.74 KB

And I made the patch against the wrong directory. Attaching a new patch and trying against with automated testing.

Status: Needs review » Needs work

The last submitted patch, 44: views-render_caching_ajax_requests-2500313-44-85x.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

wim leers’s picture

Thanks for pushing this forward again, @merauluka! 👌 Hopefully Views maintainers can soon review this :)

dawehner’s picture

+++ b/core/modules/views/views.module
@@ -66,6 +66,7 @@ function views_views_pre_render($view) {
+          'pager_query_method' => !empty($view->pager->options['query_type']) ? $view->pager->options['query_type'] : 'POST',

I'm a bit confused about this one. Why do we have a pager specific method even there are other places where one could do ajax requests with views, like exposed filters.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

piyuesh23’s picture

We have been using this patch on a Project since past few Drupal 8 releases & while upgrading to 8.7, it failed to apply. Re-rolled this patch for 8.7.x. Attaching patch file here.

finne’s picture

+ for #47:
I would love to use cached views ajax reloads on a facets filter or exposed filter. What was the reason to only do this for paging?

malcolm_p’s picture

I also feel that #47 is an important consideration. Getting exposed filters using GET for Ajax is critical for performance.

hkirsman’s picture

+1 for this getting this on exposed filters!

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

pdenooijer’s picture

Status: Needs work » Needs review
StatusFileSize
new2.05 KB
new12.62 KB

Applied the patch from #49 with 3 way merge and update the code a bit:

  • Add CacheableResponseInterface so the response can be cached by the dynamic page cache
  • Improve the getParam by using isMethod on the request object
  • SqlBase is update after 3 way merge

Status: Needs review » Needs work

The last submitted patch, 54: views-render_caching_ajax_requests-2500313-54-88x.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

luksak’s picture

I tested this on 8.8.5 with the latest patch and the patch mentioned in the IS from #956186: Allow AJAX to use GET requests. The first uncached ajax request works, but the next cached request throws this error:

Error: Call to a member function get() on null in Drupal\views\Plugin\views\display\DisplayPluginBase->getHandlers() (line 860 of /web/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php)

pdenooijer’s picture

@Lukas von Blarer, I had the same error. Currently working on a new patch that will fix this issue. Serializing the view is the problem, if that is not serialized the caching will work as expected.

pdenooijer’s picture

StatusFileSize
new512 bytes
new12.96 KB

Updated previous patch to solve the serialization problem when caching the response.

Tests still need work, I think they should be extended to test both GET & POST requests.

pdenooijer’s picture

StatusFileSize
new3.35 KB
new12.07 KB

The serialisation of the ViewExecutable is quite broken, so for now just don't cache it.

Updated to be inline with the other patch in the mentioned issue.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

olivier.br’s picture

patch rerol for drupal 9.0

olivier.br’s picture

It works for pager but not for exposed filters.
I agree with #50, seems weird to have caching enabled when using pagination but not when using an exposed filter.

Here is a new patch that use the setting in pagination also for exposed filters. Maybe this request type setting should be in the display settings and not in the pagination settings.

arunthampiklm’s picture

This patch will fix the issue on exposed filter in 8.x

avpaderno’s picture

Status: Needs work » Needs review

The last submitted patch, 62: views-render_caching_ajax_requests-2500313-62-90x.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 63: views-render_caching_ajax_requests-2500313-63-89x.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mr.york’s picture

Status: Needs work » Needs review
StatusFileSize
new3.94 KB
new13.92 KB

Reroll #62 patch and try fix tests.

mr.york’s picture

Fixed typo in patch.

avpaderno’s picture

Status: Needs review » Needs work
anmolgoyal74’s picture

Status: Needs work » Needs review
StatusFileSize
new12.63 KB
new11.28 KB
new2.03 KB

Re-rolled for 8.9.x
and fixed CS issues in 9.2.x

Status: Needs review » Needs work
mr.york’s picture

Version: 8.9.x-dev » 9.1.x-dev
Status: Needs work » Needs review
StatusFileSize
new13.9 KB
new13.9 KB
new2.62 KB

Add missing JS code.

avpaderno’s picture

Status: Needs review » Needs work
mr.york’s picture

Status: Needs work » Needs review
StatusFileSize
new3.12 KB
new14.7 KB

Fixed JS codes.

mr.york’s picture

Reroll.

huzooka’s picture

Status: Needs review » Needs work

JS coding standard.

huzooka’s picture

Assigned: Unassigned » huzooka
huzooka’s picture

Assigned: huzooka » Unassigned
Status: Needs work » Needs review
StatusFileSize
new14.67 KB
new3.79 KB

Status: Needs review » Needs work

The last submitted patch, 78: core-views_render_caching_ajax-2500313-78.patch, failed testing. View results

mr.york’s picture

Status: Needs work » Needs review
StatusFileSize
new810 bytes
new15.46 KB

Change media test.

Version: 9.1.x-dev » 9.3.x-dev

Drupal 9.1.10 (June 4, 2021) and Drupal 9.2.10 (November 24, 2021) were the last bugfix releases of those minor version series. Drupal 9 bug reports should be targeted for the 9.3.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

melvinlouwerse’s picture

reroll

avpaderno’s picture

Title: Add views render caching on views ajax requests. » Add views render caching on views ajax requests
Status: Needs review » Needs work

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

supreetam09’s picture

Status: Needs work » Needs review
StatusFileSize
new15.27 KB

Rerolling..
Can't seem to generate the interdiff as its throwing error interdiff: Whitespace damage detected in input

avpaderno’s picture

Status: Needs review » Needs work
supreetam09’s picture

Status: Needs work » Needs review
StatusFileSize
new15.13 KB

Adding new patch for custom commands failure.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

uber_denis’s picture

I just ported the code of #87 to make it work with 9.5.x branch.

_utsavsharma’s picture

StatusFileSize
new1.97 KB
new15.18 KB

Fixed CCF for #89.

michelle’s picture

Status: Needs review » Needs work
StatusFileSize
new15.19 KB

I've re-rolled this to work with 9.5.1. It wasn't applying due to changes from "will()" to "willReturn()". I fixed the conflicts manually. I have not yet tested the patch aside from seeing that it applies.

I'm going to keep this at needs work because core patches should be going against D10, now, but the client needs it for D9 so that's what I did. If I can, I'll see if I can circle back and get it to D10.

_utsavsharma’s picture

StatusFileSize
new830 bytes
new15.18 KB

Fixed CCF for #91.

avpaderno’s picture

Status: Needs work » Needs review
avpaderno’s picture

Status: Needs review » Needs work

(I apologize: The status change was wrong.)

catch’s picture

Status: Needs work » Postponed
wim leers’s picture

Status: Postponed » Needs work

Unblocked!

catch’s picture

I think we actually don't need to do this any more - #956186: Allow AJAX to use GET requests already converted Views (without configuration) since it was the main (only) use-case for non-form AJAX in core, so Views is using GET for pagers etc. in Drupal 10.1 already.

wim leers’s picture

It's using GET AJAX requests indeed, but the scope of this issue seems to also stress the need to add render caching in that situation. But perhaps that's already happening? 😄

(I could investigate/verify that too but it's been ages since I've looked at Views' render pipeline, it'd probably take you only a few dozen seconds to check? 🤓😅)

If that's already happening too, then I definitely agree this can be closed (as a duplicate?).

catch’s picture

Status: Needs work » Closed (outdated)

Views render caching is just normal render caching now, that's why this issue was opened in the first place!

Drupal 7: Views has its own HTML caching pipeline, which works on POST requests, but doesn't handle any of the things Drupal 8+ render caching does like cache tags etc.

Drupal 8+: Views uses core render caching, which is great for normal GET requests, but skips caching on POST requests.

Drupal 10.1: cache cache cache cache cache cache!

Closing as outdated.