Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[AssetMapper] Add cached asset factory#50286

New issue

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

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

@weaverryan
Copy link
Member

QA
Branch?6.3
Bug fix?no
New feature?yes
Deprecations?no
TicketsNone
LicenseMIT
Doc PRStill TODO

Hi!

This is built on top of#50264. I CAN separate them if needed - sorry for the noise.

tl;dr When using asset mapper, to load the page, we need to build the importmap & resolve a few paths, like{{ asset('styles/app.css') }}. Because asset mapper loads the contents and performs some regex on CSS and JS files, this can slow down the page in dev (in prod,asset-map:compile removes all overhead).

This PR fixes that (I can see a big improvement in my test app). We "cache" theMappedAsset objects via the config cache system so that if an underlying file changes (e.g.assets/styles/app.css), we only need to rebuild that ONEMappedAsset when the page is loading.

Cheers!

* @param iterable<AssetCompilerInterface> $assetCompilers
*/
publicfunction__construct(privateiterable$assetCompilers)
publicfunction__construct(privateiterable$assetCompilers,privateContainerInterface$container)
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

This is the ugliest part of this PR, and it's actually a small fix so that decorating the AssetMapper will work properly.

  • It's super convenient for compilers to have access to the AssetMapper
  • But, we get a circular reference: AssetMapper -> MappedAssetFactory -> AssetMapperCompiler -> AssetMapper

Is there a more elegant way to makejust this one dependency lazy?

Copy link
Member

Choose a reason for hiding this comment

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

You could inject a lazy proxy here, using the same kind of trick than used when using#[Autowire(lazy: AssetMapperInterface::class)] for autowiring. But this would make the component much harder to use standalone if the circular dependency is between constructors (as theonly way to instantiate the object graph would be through a lazy proxy)

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

But this would make the component much harder to use standalone

Thank you - that makes me want to keep this as it is :)

Choose a reason for hiding this comment

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

what about using a closure here, that'd return the mapper? that's a service_closure inthe DI world

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we can keep this as is TBH.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I'll fix this up shortly!


$resources[] =newFileResource($dependency->asset->getSourcePath());
}
$configCache->write(serialize($mappedAsset),$resources);
Copy link
Member

Choose a reason for hiding this comment

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

Given that the MappedAsset object contains AssetDependency objects that contain other MappedAsset objects, what happens when you serialize and unserialize those ?

Also, what is the impact of unserializing a MappedAsset with dependencies that will have MappedAsset objects not known by the AssetMapper internal cache (while potentially referring to the same assets) and also different from MappedAsset created for dependencies of other cached MappedAsset ?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Given that the MappedAsset object contains AssetDependency objects that contain other MappedAsset objects, what happens when you serialize and unserialize those ?

It seems to work fine, in practice. BothMappedAsset andAssetDependency are objects that hold scalars. For example, here is a dump of one situation (dumping the result of theunserialize in the cached factory) in a test project:

Screenshot 2023-05-10 at 1 32 25 PM

What concerns do you have?

Also, what is the impact of unserializing a MappedAsset with dependencies that will have MappedAsset objects not known by the AssetMapper internal cache (while potentially referring to the same assets) and also different from MappedAsset created for dependencies of other cached MappedAsset ?

I think I understand what you're referring to. So, for example:

  • asset1.css has a dependency onasset2.css. When something asks for theasset1.css asset, its cache is fresh, so we get backMappedAsset instances from the cache for bothasset1.css andasset2.css.
  • Meanwhile,asset3.css also has a dependency onasset2.css. When something asks for theasset3.css asset, its cache is NOT fresh, so we get back FRESHMappedAssetinstances for bothasset3.css andasset2.css.

So, at this moment, there are two distinctasset2.cssMappedAsset objects floating around the system. Their data is equal, but the objects are not identical. Other than being wasteful, I don't think it's a problem.MappedAsset objects are "read-only" informational objects. Well, except forMappedAsset::addDependency(). But, in practice, once aMappedAsset is returned fromAssetMapper, it is intended to be read-only: its data is entirely setduring the creation process (we could even "enforce" this by adding some flag to "freeze" theMappedAsset and thus reject callingaddDependency(), but that might be overkill).

However, if we're concerned about this, wecould, "refresh" the dependencies after fetching a cachedMappedAsset - e.g. loop over$mappedAsset->getDependencies()... grab the->logicalName +->getSourcePath() of each, call$this->createMappedAsset($logicalName, $sourcePath) on each, then "replace" theMappedAsset on each dependency.

tl;dr I don't see any real problem, but I could add extra code to be absolutely sure.

@fabpot
Copy link
Member

Should be rebased :)

@weaverryanweaverryanforce-pushed theasset-mapper-cached-asset-factory branch fromda1cc81 to1536554CompareMay 12, 2023 10:03
@weaverryan
Copy link
MemberAuthor

Rebased, reviewed again (by me) and tested again in my local app. Looks good 👍

@weaverryanweaverryanforce-pushed theasset-mapper-cached-asset-factory branch 3 times, most recently from0053044 tod345b7eCompareMay 12, 2023 14:36
@weaverryan
Copy link
MemberAuthor

This should be happy now -service_closure added - much, much nicer.

@weaverryan
Copy link
MemberAuthor

Updated - thanks for the suggestions :)

@fabpot
Copy link
Member

Thank you@weaverryan.

fabpot added a commit that referenced this pull requestMay 13, 2023
This PR was squashed before being merged into the 6.3 branch.Discussion----------[AssetMapper] Add cached asset factory| Q             | A| ------------- | ---| Branch?       | 6.3| Bug fix?      | no| New feature?  | yes| Deprecations? | no| Tickets       | None| License       | MIT| Doc PR        | Still TODOHi!This is built on top of#50264. I CAN separate them if needed - sorry for the noise.tl;dr When using asset mapper, to load the page, we need to build the importmap & resolve a few paths, like `{{ asset('styles/app.css') }}`. Because asset mapper loads the contents and performs some regex on CSS and JS files, this can slow down the page in dev (in prod, `asset-map:compile` removes all overhead).This PR fixes that (I can see a big improvement in my test app). We "cache" the `MappedAsset` objects via the config cache system so that if an underlying file changes (e.g. `assets/styles/app.css`), we only need to rebuild that ONE `MappedAsset` when the page is loading.Cheers!Commits-------ce77ed8 [AssetMapper] Add cached asset factory
@fabpotfabpot closed thisMay 13, 2023
@fabpotfabpotforce-pushed theasset-mapper-cached-asset-factory branch from5bb88ad toce77ed8CompareMay 13, 2023 07:17
@fabpotfabpot mentioned this pull requestMay 13, 2023
@weaverryanweaverryan deleted the asset-mapper-cached-asset-factory branchMay 13, 2023 12:29
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@fabpotfabpotfabpot left review comments

@stofstofstof left review comments

@nicolas-grekasnicolas-grekasnicolas-grekas approved these changes

Assignees

No one assigned

Projects

None yet

Milestone

6.3

Development

Successfully merging this pull request may close these issues.

5 participants

@weaverryan@fabpot@nicolas-grekas@stof@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp