Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[StimulusBundle] Improve StimulusAttributes rendering performances by switching to html escaping strategy #2180

Conversation

Kocal
Copy link
Collaborator

@Kocal Kocal commented Sep 18, 2024

Q A
Bug fix? no
New feature? no
Issues Fix #...
License MIT

A better alternative to #2178, by changing the escaping strategy for HTML attributes value from html_attr to html, as indicated by @stof in twigphp/Twig#4322 (comment).

On my use case (a Map with 1000 Marker and InfoWindow), I have a performance gain of ~68%:
image

This PR should also improve performances of our packages using the StimulusAttributes DTO, like Chart.js, LiveComponent, ...


Important

The initial PR changed a bit, the default rendering strategy does not change, but instead we introduce a new configuration to use the new (and optimized) rendering strategy, see #2180 (comment).

@Kocal Kocal force-pushed the imp-stimulus-attributes-rendering-performances branch 3 times, most recently from cd9c74a to 1525a9a Compare September 18, 2024 13:47
@smnandre
Copy link
Collaborator

Do we still need to call the Runtime then ? Would this not be sufficient ?

 return htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);

@Kocal Kocal force-pushed the imp-stimulus-attributes-rendering-performances branch 5 times, most recently from af1c114 to 6c92d01 Compare September 18, 2024 21:03
@Kocal
Copy link
Collaborator Author

Kocal commented Sep 18, 2024

Do we still need to call the Runtime then ? Would this not be sufficient ?

 return htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);

If we assume UTF-8 is used everywhere, yes, but |escape('html') does more than that :/

@smnandre
Copy link
Collaborator

This bundle is the most used / downloaded. So we cannot release a version that will break tests (and maybe code) during a minor...

so we need to find a way out here... what about thinking a new object ? less "stimulus" and more "attributes" ?

Copy link
Collaborator

@WebMamba WebMamba left a comment

Choose a reason for hiding this comment

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

Hey! I am agree with @smnandre here! It's a BC break for me. Maybe we can have a config that allow to switch from html_attr to html ?

@smnandre
Copy link
Collaborator

Sadly, it's difficult, as this class is directly used by other components / bundle.. and it's neither final or internal :|

@Kocal
Copy link
Collaborator Author

Kocal commented Sep 22, 2024

It's a BC for tests/assertions yes, but I don't really see how and where it can impact end users.

However, we can't stay ad vitam aeternam with html_attr escaping for HTML attribute values, as we all see it is not performant at all.

Since StimulusAttributes is not final nor internal, maybe... we can configure the escaping format through a new method?

@kbond
Copy link
Member

kbond commented Sep 22, 2024

New bundle config? Deprecate not setting it to the new, desired value?

@smnandre
Copy link
Collaborator

New bundle config ?

We cannot here, this class may be instanciated directly in many projects, as it is not a service.

Deprecate not setting it to the new, desired value?

This is a good idea. Probably we can add an argument either in the render / toString methods, or maybe more in the constructor..

.. and deprecate no passing it (stating in 3.x it will use the new mode)

?

@smnandre
Copy link
Collaborator

Regarding performances, i'm very very happy you found this bottleneck and have a clean method to improve things.

But as always, we cannot "force it" down, and it's been written everywhere Symfony UX would follow Symfony BC promise.

