jenkins-bot has submitted this change and it was merged.
Change subject: Optimize how user options are delivered to the client
......................................................................
Optimize how user options are delivered to the client
We currently embed the full set of user options in a <script> tag in the HTML
output of every page. This is grossly inefficient, because the full set of
options is usually largely made up of site defaults which the user hasn't
customized.
So instead of doing that, let's emit the default options using one
ResourceLoader module and then apply the user's customizations on top.
This has the effect of slightly increasing the total bytes of JavaScript code
(because options that the user has customized will be emitted twice: once with
their default value in the user.defaults module, and then again with the
customized value in user.options). But this is more than offset by the
fact that the bulk of user options code (~4 kB uncompressed on enwiki) becomes
cacheable across requests.
Bonus round:
* Varnish gets to cache 4 kB fewer per page.
* Changes to the default options don't take 30 days to propagate.
Change-Id: I5a7e258d2d69159381bf5cc363227088b8fd6019
---
M autoload.php
M includes/User.php
A includes/resourceloader/ResourceLoaderUserDefaultsModule.php
M includes/resourceloader/ResourceLoaderUserOptionsModule.php
M resources/Resources.php
5 files changed, 82 insertions(+), 2 deletions(-)
Approvals:
Krinkle: Looks good to me, approved
jenkins-bot: Verified
diff --git a/autoload.php b/autoload.php
index dbc28ed..8003284 100644
--- a/autoload.php
+++ b/autoload.php
@@ -961,6 +961,7 @@
'ResourceLoaderUserCSSPrefsModule' => __DIR__ .
'/includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php',
'ResourceLoaderUserGroupsModule' => __DIR__ .
'/includes/resourceloader/ResourceLoaderUserGroupsModule.php',
'ResourceLoaderUserModule' => __DIR__ .
'/includes/resourceloader/ResourceLoaderUserModule.php',
+ 'ResourceLoaderUserDefaultsModule' => __DIR__ .
'/includes/resourceloader/ResourceLoaderUserDefaultsModule.php',
'ResourceLoaderUserOptionsModule' => __DIR__ .
'/includes/resourceloader/ResourceLoaderUserOptionsModule.php',
'ResourceLoaderUserTokensModule' => __DIR__ .
'/includes/resourceloader/ResourceLoaderUserTokensModule.php',
'ResourceLoaderWikiModule' => __DIR__ .
'/includes/resourceloader/ResourceLoaderWikiModule.php',
diff --git a/includes/User.php b/includes/User.php
index 5348020..3cbb052 100644
--- a/includes/User.php
+++ b/includes/User.php
@@ -59,6 +59,12 @@
const MAX_WATCHED_ITEMS_CACHE = 100;
/**
+ * Exclude user options that are set to their default value.
+ * @since 1.25
+ */
+ const GETOPTIONS_EXCLUDE_DEFAULTS = 1;
+
+ /**
* @var PasswordFactory Lazily loaded factory object for passwords
*/
private static $mPasswordFactory = null;
@@ -2547,9 +2553,12 @@
/**
* Get all user's options
*
+ * @param int $flags Bitwise combination of:
+ * User::GETOPTIONS_EXCLUDE_DEFAULTS Exclude user options that are
set
+ * to the default value. (Since
1.25)
* @return array
*/
- public function getOptions() {
+ public function getOptions( $flags = 0 ) {
global $wgHiddenPrefs;
$this->loadOptions();
$options = $this->mOptions;
@@ -2566,6 +2575,10 @@
}
}
+ if ( $flags & self::GETOPTIONS_EXCLUDE_DEFAULTS ) {
+ $options = array_diff_assoc( $options,
self::getDefaultOptions() );
+ }
+
return $options;
}
diff --git a/includes/resourceloader/ResourceLoaderUserDefaultsModule.php
b/includes/resourceloader/ResourceLoaderUserDefaultsModule.php
new file mode 100644
index 0000000..1249cf8
--- /dev/null
+++ b/includes/resourceloader/ResourceLoaderUserDefaultsModule.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Resource loader module for default user preferences.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Ori Livneh
+ */
+
+/**
+ * Module for default user preferences.
+ */
+class ResourceLoaderUserDefaultsModule extends ResourceLoaderModule {
+
+ /* Protected Members */
+
+ protected $targets = array( 'desktop', 'mobile' );
+
+ /* Methods */
+
+ /**
+ * @param ResourceLoaderContext $context
+ * @return string Hash
+ */
+ public function getModifiedHash( ResourceLoaderContext $context ) {
+ return md5( serialize( User::getDefaultOptions() ) );
+ }
+
+ /**
+ * @param ResourceLoaderContext $context
+ * @return array|int|mixed
+ */
+ public function getModifiedTime( ResourceLoaderContext $context ) {
+ return $this->getHashMtime( $context );
+ }
+
+ /**
+ * @param ResourceLoaderContext $context
+ * @return string
+ */
+ public function getScript( ResourceLoaderContext $context ) {
+ return Xml::encodeJsCall( 'mw.user.options.set', array(
User::getDefaultOptions() ) );
+ }
+}
diff --git a/includes/resourceloader/ResourceLoaderUserOptionsModule.php
b/includes/resourceloader/ResourceLoaderUserOptionsModule.php
index e6b07c1..a1847fb 100644
--- a/includes/resourceloader/ResourceLoaderUserOptionsModule.php
+++ b/includes/resourceloader/ResourceLoaderUserOptionsModule.php
@@ -38,6 +38,13 @@
/* Methods */
/**
+ * @return array List of module names as strings
+ */
+ public function getDependencies() {
+ return array( 'user.defaults' );
+ }
+
+ /**
* @param ResourceLoaderContext $context
* @return array|int|mixed
*/
@@ -56,7 +63,7 @@
*/
public function getScript( ResourceLoaderContext $context ) {
return Xml::encodeJsCall( 'mw.user.options.set',
- array( $context->getUserObj()->getOptions() ),
+ array( $context->getUserObj()->getOptions(
User::GETOPTIONS_EXCLUDE_DEFAULTS ) ),
ResourceLoader::inDebugMode()
);
}
diff --git a/resources/Resources.php b/resources/Resources.php
index d6a3181..9c43987 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -44,6 +44,7 @@
'user.cssprefs' => array( 'class' => 'ResourceLoaderUserCSSPrefsModule'
),
// Populate mediawiki.user placeholders with information about the
current user
+ 'user.defaults' => array( 'class' => 'ResourceLoaderUserDefaultsModule'
),
'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ),
'user.tokens' => array( 'class' => 'ResourceLoaderUserTokensModule' ),
--
To view, visit https://gerrit.wikimedia.org/r/177501
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I5a7e258d2d69159381bf5cc363227088b8fd6019
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Ori.livneh <[email protected]>
Gerrit-Reviewer: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Bartosz DziewoĆski <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Chad <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Nikerabbit <[email protected]>
Gerrit-Reviewer: Ori.livneh <[email protected]>
Gerrit-Reviewer: Parent5446 <[email protected]>
Gerrit-Reviewer: Tim Starling <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits