Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
As loading a display plugin is pretty heavy and some views have a lot of views we should make the display plugin
lazy-loading.
What does this mean:
* Replace $view->displayHandlers with an arrayAccess object, so if anything is accessing the data we will load the plugin, initialize
and no other code has to be changed.
Comment | File | Size | Author |
---|---|---|---|
#88 | views-1817582-88.patch | 7.63 KB | dawehner |
#84 | no-patch.png | 36.1 KB | Kars-T |
#84 | patch.png | 7.22 KB | Kars-T |
#84 | vdc.tar_.gz | 155.78 KB | Kars-T |
#81 | vdc-1817582-81.patch | 16.52 KB | tim.plunkett |
Comments
Comment #1
tim.plunkett+1
Comment #2
dawehnerLet's see what the testbot tells us.
Comment #3
dawehnerI'm wondering whether we actually could backport this change.
Comment #5
dawehnerThis one should be better :)
Comment #7
tim.plunkettIt doesn't make sense to me that initializeDisplay has a return value.
Then initializeDisplay() could also be simplified.
Comment #8
dawehnerSo this fixes many issues.
Comment #10
dawehnerNow finally.
Comment #12
tim.plunkettThis is what I had in mind.
Comment #13
dawehnerOh i like those changes.
The drop is always moving.
So i think we should initialize the default display in the constructor.
Comment #14
damiankloip CreditAttribution: damiankloip commentedYESSSSS!
Would it be better if this was $displays or $display_storage or something instead?
Does this make you think of static properties?
Would be nice if there was a nicer way to get this stuff. Not really a part of this issue though :)
next()
Comment #15
catchThis looks great!
Comment #16
dawehnerThanks for the review!
Here is a rerole which fixes the stuff mentioned above.
Comment #17
damiankloip CreditAttribution: damiankloip commentedLooks great, I guess this will pass but you never know... :)
Comment #19
dawehner#16: views-1817582-16.patch queued for re-testing.
Comment #21
tim.plunkett$this->$displayHandlers has an extra $
Comment #22
damiankloip CreditAttribution: damiankloip commentedJust to be clear; I only removed a '$' character.
Comment #24
tim.plunkettThese are all still the old variable
This looks weird. Wouldn't you just need to do
return key($this->displayHandlers) !== NULL;
Comment #25
damiankloip CreditAttribution: damiankloip commentedA few other instances of $this->display weren't changed.
Comment #26
catchOK one question though:
When views is figuring out the display for a view, it iterates over the displays until one passes an access check, then returns from within the foreach() - that seems like one of the main places that'd benefit from his but initializing all displays won't help with it.
Comment #27
damiankloip CreditAttribution: damiankloip commentedWe talked about this briefly on IRC; It's a good point. One idea is to store a list of the displays on the class, maybe in the conststructor so we don't have to get them from $this->view->storage->display each time. Not sure if that's a good trade off or not?
Something like :
Just an idea.
Comment #28
dawehnerOkay implemented the idea mentioned by damian.
Additional i corrected the implementation of valid(), do you think this is okay now?
Comment #29
tim.plunkettThis is broken copy/paste?
return ($display_id !== NULL && $display_id !== FALSE);
Comment #31
dawehnerOH!
Thank you! It is amazing that this issue already has 31 comments.
Comment #33
damiankloip CreditAttribution: damiankloip commentedWont !empty() give you the same result? empty will evaluate TRUE for both NULL and FALSE.
Comment #34
dawehnerWell actually $display_id should be named $key here, so it might be 0, which is a reference to 'default', so it's for sure valid.
Comment #36
dawehnerLet's see whether the tests are running now.
Comment #38
damiankloip CreditAttribution: damiankloip commentedreturn isset($this->displayHandlers[$offset]) || in_array($offset, $this->displayIDs);
Instead?count($this->displayIDs) ?
Comment #39
dawehnerThanks for that additions, i implemented it slightly different, so we don't have to in_array but just use isset().
Comment #40
dawehnerForgot the interdiff
Comment #42
dawehnerThe rewind() has been wrong.
Comment #43
damiankloip CreditAttribution: damiankloip commentedChange this back, and this is RTBC.
Comment #44
dawehnerJust remove some temporary variables.
Comment #45
damiankloip CreditAttribution: damiankloip commentedThis looks pretty awesome now.
Comment #46
xjm#44: drpal-1817582-43.patch queued for re-testing.
Comment #48
damiankloip CreditAttribution: damiankloip commentedRerolled after #1763974: Convert entity type info into plugins
Comment #49
catchIt'd be good to profile this before it goes in on a view with say 5 or 10 displays, to see how much difference it actually makes.
Comment #50
xjm@catch We are actually in the process of doing that already. :)
Comment #51
Kars-T CreditAttribution: Kars-T commentedHi
I did benchmark this a lot of times with different settings. The point is there is no real difference. The lazy loading script might be a bit slower. For the test I created a view with > 20 displays that use 14 fields. Than I profiled the call of views_get_view_result(). dawehner told me that we should get a real view that is known for having performance problem. Otherwise I can't show any performance problem or gain.
Comment #52
dawehnerSo one problem why we don't see any benefit is that all displays are allowed to attach additional information to existing displays.
This is primarily used at the moment to show the feed icon on a page display.
To be able to do this, we have a foreach loop and so we have lost: http://drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/modul...
Comment #53
tim.plunkettRemoving from RTBC until we improve it.
Comment #54
dawehnerThe question is whether we should do it here or in another issue, as this issue is just about actually lazy loading display plugins.
One idea we came up with is to store the displays which want to attach to an existing one.
Comment #55
dawehnerThis patch actually changes the logic and not initializes all the displays all the time by introducing an helper function.
This one also got a patch.
Comment #57
dawehnerThat's blocked on the fixes of #1829822: Write a test which tests the UI for all of the handlers
Comment #58
dawehnerFor some reasons this contains a hunk from #1810816: Link options for displayPluginBase is still using the display on the storage.
Comment #60
dawehnerRerolled against the UI changes.
Comment #62
damiankloip CreditAttribution: damiankloip commentedJust fixed the fatal from DisplayPluginBase.
Comment #64
dawehnerOne current problem of the patch is that now that we have getters/setters, we don't have $display as reference anymore, so
the value on the storage points to another location then on the actual display instance.
Comment #65
dawehnerOh there is getDisplay nice! Patch, please apply!
Comment #67
dawehner#65: durpal-1817582-65.patch queued for re-testing.
Comment #68
damiankloip CreditAttribution: damiankloip commentedI think this is perilously close now ...
Maybe 'If the display was initialized before, just return.'?
It's always slightly annoying that we have to declare by reference on the method itself and the call to it, but hey, that's php :)
Is there any sense in checking we have a display before continuing here? Not sure.
The doc still says we are returning a reference. Hang on, why do we want to change this again? :)
The attached display change looks good too, I think that is the only way we can do this without actually loading displays.
Comment #69
dawehnerPerfect.
Why not ... let's use the strategy to use a default display plugin so it doesn't break completly.
Updated the doc ... well the thing is, it's an object so you just don't have to specify whether to return a reference or not.
Comment #70
dawehnerUpdate
Comment #71
dawehnerSynced the @return between the two newDisplay methods.
Comment #73
damiankloip CreditAttribution: damiankloip commented#71: drupal-1817582-71.patch queued for re-testing.
Comment #75
dawehnerReroll the patch.
Comment #76
Jelle_SHad a quick glance over the patch... I think the file containing the DisplayArray class is not included. Testbot will probably confirm, unless I totally missed something :-)
Comment #78
dawehnerOh you are absolute right, thank you!
used patch -p1 for the rerole, and failed to readd the file.
Comment #79
damiankloip CreditAttribution: damiankloip commentedThis looks good now, the attach code and tests look fine too.
Comment #80
catchLooks like there hasn't been profiling since #51, could we do that again to see the impact on a view with a few displays?
Comment #81
tim.plunkettThat's a good idea.
Also, rerolled.
Comment #82
dawehnerDo you know why exactly this new patch got 500 byte bigger?
Comment #83
tim.plunkettYes, this did it mostly.
And this
Comment #84
Kars-T CreditAttribution: Kars-T commentedIt is hard to create a view that really shows any difference to get some numbers. I created a really big view with many displays. And if you load it uncached you can find this:
With the patch added an uncached load shows only this:
I'd say it works and only loads the one needed display.
In the .gz you can find the view_from_hell.yml and the xhprof results from the runs.
+1 for the patch.
Comment #85
dawehnerThank you for the profiling!
Comment #86
catchOK that's great. Committed/pushed to 8.x.
Wondering if this could ever be backported to 7.x-3.x, but marking 'fixed' for now.
Comment #87
dawehnerLet's see, would be for sure interesting and maybe worth in terms of performance.
Comment #88
dawehnerI really fear it will be impossible to backport this patch without breaking stuff.
But yeah here is a try which fails in many cases like the actual page :)
Comment #89
johnvI'm happy to test this with my 10-display view.
Comment #90
johnvBack to original status after triggering testbot.
Comment #91
xjmNW would be the correct status now that there's a start at a patch. :)
Comment #92
dawehnerEven if this would be a real start, let's set it to the other status, so it's easier to find.
Comment #93
xjmOkay, different rules from core then. ;)
Comment #94
killua99 CreditAttribution: killua99 commentedHi,
I'm not 100% sure if this fatal error I have it's related with this issue, but I find this issue cause the qa drupal test. In the test it have the same fatal error.
Fatal error: Call to a member function ensure_my_table() on a non-object in /var/lib/drupaltestbot/sites/default/files/checkout/sites/default/modules/views/handlers/views_handler_filter_combine.inc on line 60
I get this fatal error when I have an exposed filter with combined fields. I'm trying to figure out what cause this error, but it's hard to find.
Comment #95
johnvI tried to implement and test this patch on D7. I keep getting "reference to non-object" errors.
In the end, I have the following additions to patch #88
The variable handle_inited must be reset, too.
The check must be inversed.
Added the 'return FALSE' line.
Also, function fix_missing_relationships() seems to load all handlers and objects. It is already called when building the menu, not when building the page itself.
Comment #96
boreg CreditAttribution: boreg commented88: views-1817582-88.patch queued for re-testing.
Comment #99
Chris CharltonIs this abandoned? Or just dormant?