To be clear, i'm not saying we cannot use these optimisations in the ux components

  • ux map is still experimental, and this is a very legit case of accepted change
  • we did not made any promise/engagement on the attributes generated by live component, and it could 100% be considered internal .. this also work for chartsjs, etc (but should we release a typed bundle version just for this ? i'm not entirely sure here..)

I'm concerned about two things here:

  • the StimulusAttributes class in itself, that can be used elsewhere / tested / etc ... this would be a major BC break, as simple unit test cases would break
  • the StimulusBundle twig functions (stimulus_xxx), that could be configured by the stimulus bundle but i'm not sure this is worth it

@kbond
Copy link
Member

kbond commented Sep 22, 2024

This is a good idea. Probably we can add an argument either in the render / toString methods, or maybe more in the constructor..

.. and deprecate no passing it (stating in 3.x it will use the new mode)

Constructor then, yes.

@Kocal
Copy link
Collaborator Author

Kocal commented Sep 22, 2024

I'm reverting to html_attr escaping strategy by default, then I will add whatever needed to re-use html for escaping html attribute values (without BC breaks)

@Kocal Kocal force-pushed the imp-stimulus-attributes-rendering-performances branch 2 times, most recently from 0ac2cf2 to 736543a Compare September 24, 2024 08:02
@Kocal
Copy link
Collaborator Author

Kocal commented Sep 24, 2024

I've updated the PR and introduced a new config stimulus.use_optimized_attributes_rendering (default to null, which allows me to trigger a deprecation if not explicitly specified):
image
Note: I'll gladly take any comments for my deprecation messages... 😅

This configuration is injected to the StimulusHelper constructor, then injected to the StimulusAttributes constructor.

I've rollbacked tests added in my first commit as it was considered as breaking changes. Instead, I've configured stimulus.use_optimized_attributes_rendering/$useOptimizedRendering to false in order to get rid of deprecation notices (which make tests fails and CI red). I also adapted actual tests to test the new optimized rendering, this way we can clearly see the difference between the actual and new rendering behaviour.

With all those changes, I took a new Blackfire profile on my page with a Map and 1000 Marker/InfoWindow, and did a new comparaison:
image

@Kocal Kocal marked this pull request as ready for review September 24, 2024 08:12
@Kocal Kocal force-pushed the imp-stimulus-attributes-rendering-performances branch from 736543a to 4af2a0e Compare September 24, 2024 08:21
@javiereguiluz
Copy link
Member

@Kocal impressive performance improvement 🤯 thanks a lot 🙇

I still think this is not a true BC break and we shouldn't complicate things with the new config option.

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

I agree with Javier, no need for the option.
We might reconsider if we get enough reports but without, I wouldn't anticipate this aspect.

Copy link
Member

@stof stof left a comment

Choose a reason for hiding this comment

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

I'm still not convinced this should be considered a breaking change. The generated HTML string will be different, but this will not change anything for the output of parsing it.

src/TwigComponent/tests/Fixtures/Kernel.php Outdated Show resolved Hide resolved
@Kocal
Copy link
Collaborator Author

Kocal commented Sep 24, 2024

I agree with all of you, I don't consider it a breaking change either.
The behavior won't change in the browser, users won't be (badly) impacted by this modification.

Let's revert the 2 last commit then, just in case. We will squash the PR at merging.

@Kocal Kocal force-pushed the imp-stimulus-attributes-rendering-performances branch from 77a08ac to 34deb47 Compare September 24, 2024 08:39
@Kocal
Copy link
Collaborator Author

Kocal commented Sep 24, 2024

The PR is now back at its original state, there is no stimulus.use_optimized_attributes_rendering config anymore.

@carsonbot carsonbot added Status: Reviewed Has been reviewed by a maintainer and removed Status: Needs Review Needs to be reviewed labels Sep 24, 2024
@Kocal Kocal force-pushed the imp-stimulus-attributes-rendering-performances branch from b35c2b8 to e3b42f1 Compare September 24, 2024 08:56
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

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

thanks

@javiereguiluz javiereguiluz force-pushed the imp-stimulus-attributes-rendering-performances branch from e3b42f1 to 647532a Compare September 24, 2024 09:28
@javiereguiluz
Copy link
Member

Thank you Hugo.

@javiereguiluz javiereguiluz merged commit 06e026c into symfony:2.x Sep 24, 2024
7 of 8 checks passed
@Kocal Kocal deleted the imp-stimulus-attributes-rendering-performances branch September 24, 2024 09:29
Kocal added a commit that referenced this pull request Sep 25, 2024
…ests (Kocal)

This PR was squashed before being merged into the 2.x branch.

Discussion
----------

[Map] Explicitly require StimulusBundle in Bridges, fix tests

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Issues        | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT

<!--
Replace this notice by a description of your feature/bugfix.
This will help reviewers and should be a good start for the documentation.

Additionally (see https://symfony.com/releases):
 - Always add tests and ensure they pass.
 - For new features, provide some code snippets to help understand usage.
 - Features and deprecations must be submitted against branch main.
 - Changelog entry should follow https://symfony.com/doc/current/contributing/code/conventions.html#writing-a-changelog-entry
 - Never break backward compatibility (see https://symfony.com/bc).
-->

Follows #2180.

When installing a Map Bridge dependencies, the StimulusBundle was not the one from the PR's branch but from `2.x`, and so tests didn't fail in #2180 **but** started to fail after merging:

<img width="661" alt="image" src="https://github.com/user-attachments/assets/de206abe-9490-4103-b1cb-a8fa48753cde">

Commits
-------

7164b57 [Map] Fix Bridges tests
01e902d [Map] Explicitly require StimulusBundle in Bridges
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Performance Status: Reviewed Has been reviewed by a maintainer StimulusBundle
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants