WordPress.org

Make WordPress Core

Opened 4 weeks ago

Last modified 13 days ago

#48654 new feature request

Consider a solution/endpoint to lazy-load scripts and styles

Reported by: youknowriad Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: has-patch dev-feedback needs-unit-tests
Focuses: javascript, rest-api Cc:
PR Number:

Description

As we move towards more JavaScript-heavy UIs, the need to lazy-load assets for performance reasons is increasing.

The Gutenberg plugin has also an experimental feature allowing users to install blocks available in the block directory without leaving the editor or refreshing the page.

In all these situations we need to load assets (JavaScript scripts and stylesheets) from the server. The only thing the client knows is the "handle" of these scripts and styles. It doesn't know the dependencies of these scripts and styles which need to be loaded as well.

So, the requirements here are:

  • Given a script or style handle name, retrieve its dependencies. (Possibly an endpoint)
  • Load these dependencies in the client without duplication (possibly a task that will be tackled in a separate ticket)

Ideally, this endpoint would work for any script and style handle but historically WordPress users may have attached sensible data to their scripts (by calling localize_script or add_inline_script). A solution here should address that issue

Potential solutions:

  • whitelist have a flag similar to show_in_rest saying whether the script is whitelisted or not. This solution risk excluding way too much scripts and styles creating bad user experiences (no lazy load possible, no inline block installs...)
  • blacklist Potentially find a way to detect sensible scripts and styles with rules, for example by saying that all localized scripts are blacklisted by default unless authorized using a flag.
  • Other solutions I didn't think of :)

No matter the solution, if we're not able to load all the dependencies, the client should be notified (in the endpoint response maybe) in order to take the proper action in that case.

Attachments (2)

48654.diff (8.8 KB) - added by spacedmonkey 3 weeks ago.
48654.2.diff (11.4 KB) - added by spacedmonkey 13 days ago.

Download all attachments as: .zip

Change History (10)

@spacedmonkey
3 weeks ago

#1 @spacedmonkey
3 weeks ago

  • Keywords has-patch dev-feedback needs-unit-tests added
  • Version set to 4.7

In 48654.diff I made a first pass at the new REST APIs. This patch, does nothing to handle the security issues related to show on register scripts and styles. Just output the scripts and styles in a usable format.

This patch adds the following APIs.

/wp-json/wp/v2/scripts
/wp-json/wp/v2/styles

Both of these apis have the followings options.

/wp-json/wp/v2/scripts - List all registered scripts
/wp-json/wp/v2/scripts/<handle> - List a single script by handle.
wp/v2/scripts/?dependency=<handle> - List all dependencies of a given handle. This includes the handle itself and recursive dependencies.

{
   handle: "jquery-ui-core",
   src: "/wp-includes/js/jquery/ui/core.min.js",
   deps: [
     "jquery"
   ],
   ver: "1.11.4",
   args: 1,
   extra: [ ],
   textdomain: null,
   translations_path: null,
   url: "http://src.wordpress-develop.test/wp-includes/js/jquery/ui/core.min.js?ver=1.11.4",
   _links: {
     self: [
       {
         href: "http://src.wordpress-develop.test/wp-json/wp/v2/scripts/jquery-ui-core"
       }
     ],
     collection: [
       {
         href: "http://src.wordpress-develop.test/wp-json/wp/v2/scripts"
       }
     ],
     deps: [
       {
         href: "http://src.wordpress-develop.test/wp-json/wp/v2/scripts/?dependency=jquery-ui-core"
       }
     ]
  }
},

Does this look like a work format for you @youknowriad

#2 @youknowriad
3 weeks ago

Thanks @spacedmonkey That's cool.

Maybe we can start by putting this in a Github PR and try to start using it with the Block Directory Inserter. It would be a good real use-case to validate the endpoint. Of course, we need to handle the security issues as well somehow.

Pinging some folks that might be interested in this @noisysocks @tellyworth @talldanwp

This ticket was mentioned in Slack in #core-restapi by spacedmonkey. View the logs.


3 weeks ago

This ticket was mentioned in Slack in #core-restapi by aduth. View the logs.


3 weeks ago

#5 @kadamwhite
3 weeks ago

This is perhaps a naive response, but could we utilize oEmbed at all for this purpose? The need to expose the full script dependency graph seems like overkill, if a plugin's been installed and activated in the background then I'd think it should be possible to treat a given script handle as an oEmbed target and to dynamically load scripts through that manner instead of manually orchestrating everything from the Gutenberg JS code.

#6 @youknowriad
3 weeks ago

@kadamwhite I'm not sure I understand what you propose? Can you clarify a little bit.

#7 @youknowriad
3 weeks ago

I guess you mean something like the current load-scripts.php that also loads the dependencies of the given script. This may work too, conceptually it's very similar to the endpoint proposed above as it exposes the same data but not having to orchestrate inline scripts concats in the client is a win.

@spacedmonkey
13 days ago

#8 @spacedmonkey
13 days ago

In 48654.2.diff I added a basic permission model.

Here are the basic permissions rules.

All core scripts and styles are set as public. All can be found in WP core so should be considered public.

All public script / styles for blocks, also public. These are designed to be displayed on the front end.

All editor script / styles for blocks, check if user has access to edit_posts. These are designed to be displayed on the editor.

All other script / styles check for manage_options.

This model is not perfect, but it to get the ball rolling.

Note: See TracTickets for help on using tickets.