Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Ensure filter blocks are not reloaded every time they are selected in the editor #8002

Merged
merged 11 commits into from
Jan 1, 2023

Conversation

nefeline
Copy link
Contributor

@nefeline nefeline commented Dec 21, 2022

Fixes #7676

This update ensures the filter components are not reloaded every time they are selected in the editor.

Why was this problem happening in the first place?

On the useCollectionData hook, we are debouncing shouldSelect to delay data collection requests on the initial mount for 200ms. By reading the original PR where it was introduced, #1233, this was added to prevent multiple collection data requests, which makes total sense.

The problem here is when shouldSelect is false, the useCollection hook returns null. In the editor, whenever we click on a component, it is re-rendered. Since the initial request is debounced (with shouldSelect being false by default), we always end up fetching again from the store.

To circumvent this, the isEditor and isSelected props are now passed to the useCollectionData and useCollection hooks as params. If we are in the editor, shouldSelect is set to true by default. This way, we will always fetch the latest data when the editor page is initially loaded.

When a given block is selected in the editor, we now return the same data from the initial request (from currentResults) instead of fetching from the store again on re-render. This change only affects the editor, where the components are disabled by default.

Screenshots

Before After

User Facing Testing

  1. Create a new post, add the following blocks: Filter by rating, filter by stock, filter by attribute, filter by price, Products (Beta), and publish it.
  2. Access the post as a regular customer would. Ensure nothing has changed, and all filters are working as expected.
  3. Now edit the post: ensure all components are normally loaded in the editor. When you click on them, ensure that you see the same behavior as demonstrated on this gif shared earlier on this PR (no preloaders should be displayed).

WooCommerce Visibility

  • WooCommerce Core
  • Feature plugin
  • Experimental

Performance Impact

We have some improvements in performance here, since, now, in the editor, we are only fetching data from the store on the initial render, relying on the currentResults whenever the component is selected.

Changelog

The filter by attribute, price, rating, and stock blocks are not reloaded when selected in the editor anymore.

@nefeline nefeline added block: filter by price Issues related to the Filter by Price block. block: filter by attribute Issues related to the Filter by Attribute block. block: filter by stock Issues related to the Filter by Stock block. block: filter by rating Issues related to the Filter by Rating block. labels Dec 21, 2022
@woocommercebot woocommercebot requested review from a team and danielwrobert and removed request for a team December 21, 2022 13:23
@github-actions
Copy link
Contributor

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-8002.zip

@github-actions
Copy link
Contributor

github-actions bot commented Dec 21, 2022

TypeScript Errors Report

Files with errors: 436
Total errors: 2079

⚠️ ⚠️ This PR introduces new TS errors on 2 files:

assets/js/base/context/hooks/collections/use-collection.ts

assets/js/blocks/rating-filter/test/block.tsx

@github-actions
Copy link
Contributor

github-actions bot commented Dec 21, 2022

Size Change: -543 B (0%)

Total Size: 1.01 MB

