[5.x]: Closing an element selector modal while it loads makes it load every element in the background
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 1/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- javascript, php
- 領域
- backend, frontend, performance
調査の方向性
Start in src/web/assets/cp/src/js/BaseElementIndexView.js and trace canLoadMore() and the maybeLoadMore() callbacks after requests complete. Reproduce by closing an element selector modal while its first batch is loading, then check the network panel for continued get-more-elements requests. Done means loading stops while the scroller is hidden and resumes when it becomes visible; an open linked pull request indicates work is already underway.
索引モデルが issue の本文から書いたものです。
説明
What happened?
If an element selector modal is closed while its first batch of elements is still loading, the (now hidden) element index view keeps requesting element-indexes/get-more-elements, batch after batch, until the entire source has been loaded.
For an Assets field this renders thumbnails for every asset in the volume, and since thumbnails aren't generated before page load by default, every thumbnail pushes a GenerateImageTransform queue job. On a production site with an ~11k-image volume, a single editor closing the asset modal at the wrong moment caused 114 get-more-elements requests in ~90 seconds and ~22k queued jobs.
Steps to reproduce (fresh Craft 5.11.5.1 install, no plugins, default config):
- Create a volume with a few hundred images (I used 350) and an Assets field for it on an entry type.
- Edit an entry and click Add an asset.
- Press Esc as soon as the modal has faded in, before the first batch of assets has rendered (i.e. while
actions/element-selector-modals/bodyor the firstactions/element-indexes/get-elementsrequest is in flight). - Watch the network panel and the
queuetable.
Expected: no more requests after the modal is closed; the queue contains jobs for the first batch only (200 for 100 assets).
Actual: get-more-elements fires until the whole source is loaded (3 requests for 350 assets), and the queue contains 700 GenerateImageTransform jobs.
| Scenario (fresh install, 350 assets) | get-more-elements |
Assets loaded | Queued jobs |
|---|---|---|---|
| Modal open 30 s, no scrolling | 0 | 100 | 200 |
Esc right after element-selector-modals/body is sent |
3 | 350 | 700 |
Esc while the first get-elements is in flight |
3 | 350 | 700 |
| Esc after the first batch has rendered | 0 | 100 | 200 |
Cause
In src/web/assets/cp/src/js/BaseElementIndexView.js:
- Element selector modals aren't paginated, so the view calls
maybeLoadMore()right after it's created and again after every completed batch (// Is there room to load more right now?). - For a non-window scroller,
canLoadMore()checkscontainerScrollHeight - containerScrollTop <= containerHeight + 15. Once the modal is hidden (display: none) all three values are0, so the check is always true. Verified in the console after closing:scrollHeight0,scrollTop()0,outerHeight()0,canLoadMore()→true. - Closing the modal doesn't destroy the element index, and the callback of an in-flight request still calls
maybeLoadMore().
Returning false from canLoadMore() when a non-window scroller isn't visible fixes it; loading resumes normally (on scroll) when the modal is reopened:
if (this.$scroller[0] !== Garnish.$win[0] && !this.$scroller.is(':visible')) {
return false;
}
Craft CMS version
5.11.5.1 (also seen on 5.11.1)
PHP version
8.3
Operating system and version
macOS (local repro), Linux (production)
Database type and version
MySQL
Image driver and version
Imagick 3.8.1 (ImageMagick 7.1.2) locally; GD in production
Installed plugins and versions
None (fresh install)
- 主要言語
- PHP
- スター
- 3.6k
- フォーク
- 710
- 平均マージ
- 12時間 44分
- マージ済み PR(30日)
- 335
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
craftcms/cms のほかの issue
-
repo:cms
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
craftcms/cms#20235 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug repo:cms
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
craftcms/cms#20205 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug repo:cms
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
craftcms/cms#20203 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[5.x]: Moving an asset with “Replace it” throws TypeError: volumeUid must be of type string, null given対応中かも @i-just が 2 日前に担当しました。 オープンbug repo:cms
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
craftcms/cms#20128 · コメント 2 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
repo:cms
難易度 3/5 1〜2日 初心者へのやさしさ 72/100
craftcms/cms#20234 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
0. Needs triage bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
nextcloud/fulltextsearch#1061 ·
メンテナーはふだん 1 日以内に返信
-
resource-submission validation-passed
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
hesreallyhim/awesome-claude-code#3375 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信