Filename Size Change
build/active-filters-frontend.js 7.8 kB +59 B (+1%)
build/active-filters-wrapper-frontend.js 6.07 kB +57 B (+1%)
build/active-filters.js 7.38 kB +59 B (+1%)
build/all-products-frontend.js 11.4 kB +145 B (+1%)
build/all-products.js 33.5 kB +62 B (0%)
build/attribute-filter-frontend.js 22.8 kB +71 B (0%)
build/attribute-filter-wrapper-frontend.js 5.07 kB -2.6 kB (-34%) 🎉
build/attribute-filter.js 12.4 kB +64 B (+1%)
build/blocks-checkout.js 39.5 kB -2 B (0%)
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.38 kB +1 B (0%)
build/cart-blocks/cart-cross-sells-products-frontend.js 9.64 kB +6 B (0%)
build/cart-blocks/cart-express-payment--checkout-blocks/express-payment-frontend.js 5.08 kB +1 B (0%)
build/cart-blocks/cart-line-items--mini-cart-contents-block/products-table-frontend.js 5.29 kB +1 B (0%)
build/cart-blocks/cart-line-items-frontend.js 1.07 kB +1 B (0%)
build/cart-blocks/empty-cart-frontend.js 344 B +1 B (0%)
build/cart-blocks/filled-cart-frontend.js 782 B -1 B (0%)
build/cart-blocks/order-summary-heading-frontend.js 456 B +1 B (0%)
build/cart-blocks/order-summary-shipping-frontend.js 14.6 kB +1 B (0%)
build/cart-frontend.js 28.1 kB -4 B (0%)
build/checkout-blocks/actions-frontend.js 1.86 kB -1 B (0%)
build/checkout-blocks/order-summary-discount-frontend.js 2.29 kB +1 B (0%)
build/checkout-blocks/shipping-address-frontend.js 1.11 kB +1 B (0%)
build/checkout-blocks/totals-frontend.js 325 B +1 B (0%)
build/checkout-frontend.js 29.4 kB +7 B (0%)
build/filter-wrapper-frontend.js 13.8 kB +25 B (0%)
build/mini-cart-component-frontend.js 20 kB -6 B (0%)
build/mini-cart-contents-block/products-table-frontend.js 590 B -1 B (0%)
build/price-filter-frontend.js 13.7 kB +66 B (0%)
build/price-filter-wrapper-frontend.js 7.08 kB +67 B (+1%)
build/price-filter.js 8.45 kB +70 B (+1%)
build/product-add-to-cart-frontend.js 6.71 kB -2 B (0%)
build/product-button-frontend.js 2.16 kB +4 B (0%)
build/product-category-list-frontend.js 1.14 kB +2 B (0%)
build/product-image-frontend.js 2.16 kB +7 B (0%)
build/product-rating-frontend.js 1.59 kB +2 B (0%)
build/product-sale-badge-frontend.js 1.39 kB +4 B (0%)
build/product-stock-indicator-frontend.js 1.27 kB +8 B (+1%)
build/product-tag-list-frontend.js 1.14 kB +1 B (0%)
build/rating-filter-frontend.js 21.2 kB +80 B (0%)
build/rating-filter-wrapper-frontend.js 6.26 kB +77 B (+1%)
build/rating-filter.js 7.45 kB +68 B (+1%)
build/single-product-frontend.js 17.3 kB +2 B (0%)
build/stock-filter-frontend.js 20.9 kB +80 B (0%)
build/stock-filter-wrapper-frontend.js 3.16 kB -2.7 kB (-46%) 🎉
build/stock-filter.js 8.19 kB +65 B (+1%)
build/vendors--attribute-filter-wrapper--cart-blocks/cart-cross-sells-products--cart-blocks/order-summary--cde4eab5-frontend.js 6.86 kB -1 B (0%)
build/vendors--attribute-filter-wrapper--rating-filter-wrapper--stock-filter-wrapper-frontend.js 7.7 kB +1 B (0%)
build/vendors--cart-blocks/cart-cross-sells-products--product-add-to-cart-frontend.js 7.53 kB +1 B (0%)
build/wc-blocks-data.js 21.2 kB +5 B (0%)
build/wc-blocks-registry.js 2.92 kB +1 B (0%)
build/wc-blocks-shared-hocs.js 1.88 kB +154 B (+9%) 🔍
build/attribute-filter-wrapper--stock-filter-wrapper-frontend.js 3.44 kB +3.44 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size
build/all-reviews.js 7.65 kB
build/cart-blocks/cart-cross-sells-frontend.js 253 B
build/cart-blocks/cart-express-payment-frontend.js 720 B
build/cart-blocks/cart-items-frontend.js 299 B
build/cart-blocks/cart-order-summary-frontend.js 1.25 kB
build/cart-blocks/cart-totals-frontend.js 322 B
build/cart-blocks/order-summary-coupon-form-frontend.js 1.78 kB
build/cart-blocks/order-summary-discount-frontend.js 2.13 kB
build/cart-blocks/order-summary-fee-frontend.js 273 B
build/cart-blocks/order-summary-subtotal-frontend.js 273 B
build/cart-blocks/order-summary-taxes-frontend.js 436 B
build/cart-blocks/proceed-to-checkout-frontend.js 1.24 kB
build/cart.js 46.9 kB
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 3.86 kB
build/checkout-blocks/billing-address-frontend.js 1.12 kB
build/checkout-blocks/contact-information-frontend.js 2 kB
build/checkout-blocks/express-payment-frontend.js 1.14 kB
build/checkout-blocks/fields-frontend.js 343 B
build/checkout-blocks/order-note-frontend.js 1.14 kB
build/checkout-blocks/order-summary-cart-items-frontend.js 3.67 kB
build/checkout-blocks/order-summary-coupon-form-frontend.js 1.93 kB
build/checkout-blocks/order-summary-fee-frontend.js 275 B
build/checkout-blocks/order-summary-frontend.js 1.25 kB
build/checkout-blocks/order-summary-shipping-frontend.js 14.6 kB
build/checkout-blocks/order-summary-subtotal-frontend.js 273 B
build/checkout-blocks/order-summary-taxes-frontend.js 436 B
build/checkout-blocks/payment-frontend.js 8.34 kB
build/checkout-blocks/shipping-methods-frontend.js 4.57 kB
build/checkout-blocks/terms-frontend.js 1.56 kB
build/checkout.js 40.9 kB
build/customer-account.js 3.08 kB
build/featured-category.js 13.1 kB
build/featured-product.js 13.3 kB
build/filter-wrapper.js 2.4 kB
build/general-style-rtl.css 1.29 kB
build/general-style.css 1.29 kB
build/handpicked-products.js 7.22 kB
build/legacy-template.js 2.85 kB
build/mini-cart-contents-block/empty-cart-frontend.js 366 B
build/mini-cart-contents-block/filled-cart-frontend.js 388 B
build/mini-cart-contents-block/footer-frontend.js 2.81 kB
build/mini-cart-contents-block/items-frontend.js 237 B
build/mini-cart-contents-block/shopping-button-frontend.js 313 B
build/mini-cart-contents-block/title-frontend.js 368 B
build/mini-cart-contents.js 16.7 kB
build/mini-cart-frontend.js 1.88 kB
build/mini-cart.js 4.26 kB
build/price-format.js 1.19 kB
build/product-add-to-cart--product-button--product-category-list--product-image--product-price--product-r--a0326d00.js 226 B
build/product-add-to-cart--product-button--product-image--product-rating--product-title.js 151 B
build/product-add-to-cart.js 8.48 kB
build/product-best-sellers.js 7.58 kB
build/product-button--product-category-list--product-image--product-price--product-rating--product-sale-b--e17c7c01.js 443 B
build/product-button--product-image--product-rating--product-sale-badge--product-title.js 302 B
build/product-button.js 3.84 kB
build/product-categories.js 2.36 kB
build/product-category-list.js 502 B
build/product-category.js 8.57 kB
build/product-image.js 3.93 kB
build/product-new.js 7.57 kB
build/product-on-sale.js 7.89 kB
build/product-price-frontend.js 2.18 kB
build/product-price.js 1.54 kB
build/product-query.js 5.88 kB
build/product-rating.js 919 B
build/product-sale-badge.js 814 B
build/product-search.js 2.62 kB
build/product-sku-frontend.js 629 B
build/product-sku.js 377 B
build/product-stock-indicator.js 645 B
build/product-summary-frontend.js 1.53 kB
build/product-summary.js 919 B
build/product-tag-list.js 497 B
build/product-tag.js 8.06 kB
build/product-title-frontend.js 1.59 kB
build/product-title.js 3.31 kB
build/product-top-rated.js 7.81 kB
build/products-by-attribute.js 8.5 kB
build/reviews-by-category.js 11.2 kB
build/reviews-by-product.js 12.3 kB
build/reviews-frontend.js 6.88 kB
build/single-product.js 9.96 kB
build/vendors--cart-blocks/cart-cross-sells-products--cart-blocks/cart-line-items--cart-blocks/cart-order--671ca56f-frontend.js 5.26 kB
build/vendors--cart-blocks/cart-cross-sells-products--cart-blocks/order-summary-shipping--checkout-blocks--18f9376a-frontend.js 19.1 kB
build/vendors--cart-blocks/cart-line-items--checkout-blocks/order-summary-cart-items--mini-cart-contents---233ab542-frontend.js 3.14 kB
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--5b8feb0b-frontend.js 4.82 kB
build/vendors--checkout-blocks/shipping-methods-frontend.js 9.48 kB
build/wc-blocks-editor-style-rtl.css 5.41 kB
build/wc-blocks-editor-style.css 5.41 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 931 B
build/wc-blocks-shared-context.js 1.52 kB
build/wc-blocks-style-rtl.css 24.8 kB
build/wc-blocks-style.css 24.8 kB
build/wc-blocks-vendors-style-rtl.css 1.95 kB
build/wc-blocks-vendors-style.css 1.95 kB
build/wc-blocks-vendors.js 62.7 kB
build/wc-blocks.js 2.63 kB
build/wc-payment-method-bacs.js 816 B
build/wc-payment-method-cheque.js 811 B
build/wc-payment-method-cod.js 909 B
build/wc-payment-method-paypal.js 837 B
build/wc-settings.js 2.6 kB

compressed-size-action

Copy link
Member

@dinhtungdu dinhtungdu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for the PR @nefeline! Great work, I can confirm that the filter block is no longer flashing when clicking on them.

On the useCollectionData hook, we are debouncing shouldSelect to delay data collection requests on the initial mount for 200ms. By reading the original PR where it was introduced, #1233, this was added to prevent multiple collection data requests, which makes total sense.

In testing this, I realize that there are still multiple collections data requests made on the page that contain multiple PR blocks. Should we revisit 1233?

Screenshot image

We're passing isEditor and isSelected to our useCollection* hooks, but as we're making the debouncedShouldSelect not 'debounced' in the editor, I think only passing isEditor is enough, as shouldSelect is now always true in the editor, so the collection hook won't return null anymore. What do you think?

@nefeline
Copy link
Contributor Author

Thank you so much for the PR @nefeline! Great work, I can confirm that the filter block is no longer flashing when clicking on them.

Thanks 🙌 !

In testing this, I realize that there are still multiple collections data requests made on the page that contain multiple PR blocks. Should we revisit 1233?

Yes, I agree there's room for improvements regarding 1233; from my understanding, the debounce was added as a workaround to reduce the number of API requests, due to the absence of a shared context, which makes sense: if we can structure the codebase in a way we know for a fact that x filter components exist on a given post/page and make only one request based on this shared information, that would be the ideal. If we stick with the debounce path, for now, there are other avenues I believe we can explore, such as increasing the debounce value and comparing the currentQuery with the query and returning the currentResult if they are the same as well (open to hearing your thoughts if you have other ideas here!). I'd say this is a bit bigger than the scope of this PR, which targets the editor exclusively and aims to prevent reload when filter components are selected in this area. Perhaps opening a separate PR to address this in the customer-facing area could be a good path to follow next? What do you think?

We're passing isEditor and isSelected to our useCollection* hooks, but as we're making the debouncedShouldSelect not 'debounced' in the editor, I think only passing isEditor is enough, as shouldSelect is now always true in the editor, so the collection hook won't return null anymore. What do you think?

isSelected was added here to be super conservative, as I wanted to isolate the changes to the scope of the selected blocks and not all blocks, but in retrospect, it might make sense to have the same behavior across all filter components in the editor. I'll go ahead & review/update this 👍.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 28, 2022

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-8002.zip

Script Dependencies Report

There is no changed script dependency between this branch and trunk.

This comment was automatically generated by the ./github/compare-assets action.

TypeScript Errors Report

  • Files with errors: 421
  • Total errors: 1917

⚠️ ⚠️ This PR introduces new TS errors on 1 files:

assets/js/blocks/rating-filter/test/block.tsx

comments-aggregator

Copy link
Member

@dinhtungdu dinhtungdu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for the update @nefeline! This is testing great on my end. I left an optional comment but I'm pre-approving this. 🚀

assets/js/base/context/hooks/collections/use-collection.ts Outdated Show resolved Hide resolved
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
block: filter by attribute Issues related to the Filter by Attribute block. block: filter by price Issues related to the Filter by Price block. block: filter by rating Issues related to the Filter by Rating block. block: filter by stock Issues related to the Filter by Stock block. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Filter control blocks in the editor reload every time they are selected
3 participants