Page MenuHomePhabricator

Make a performance audit of the mobile site
Closed, ResolvedPublic5 Estimated Story Points

Description

After ResourceLoader made scripts async the performance profile has probably changed a lot and we should re-run this audit and see what else we can find out.

See initial description ⬇️ and comments for the previous audit and discussion.


We need an in depth audit of the mobile site performance.

Take a look at this example: https://github.com/reddit/reddit-mobile/issues/247

Rough guidelines:

  • Initial loading
    • Analysis of timeline and network waterfall.
    • Usability through loading (Not usable, scrollable, style flashes, usable, etc).
    • Timeline of screenshots through loading.
    • Assets size (CSS, JS).
    • Agregated time spent on each section (loading, CSS, JS parsing & execution, etc.)
  • Deep dive
    • Topic
      • Analysis & in-detail data
      • Conclusions
    • Repeat to next topic
  • Summary and conclusions
  • Recommendations and ideas

Outcomes:

  • In-depth audit has been done for the mobile web. Publish draft for team consumption and analysis.
  • Several developers have gone through the audit, validated the information posted and the problems found.
  • Publicly send the audit of the site.
  • After discussion tasks for the found and agreed problems have been created and linked in the comments.

Next: Hypothesis, areas of work, and matching with existing subtasks of parent task.

Event Timeline

Jhernandez raised the priority of this task from to High.
Jhernandez updated the task description. (Show Details)
Jhernandez added a subscriber: Jhernandez.


Here goes the initial draft:

Setup

  • OS: Mac OS X Yosemite 10.10.4
  • Browser: Chrome 46.0.2462.0 canary (64-bit)
  • Emulated speed: Regular 3G (Max download throughput: 750 kbps, Minimum round-trip time: 100ms)
  • Emulated device: Apple iPhone 5
  • Page: https://en.m.wikipedia.org/wiki/Barack_Obama
  • Logged in: no

Overview

Web page performance

Forced synchronous layout

See https://developer.chrome.com/devtools/docs/timeline#locating-forced-synchronous-layouts
browser.isWideScreen() is forcing Chrome to perform a layout.
Recommendation: The result of the function call should be cached and only changed when the browser is resized or the device changes oreintation.

Remove unused CSS rules

368 rules (63%) of CSS not used by the current page.

.main-menu-button.indicator-circle
.main-menu-button.indicator-circle::after
.notifications-overlay.navigation-drawer
.client-js nav .secondary-action
.client-js nav .primary-action
body.navigation-enabled #mw-mf-viewport
body.navigation-enabled #mw-mf-page-center
body.navigation-enabled .navigation-drawer,body.navigation-enabled .transparent-shield
body.navigation-enabled .transparent-shield
.primary-navigation-enabled
.primary-navigation-enabled #mw-mf-viewport
.primary-navigation-enabled nav
.primary-navigation-enabled .position-fixed
.secondary-navigation-enabled #mw-mf-page-center
.secondary-navigation-enabled #mw-mf-page-center .main-header-button
.notifications-overlay.navigation-drawer
.animations .notifications-overlay.navigation-drawer
.animations .notifications-overlay.navigation-drawer.visible
.navigation-enabled.animations .position-fixed,.navigation-enabled.animations #mw-mf-page-center
.primary-navigation-enabled.animations .position-fixed,.primary-navigation-enabled.animations #mw-mf-page-center
.primary-navigation-enabled.animations nav
.secondary-navigation-enabled.animations #mw-mf-page-center
.rtl .animations .notifications-overlay.navigation-drawer
.rtl .animations .notifications-overlay.navigation-drawer.visible
.rtl.primary-navigation-enabled.animations .position-fixed,.rtl.primary-navigation-enabled.animations #mw-mf-page-center
.rtl.secondary-navigation-enabled.animations #mw-mf-page-center
.mw-ui-icon-uploads:after,.mw-ui-icon-uploads:before
.mw-ui-icon-secondary-logout:after,.mw-ui-icon-secondary-logout:before
.mw-ui-icon-profile:after,.mw-ui-icon-profile:before
.centralAuthPPersonalAnimation
body .wikigrok.visible
body.is-authenticated .wikigrok.visible
.mobile-float-reset
.citation *.printonly
#content .hlist dd ol > li:first-child:before,#content .hlist dt ol > li:first-child:before,#content .hlist li ol > li:first-child:before
.compact-ambox table.ambox
.compact-ambox table.mbox-small-left
.compact-ambox table .mbox-text
.compact-ambox table .mbox-text-span
.visualhide
.hatnote i
.geo-default,.geo-dms,.geo-dec
.longitude,.latitude
td .sortkey,th .sortkey
.transborder
.times-serif,span.texhtml
span.texhtml
.column-count,.references-column-count
.mw-ui-icon-refresh:after,.mw-ui-icon-refresh:before
.mw-ui-icon-clear:after,.mw-ui-icon-clear:before
.mw-ui-icon-back:after,.mw-ui-icon-back:before
.fancycaptcha-reload-loading:after,.fancycaptcha-reload-loading:before,.mw-ui-icon-spinner:after,.mw-ui-icon-spinner:before
.mw-ui-icon-search-content:after,.mw-ui-icon-search-content:before
.mw-ui-icon-close:before
.mw-ui-icon-close-gray:before
.mw-ui-icon-close-invert:before
.mw-ui-icon-tick-disabled:before
.mw-ui-icon-tick:before
.page-list,.topic-title-list,.site-link-list
.page-list li,.topic-title-list li,.site-link-list li
.page-list li .watch-this-article,.topic-title-list li .watch-this-article,.site-link-list li .watch-this-article
.page-list li > a,.topic-title-list li > a,.site-link-list li > a
.page-list li > a:active,.page-list li > a:hover,.page-list li > a:visited,.topic-title-list li > a:active,.topic-title-list li > a:hover,.topic-title-list li > a:visited,.site-link-list li > a:active,.site-link-list li > a:hover,.site-link-list li > a:visited
.page-list.thumbs li,.page-list.side-list li,.topic-title-list.thumbs li,.topic-title-list.side-list li,.site-link-list.thumbs li,.site-link-list.side-list li
.page-list.thumbs .title,.topic-title-list.thumbs .title,.site-link-list.thumbs .title
.page-list .title h3,.page-list .title .mw-mf-user,.page-list .title .component,.page-list .title .info,.topic-title-list .title h3,.topic-title-list .title .mw-mf-user,.topic-title-list .title .component,.topic-title-list .title .info,.site-link-list .title h3,.site-link-list .title .mw-mf-user,.site-link-list .title .component,.site-link-list .title .info
.page-list .list-thumb,.topic-title-list .list-thumb,.site-link-list .list-thumb
.page-list.side-list .list-thumb,.topic-title-list.side-list .list-thumb,.site-link-list.side-list .list-thumb
.page-list.side-list .list-thumb p,.topic-title-list.side-list .list-thumb p,.site-link-list.side-list .list-thumb p
.page-list.side-list .list-thumb .timestamp,.topic-title-list.side-list .list-thumb .timestamp,.site-link-list.side-list .list-thumb .timestamp
.page-list .title.new h3,.topic-title-list .title.new h3,.site-link-list .title.new h3
.page-list p,.topic-title-list p,.site-link-list p
.page-list .info,.page-list .component,.topic-title-list .info,.topic-title-list .component,.site-link-list .info,.site-link-list .component
.page-list .info,.topic-title-list .info,.site-link-list .info
.stable .page-summary-list,.stable .topic-title-list,.stable .site-link-list
.page-summary h2,.page-summary h3
.page-summary h2 a,.page-summary h3 a
.page-summary h2 strong,.page-summary h3 strong
.list-header
.list-thumb
.list-thumb.list-thumb-none
.list-thumb.list-thumb-x
.list-thumb.list-thumb-y
.mw-ui-icon-arrow-up:before
.mw-ui-icon-talk:before
.mw-ui-icon-watched:before
.mw-ui-icon-edit-enabled:before
.mw-ui-icon-addimage:before
.mw-ui-icon-addimage-enabled:before
.mw-ui-icon-edit-source:before
.mw-ui-icon-edit-ve:before
.mw-ui-icon-edit-switch:before
.mw-ui-icon-toc:before
.mw-ui-icon-cleanup:before
.mw-ui-icon-cleanup-gray:before
.mw-ui-icon-user:before
.mw-ui-icon-anonymous:before
.mw-ui-icon-citation:before
.mw-ui-input
.mw-ui-input::-webkit-input-placeholder
.mw-ui-input::-moz-placeholder
.mw-ui-input:-moz-placeholder
.mw-ui-input:-ms-input-placeholder
.mw-ui-input:invalid
.mw-ui-input:focus
.mw-ui-input:disabled
textarea.mw-ui-input
input[type="number"],.mw-ui-input-inline
.mw-ui-input-large
.mw-ui-input-large + .mw-ui-input-large
.mw-ui-input-large:focus
input.mw-ui-input-large
.loading.spinner
#content .panel
#content .panel .content
.toast-panel.visible,.animations .toast-panel.visible
.button-spinner .loading.spinner
.overlay-enabled #mw-mf-page-center
.overlay-enabled .overlay,.overlay-enabled #mw-mf-page-center
.overlay
.overlay.visible
.overlay input,.overlay textarea
.overlay .captcha-word,.overlay .summary
.overlay .wikitext-editor
.overlay .panel
.overlay .license
.overlay .content .cancel
.overlay .content-header
.overlay .slider-button
.overlay .slider-button.prev
.overlay .slider-button.next
.overlay .slider-button > *
.overlay-header
.overlay-header .overlay-title
.overlay-header .overlay-title,.overlay-header .overlay-search
.overlay-header .overlay-action a,.overlay-header .overlay-action button
.overlay-header .overlay-action a:before,.overlay-header .overlay-action button:before
.overlay-header .overlay-action a[disabled],.overlay-header .overlay-action button[disabled]
.overlay-header .continue
.overlay-header .submit
.overlay-header h2
.overlay-header h2 > *
.overlay-header h2 span
.overlay-header > ul,.overlay-header > div
.overlay-header > ul li
.overlay-header > ul,.overlay-header button
.overlay-header .overlay-action a,.overlay-header button
.overlay-header .overlay-action a:focus,.overlay-header button:focus
.overlay-header-container,.overlay-footer-container
.overlay-header-container.position-fixed,.overlay-footer-container.position-fixed
.overlay-header-container
.overlay-footer-container
.overlay-footer-container a
.overlay-bottom
.overlay-bottom .overlay-header-container
.overlay-ios .overlay-header-container
.overlay-ios .overlay-footer-container
.overlay-ios .overlay-content
.overlay .panel
.alpha .overlay-header,.beta .overlay-header
.alpha .overlay-header-container,.beta .overlay-header-container
.alpha .overlay-header .cancel,.alpha .overlay-header .back,.beta .overlay-header .cancel,.beta .overlay-header .back
.alpha .overlay-header .clear,.beta .overlay-header .clear
.alpha .overlay-header input.search,.beta .overlay-header input.search
.drawer.text
.drawer p
.drawer p,.drawer a:not(:last-child),.drawer .mw-ui-button
.drawer .cancel
.overlay-enabled .drawer
.client-js .collapsible-block.open-block
.panel-inline
.panel-inline.visible
.navigation-drawer .pointer-overlay
.pointer-overlay
.pointer-overlay p
.pointer-overlay .button
.pointer-overlay .tutorial-pointer
.pointer-overlay.tutorial-overlay
.pointer-overlay.tutorial-overlay p
.pointer-overlay.tutorial-overlay .tutorial-pointer
.pointer-overlay.tutorial-overlay .button
.pointer-overlay.tutorial-overlay .cancel.inline
.pointer-overlay.tutorial-overlay .button-bar
.mw-mf-cleanup
.overlay .cleanup li
.overlay .cleanup li .issue-notice
.overlay .cleanup li .issue-notice:before
.overlay .cleanup li .issue-notice
.overlay .cleanup li .issue-notice:before
.mw-notification-area.visible,.toast.visible,.drawer.visible
.animations .toast.animated,.animations .drawer.animated
.animations .toast.visible,.animations .drawer.visible
.mw-notification-area.error,.toast.error
.mw-notification-area a,.toast a
.mw-notification-area a.new,.toast a.new
.drawer-enabled
.drawer.references
.drawer.references.text
.drawer.references a
.drawer.references .cite
.drawer.references .cite:after
.drawer.references .cite .text
.drawer.references .cite .cancel
.drawer.references .mw-cite-backlink
.drawer.references .reference-text
.gather-overlay-enabled #mw-mf-page-center
.overlay.collection-overlay
.overlay.collection-overlay.content-overlay
.overlay.collection-overlay.content-overlay.compact
.overlay.collection-overlay .cancel
.overlay.collection-overlay .overlay-header-container .overlay-header li
.overlay.collection-overlay .overlay-content
.overlay.collection-overlay .overlay-content .snapshot
.overlay.collection-overlay .overlay-content .snapshot .thumbnail
.overlay.collection-overlay .overlay-content .snapshot .thumbnail.missing
.overlay.collection-overlay .overlay-content .snapshot .thumbnail img
.overlay.collection-overlay .overlay-content .snapshot strong
.overlay.collection-overlay .overlay-content.interstitial
.overlay.collection-overlay .overlay-content.interstitial .tutorial .heading
.overlay.collection-overlay .overlay-content.interstitial .tutorial .button-bar
.overlay.collection-overlay .overlay-content h3
.overlay.collection-overlay .overlay-content li,.overlay.collection-overlay .overlay-content form
.overlay.collection-overlay .overlay-content form
.overlay.collection-overlay .overlay-content form .create-collection-input
.overlay.collection-overlay .overlay-content form .create-collection
.overlay.collection-overlay .overlay-content li
.overlay.collection-overlay .overlay-content li > div
.overlay.collection-overlay .overlay-content hr
.overlay.collection-overlay h3
.overlay.collection-overlay .more-collections
.overlay.collection-overlay.content-overlay
.overlay.collection-overlay.content-overlay .overlay-content
.overlay.collection-overlay .overlay-content hr
.overlay.collection-overlay .overlay-content .snapshot .thumbnail
.animations .watch-this-article.watched
.collection-star-container
.collection-star-container button
.gather-tag
.search-overlay
.search-overlay .overlay-header,.search-overlay .results,.search-overlay .search-feedback
.search-overlay input
.search-overlay input::-ms-clear
.search-overlay .overlay-content
.search-overlay .search-content
.search-overlay .search-content .caption
.search-overlay .search-content.overlay-header
.search-overlay .results
.search-overlay .results li
.search-overlay .results li .list-thumb
.search-overlay .results li:last-child
.search-overlay .results h2
.search-overlay .search-feedback
.search-overlay.no-results .search-feedback
from
to
from
to
from
to
from
to
.animations .search-overlay.visible
.animations .search-overlay.fade-out
#page-actions li.collection-star-container a
.mw-ui-icon-notifications:before
.mw-ui-button.mw-ui-big
.mw-ui-button.mw-ui-block
.mw-ui-button.mw-ui-progressive.mw-ui-quiet,.mw-ui-button.mw-ui-primary.mw-ui-quiet
.mw-ui-button.mw-ui-progressive.mw-ui-quiet:hover,.mw-ui-button.mw-ui-progressive.mw-ui-quiet:focus,.mw-ui-button.mw-ui-primary.mw-ui-quiet:hover,.mw-ui-button.mw-ui-primary.mw-ui-quiet:focus
.mw-ui-button.mw-ui-progressive.mw-ui-quiet:active,.mw-ui-button.mw-ui-progressive.mw-ui-quiet.mw-ui-checked,.mw-ui-button.mw-ui-primary.mw-ui-quiet:active,.mw-ui-button.mw-ui-primary.mw-ui-quiet.mw-ui-checked
.mw-ui-button.mw-ui-progressive.mw-ui-quiet:disabled,.mw-ui-button.mw-ui-primary.mw-ui-quiet:disabled
.mw-ui-button.mw-ui-constructive
.mw-ui-button.mw-ui-constructive:hover
.mw-ui-button.mw-ui-constructive:focus
.mw-ui-button.mw-ui-constructive:focus::-moz-focus-inner
.mw-ui-button.mw-ui-constructive:active,.mw-ui-button.mw-ui-constructive.mw-ui-checked
.mw-ui-button.mw-ui-constructive:disabled
.mw-ui-button.mw-ui-constructive:disabled:hover,.mw-ui-button.mw-ui-constructive:disabled:active,.mw-ui-button.mw-ui-constructive:disabled.mw-ui-checked
.mw-ui-button.mw-ui-constructive.mw-ui-quiet
.mw-ui-button.mw-ui-constructive.mw-ui-quiet:hover,.mw-ui-button.mw-ui-constructive.mw-ui-quiet:focus
.mw-ui-button.mw-ui-constructive.mw-ui-quiet:active,.mw-ui-button.mw-ui-constructive.mw-ui-quiet.mw-ui-checked
.mw-ui-button.mw-ui-constructive.mw-ui-quiet:disabled
.mw-ui-button.mw-ui-destructive
.mw-ui-button.mw-ui-destructive:hover
.mw-ui-button.mw-ui-destructive:focus
.mw-ui-button.mw-ui-destructive:focus::-moz-focus-inner
.mw-ui-button.mw-ui-destructive:active,.mw-ui-button.mw-ui-destructive.mw-ui-checked
.mw-ui-button.mw-ui-destructive:disabled
.mw-ui-button.mw-ui-destructive:disabled:hover,.mw-ui-button.mw-ui-destructive:disabled:active,.mw-ui-button.mw-ui-destructive:disabled.mw-ui-checked
.mw-ui-button.mw-ui-destructive.mw-ui-quiet
.mw-ui-button.mw-ui-destructive.mw-ui-quiet:hover,.mw-ui-button.mw-ui-destructive.mw-ui-quiet:focus
.mw-ui-button.mw-ui-destructive.mw-ui-quiet:active,.mw-ui-button.mw-ui-destructive.mw-ui-quiet.mw-ui-checked
.mw-ui-button.mw-ui-destructive.mw-ui-quiet:disabled
.mw-ui-button.mw-ui-quiet
.mw-ui-button.mw-ui-quiet:hover,.mw-ui-button.mw-ui-quiet:focus
.mw-ui-button.mw-ui-quiet:active,.mw-ui-button.mw-ui-quiet.mw-ui-checked
.mw-ui-button.mw-ui-quiet:disabled
.mw-ui-button.mw-ui-quiet:hover,.mw-ui-button.mw-ui-quiet:focus
.mw-ui-button.mw-ui-quiet:active,.mw-ui-button.mw-ui-quiet:disabled
.mw-ui-button-group > *
.mw-ui-button-group > *:first-child
.mw-ui-button-group > *:not(:first-child)
.mw-ui-button-group > *:last-child
button
.header > .header-title
.client-use-basic-search .header .search,.client-use-basic-search .header .fulltext-search,.client-nojs .header .search,.client-nojs .header .fulltext-search
.client-use-basic-search .header .search,.client-nojs .header .search
.content h1 .edit-page
.content h2 .edit-page
.content h3 .edit-page
.content .edit-page
.content .open-block .edit-page
.truncated-text.multi-line
.truncated-text.two-line
.overlay #secondary-button.user-button,.overlay .user-button,.header #secondary-button.user-button,.header .user-button
.overlay #secondary-button.user-button .label,.overlay .user-button .label,.header #secondary-button.user-button .label,.header .user-button .label
.overlay #secondary-button.user-button.loading span,.overlay .user-button.loading span,.header #secondary-button.user-button.loading span,.header .user-button.loading span
.notification-count
.notification-count.zero
.notification-count.max
.mw-ui-button-group
.mw-ui-button-group *
.mw-ui-button-group .mw-ui-block
.client-nojs .stable .header .search
.client-nojs #ca-watch,.client-nojs #ca-edit,#ca-talk.selected
.stable .pre-content .tagline,.heading-holder .tagline
.stable .pre-content .tagline:first-letter,.heading-holder .tagline:first-letter
#page-actions li input
.client-nojs #page-actions
.client-nojs #section_0
.mw-mf-image-replacement
textarea
.no-position-fixed .drawer
.no-position-fixed .position-fixed
span.mw-ui-icon
.nomobile
.content .thumb .noresize
.content .thumb .noresize img
.content .floatright
.content .floatleft
ul.gallery
ul.gallery .gallerybox
ul.gallery .gallerybox .thumb img
ul.gallery .gallerybox > div
ul.gallery .gallerybox > div > .thumb
ul.gallery .gallerybox .gallerytext
blockquote
blockquote:before
blockquote:after
.content ul>li>ul>li>ul
.content .return-link,.content #mw-mf-last-modified
code,pre
code
pre
sub
.content table caption
#filetoc,.mw-editsection
.skin-minerva .portal-column-left-wide,.skin-minerva .portal-column-left,.skin-minerva .portal-column-right,.skin-minerva .portal-column-right-narrow
.references-column-count
.quotebox
.gallery .gallerybox
.gallery .gallerybox div
.content table.multicol > tbody > tr > td,.content table.multicol > tr > td
#content_wrapper .content_block
.content blockquote
.content table caption
.stable #mw-mf-last-modified.pre-content
#content_wrapper caption

Recommendation: Lazy-load the CSS rules. Given the size of the CSS files this should be a low priority.

Use normal CSS property names instead of vendor-prefixed ones

.list-thumb.list-thumb-x
"-webkit-background-size" is used, but "background-size" is supported.
.list-thumb.list-thumb-y
"-webkit-background-size" is used, but "background-size" is supported.
.mw-ui-input
"-webkit-box-sizing" is used, but "box-sizing" is supported.
.overlay.collection-overlay
"-webkit-background-size" is used, but "background-size" is supported.
.overlay.collection-overlay.content-overlay
"-webkit-background-size" is used, but "background-size" is supported.
.gather-tag
"-webkit-background-size" is used, but "background-size" is supported.
.mw-ui-button
"-webkit-box-sizing" is used, but "box-sizing" is supported.
.view-border-box *,.view-border-box
"-webkit-box-sizing" is used, but "box-sizing" is supported.

Recommendation: Sure, use standards.

Network Utilization

Leverage browser caching

The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:

440px-President_Barack_Obama.jpg
256px-Barack_Obama_signature.svg.png
140px-President_Barack_Obama%2C_2012_portrait_crop.jpg
240px-Barack_Obama_signature.svg.png
80px-Seal_of_the_President_of_the_United_States.svg.png
22px-Speakerlink-new.svg.png
Ann_Dunham_with_father_and_children.jpg
440px-Obamamiltondavis1.jpg
220px-2004_Illinois_Senate_results.svg.png
340px-BarackObamaportrait.jpg
440px-Lugar-Obama.jpg
440px-Flickr_Obama_Springfield_01.jpg
440px-President_George_W._Bush_and_Barack_Obama_meet_in_Oval_Office.jpg
440px-P112912PS-0444_-_President_Barack_Obama_and_Mitt_Romney_in_the_Oval_Office_-_crop.jpg
440px-US_President_Barack_Obama_taking_his_Oath_of_Office_-_2009Jan20.jpg
440px-Barack_Obama_addresses_joint_session_of_Congress_2009-02-24.jpg
440px-Obama_cabinet_meeting_2009-11.jpg
220px-seek%3D63-20090124_WeeklyAddress.ogv.jpg
440px-U.S._Total_Deficits_vs._National_Debt_Increases_2001-2010.png
600px-US_Employment_Statistics.svg.png
440px-Obama-venice-la.jpg
440px-Obama_signs_health_care-20100323.jpg
600px-PPACA_Premium_Chart.jpg
440px-Barack_Obama_visiting_victims_of_2012_Aurora_shooting.jpg
340px-Barack_Obama_at_Cairo_University_cropped.jpg
440px-David_Cameron_and_Barack_Obama_at_the_G20_Summit_in_Toronto.jpg
440px-Barack_Obama_welcomes_Shimon_Peres_in_the_Oval_Office.jpg
220px--President_Obama_on_Death_of_Osama_bin_Laden.ogv.jpg
22px-Wikisource-logo.svg.png
440px-Obama_and_Biden_await_updates_on_bin_Laden.jpg
340px-Official_portrait_of_Barack_Obama.jpg
440px-Barack_Obama_hangout.jpg
440px-G8_leaders_watching_football.jpg
500px-Obama_family_portrait_in_the_Green_Room.jpg
340px-Barack_Obama_playing_basketball_with_members_of_Congress_and_Cabinet_secretaries_2.jpg
440px-Obamas_at_church_on_Inauguration_Day_2013.jpg
90px-Sound-icon.svg.png
180px-President_Barack_Obama%2C_2012_portrait_crop.jpg
31px-Symbol_book_class2.svg.png
32px-Folder_Hexagonal_Icon.svg.png
24px-Commons-logo.svg.png
32px-Wikibooks-logo.svg.png
27px-Wikiquote-logo.svg.png
30px-Wikisource-logo.svg.png
32px-Portal-puzzle.svg.png
200px-Seal_of_the_President_of_the_United_States.svg.png
30px-Yellow_flag_waving.svg.png
46px-Flag_of_Canada.svg.png
45px-Flag_of_France.svg.png
46px-Flag_of_Germany.svg.png
45px-Flag_of_Italy.svg.png
45px-Flag_of_Japan.svg.png
46px-Flag_of_the_United_Kingdom.svg.png
46px-Flag_of_the_United_States.svg.png
45px-Flag_of_Europe.svg.png
45px-Flag_of_Russia.svg.png
46px-Flag_of_Argentina.svg.png
46px-Flag_of_Australia.svg.png
43px-Flag_of_Brazil.svg.png
45px-Flag_of_the_People%27s_Republic_of_China.svg.png
45px-Flag_of_India.svg.png
45px-Flag_of_Indonesia.svg.png
46px-Flag_of_Mexico.svg.png
45px-Flag_of_Saudi_Arabia.svg.png
45px-Flag_of_South_Africa.svg.png
45px-Flag_of_South_Korea.svg.png
45px-Flag_of_Turkey.svg.png
46px-Flag_of_Brunei.svg.png
45px-Flag_of_Chile.svg.png
45px-Flag_of_Hong_Kong.svg.png
46px-Flag_of_Malaysia.svg.png
46px-Flag_of_New_Zealand.svg.png
40px-Flag_of_Papua_New_Guinea.svg.png
45px-Flag_of_Peru.svg.png
46px-Flag_of_the_Philippines.svg.png
45px-Flag_of_Singapore.svg.png
45px-Flag_of_Chinese_Taipei_for_Olympic_games.svg.png
45px-Flag_of_Thailand.svg.png
45px-Flag_of_Vietnam.svg.png
160px-Seal_of_the_United_States_Senate.svg.png
60px-Office-book.svg.png
44px-Obama.svg.png
60px-Great_Seal_of_the_United_States_%28obverse%29.svg.png
45px-Commons-logo.svg.png
60px-Wikinews-logo.svg.png
51px-Wikiquote-logo.svg.png
57px-Wikisource-logo.svg.png

Recommendation: Add cache expiration

The following cacheable resources have a short freshness lifetime:

https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=ext.gather.menu.icon%7Cmediawiki.ui.button%2Cicon%7Cskins.minerva.base.reset%2Cstyles%7Cskins.minerva.content.styles%7Cskins.minerva.tablet.styles&only=styles&skin=minerva&target=mobile&*
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=startup&only=scripts&skin=minerva&target=mobile&*
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=jquery%2Cmediawiki&only=scripts&skin=minerva&version=ldHNa8sg
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=mobile.site&skin=minerva&version=fa39937e764c&*
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=ext.gadget.switcher%7Cskins.minerva.icons.images&only=styles&skin=minerva&target=mobile&*

Recommendation: Do we even want to cache these?

The following resources are explicitly non-cacheable. Consider making them cacheable if possible:

https://en.m.wikipedia.org/wiki/Barack_Obama
https://en.m.wikipedia.org/images/mobile/wikipedia-wordmark-en.png

Recommendation: Cache the image at least.

Leverage proxy caching

Resources with a "?" in the URL are not cached by most proxy caching servers:

https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=ext.gather.menu.icon%7Cmediawiki.ui.button%2Cicon%7Cskins.minerva.base.reset%2Cstyles%7Cskins.minerva.content.styles%7Cskins.minerva.tablet.styles&only=styles&skin=minerva&target=mobile&*
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=startup&only=scripts&skin=minerva&target=mobile&*
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=jquery%2Cmediawiki&only=scripts&skin=minerva&version=ldHNa8sg
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=mobile.site&skin=minerva&version=fa39937e764c&*
https://en.wikipedia.org/w/load.php?debug=false&lang=en&modules=ext.gadget.switcher%7Cskins.minerva.icons.images&only=styles&skin=minerva&target=mobile&*

Recommendation: Is that even a concern?

Consider adding a "Cache-Control: public" header to the following resources:

440px-President_Barack_Obama.jpg
256px-Barack_Obama_signature.svg.png
140px-President_Barack_Obama%2C_2012_portrait_crop.jpg
240px-Barack_Obama_signature.svg.png
80px-Seal_of_the_President_of_the_United_States.svg.png
22px-Speakerlink-new.svg.png
Ann_Dunham_with_father_and_children.jpg
440px-Obamamiltondavis1.jpg
220px-2004_Illinois_Senate_results.svg.png
340px-BarackObamaportrait.jpg
440px-Lugar-Obama.jpg
440px-Flickr_Obama_Springfield_01.jpg
440px-President_George_W._Bush_and_Barack_Obama_meet_in_Oval_Office.jpg
440px-P112912PS-0444_-_President_Barack_Obama_and_Mitt_Romney_in_the_Oval_Office_-_crop.jpg
440px-US_President_Barack_Obama_taking_his_Oath_of_Office_-_2009Jan20.jpg
440px-Barack_Obama_addresses_joint_session_of_Congress_2009-02-24.jpg
440px-Obama_cabinet_meeting_2009-11.jpg
220px-seek%3D63-20090124_WeeklyAddress.ogv.jpg
440px-U.S._Total_Deficits_vs._National_Debt_Increases_2001-2010.png
600px-US_Employment_Statistics.svg.png
440px-Obama-venice-la.jpg
440px-Obama_signs_health_care-20100323.jpg
600px-PPACA_Premium_Chart.jpg
440px-Barack_Obama_visiting_victims_of_2012_Aurora_shooting.jpg
340px-Barack_Obama_at_Cairo_University_cropped.jpg
440px-David_Cameron_and_Barack_Obama_at_the_G20_Summit_in_Toronto.jpg
440px-Barack_Obama_welcomes_Shimon_Peres_in_the_Oval_Office.jpg
220px--President_Obama_on_Death_of_Osama_bin_Laden.ogv.jpg
22px-Wikisource-logo.svg.png
440px-Obama_and_Biden_await_updates_on_bin_Laden.jpg
340px-Official_portrait_of_Barack_Obama.jpg
440px-Barack_Obama_hangout.jpg
440px-G8_leaders_watching_football.jpg
500px-Obama_family_portrait_in_the_Green_Room.jpg
340px-Barack_Obama_playing_basketball_with_members_of_Congress_and_Cabinet_secretaries_2.jpg
440px-Obamas_at_church_on_Inauguration_Day_2013.jpg
90px-Sound-icon.svg.png
180px-President_Barack_Obama%2C_2012_portrait_crop.jpg
31px-Symbol_book_class2.svg.png
32px-Folder_Hexagonal_Icon.svg.png
24px-Commons-logo.svg.png
32px-Wikibooks-logo.svg.png
27px-Wikiquote-logo.svg.png
30px-Wikisource-logo.svg.png
32px-Portal-puzzle.svg.png
200px-Seal_of_the_President_of_the_United_States.svg.png
30px-Yellow_flag_waving.svg.png
46px-Flag_of_Canada.svg.png
45px-Flag_of_France.svg.png
46px-Flag_of_Germany.svg.png
45px-Flag_of_Italy.svg.png
45px-Flag_of_Japan.svg.png
46px-Flag_of_the_United_Kingdom.svg.png
46px-Flag_of_the_United_States.svg.png
45px-Flag_of_Europe.svg.png
45px-Flag_of_Russia.svg.png
46px-Flag_of_Argentina.svg.png
46px-Flag_of_Australia.svg.png
43px-Flag_of_Brazil.svg.png
45px-Flag_of_the_People%27s_Republic_of_China.svg.png
45px-Flag_of_India.svg.png
45px-Flag_of_Indonesia.svg.png
46px-Flag_of_Mexico.svg.png
45px-Flag_of_Saudi_Arabia.svg.png
45px-Flag_of_South_Africa.svg.png
45px-Flag_of_South_Korea.svg.png
45px-Flag_of_Turkey.svg.png
46px-Flag_of_Brunei.svg.png
45px-Flag_of_Chile.svg.png
45px-Flag_of_Hong_Kong.svg.png
46px-Flag_of_Malaysia.svg.png
46px-Flag_of_New_Zealand.svg.png
40px-Flag_of_Papua_New_Guinea.svg.png
45px-Flag_of_Peru.svg.png
46px-Flag_of_the_Philippines.svg.png
45px-Flag_of_Singapore.svg.png
45px-Flag_of_Chinese_Taipei_for_Olympic_games.svg.png
45px-Flag_of_Thailand.svg.png
45px-Flag_of_Vietnam.svg.png
160px-Seal_of_the_United_States_Senate.svg.png
60px-Office-book.svg.png
44px-Obama.svg.png
60px-Great_Seal_of_the_United_States_%28obverse%29.svg.png
45px-Commons-logo.svg.png
60px-Wikinews-logo.svg.png
51px-Wikiquote-logo.svg.png
57px-Wikisource-logo.svg.png

Recommendation: Yeah, why not make public images cachable by anyone?

Minimize cookie size

The average cookie size for all requests on this page is 33 B
Recommendation: ?

Parallelize downloads across hostnames

This page makes 87 parallelizable requests to upload.wikimedia.org. Increase download parallelization by distributing the following requests across multiple hostnames.

440px-President_Barack_Obama.jpg
256px-Barack_Obama_signature.svg.png
140px-President_Barack_Obama%2C_2012_portrait_crop.jpg
240px-Barack_Obama_signature.svg.png
80px-Seal_of_the_President_of_the_United_States.svg.png
22px-Speakerlink-new.svg.png
Ann_Dunham_with_father_and_children.jpg
440px-Obamamiltondavis1.jpg
220px-2004_Illinois_Senate_results.svg.png
340px-BarackObamaportrait.jpg
440px-Lugar-Obama.jpg
440px-Flickr_Obama_Springfield_01.jpg
440px-President_George_W._Bush_and_Barack_Obama_meet_in_Oval_Office.jpg
440px-P112912PS-0444_-_President_Barack_Obama_and_Mitt_Romney_in_the_Oval_Office_-_crop.jpg
440px-US_President_Barack_Obama_taking_his_Oath_of_Office_-_2009Jan20.jpg
440px-Barack_Obama_addresses_joint_session_of_Congress_2009-02-24.jpg
440px-Obama_cabinet_meeting_2009-11.jpg
220px-seek%3D63-20090124_WeeklyAddress.ogv.jpg
440px-U.S._Total_Deficits_vs._National_Debt_Increases_2001-2010.png
600px-US_Employment_Statistics.svg.png
440px-Obama-venice-la.jpg
440px-Obama_signs_health_care-20100323.jpg
600px-PPACA_Premium_Chart.jpg
440px-Barack_Obama_visiting_victims_of_2012_Aurora_shooting.jpg
340px-Barack_Obama_at_Cairo_University_cropped.jpg
440px-David_Cameron_and_Barack_Obama_at_the_G20_Summit_in_Toronto.jpg
440px-Barack_Obama_welcomes_Shimon_Peres_in_the_Oval_Office.jpg
220px--President_Obama_on_Death_of_Osama_bin_Laden.ogv.jpg
22px-Wikisource-logo.svg.png
440px-Obama_and_Biden_await_updates_on_bin_Laden.jpg
340px-Official_portrait_of_Barack_Obama.jpg
440px-Barack_Obama_hangout.jpg
440px-G8_leaders_watching_football.jpg
500px-Obama_family_portrait_in_the_Green_Room.jpg
340px-Barack_Obama_playing_basketball_with_members_of_Congress_and_Cabinet_secretaries_2.jpg
440px-Obamas_at_church_on_Inauguration_Day_2013.jpg
90px-Sound-icon.svg.png
180px-President_Barack_Obama%2C_2012_portrait_crop.jpg
31px-Symbol_book_class2.svg.png
32px-Folder_Hexagonal_Icon.svg.png
24px-Commons-logo.svg.png
32px-Wikibooks-logo.svg.png
27px-Wikiquote-logo.svg.png
30px-Wikisource-logo.svg.png
32px-Portal-puzzle.svg.png
200px-Seal_of_the_President_of_the_United_States.svg.png
30px-Yellow_flag_waving.svg.png
46px-Flag_of_Canada.svg.png
45px-Flag_of_France.svg.png
46px-Flag_of_Germany.svg.png
45px-Flag_of_Italy.svg.png
45px-Flag_of_Japan.svg.png
46px-Flag_of_the_United_Kingdom.svg.png
46px-Flag_of_the_United_States.svg.png
45px-Flag_of_Europe.svg.png
45px-Flag_of_Russia.svg.png
46px-Flag_of_Argentina.svg.png
46px-Flag_of_Australia.svg.png
43px-Flag_of_Brazil.svg.png
45px-Flag_of_the_People%27s_Republic_of_China.svg.png
45px-Flag_of_India.svg.png
45px-Flag_of_Indonesia.svg.png
46px-Flag_of_Mexico.svg.png
45px-Flag_of_Saudi_Arabia.svg.png
45px-Flag_of_South_Africa.svg.png
45px-Flag_of_South_Korea.svg.png
45px-Flag_of_Turkey.svg.png
46px-Flag_of_Brunei.svg.png
45px-Flag_of_Chile.svg.png
45px-Flag_of_Hong_Kong.svg.png
46px-Flag_of_Malaysia.svg.png
46px-Flag_of_New_Zealand.svg.png
40px-Flag_of_Papua_New_Guinea.svg.png
45px-Flag_of_Peru.svg.png
46px-Flag_of_the_Philippines.svg.png
45px-Flag_of_Singapore.svg.png
45px-Flag_of_Chinese_Taipei_for_Olympic_games.svg.png
45px-Flag_of_Thailand.svg.png
45px-Flag_of_Vietnam.svg.png
160px-Seal_of_the_United_States_Senate.svg.png
60px-Office-book.svg.png
44px-Obama.svg.png
60px-Great_Seal_of_the_United_States_%28obverse%29.svg.png
45px-Commons-logo.svg.png
60px-Wikinews-logo.svg.png
51px-Wikiquote-logo.svg.png
57px-Wikisource-logo.svg.png

Recommendation: Use multiple domains?

Other

  1. Use $el.addClass('hidden') rather than $el.hide() because jQuery performs unnecessary calculations before hiding. Similarly, use $el.removeClass('hidden') rather than $el.show(). See https://wikimania2015.wikimedia.org/w/index.php?title=File:How_we_made_VisualEditor_faster.pdf&page=10

Very interesting that image downloads are blocking the page from downloading.

Seems like some actionable tasks here:

  • Image caching < https://phabricator.wikimedia.org/T19577 >
  • Consider dropping vendor prefixes for border-box based on good browser support.
  • Minimising css loaded on page: <Add new ones to https://phabricator.wikimedia.org/T97289>
    • .collection-overlay css should not be loaded until you click the star (https://gerrit.wikimedia.org/r/#/c/212586/)
    • Consider loading .search-overlay and .page-list css only when making use of search
    • Consider only loading the reference drawer css when a reference is clicked.
    • Only load .overlay .cleanup css on pages which contain cleanup templates.
    • .pointer-overlay css should only be loaded conditionally when needed
    • Mediawiki ui styles T98395
  • Spike to explore impact of browser.isWideScreen
  • Update all .show / .hide calls to use addClass/removeClass hidden (we knew this already but it seems like we slacked a little)
    • Forbid use of .hide in code base (great if we can do this programmatically) to prevent this reoccurring
  • Cache static images: T86993
  • On the subject of Minimize cookie size we should look at what cookies are getting set and make them use localStorage instead

My major concern is how images are impacting firstPaint - that seems like a top priority as images are supposed to be non blocking, and from what I understand, what is happening is the image downloads are preventing the ResourceLoader ajax requests for scripts to occur (apparently @ori says there is a card for this).

I've got nothing really to add on top of the stuff above.
I ran a JavaScript CPU profile in debug mode:

Screen Shot 2015-07-31 at 4.46.33 PM.png (94×851 px, 19 KB)

First spike is loading startup module
Second spike main menu and initialising history link
Final spike is setting up Page.js

A few thoughts around glancing a this data:

  • A lot of time is spent in event handling
  • We use jQuery extend a lot - there might be a more performant way
  • MainMenu renders too early?
  • we should review our selector usage.

Thanks for the work folks. Some surprising results in here :S

I don't think the CSS size is an issue seeing the report, so let's focus on other things first.

Seems like images will be our top priority:

  • Avoid them blocking the rendering of the page
  • Ensure they have cache headers
  • Explore linking to images from different domains (even if the alias to the same one internally) for better parallel download of images

@Jdlrobson Do you see anything on the JS execution profile that is screwing with first paint?

Email here https://lists.wikimedia.org/pipermail/mobile-l/2015-August/009587.html (also posted to wikitech-l).

Moving out of the sprint but let's keep it open for the moment to see if we can have more conversations around it.

Parallelize downloads across hostnames

This page makes 87 parallelizable requests to upload.wikimedia.org. Increase download parallelization by distributing the following requests across multiple hostnames.
Recommendation: Use multiple domains?

AIUI we're doing the exact opposite and cutting down on the number of domains to take advantage of SPDY (T94896: Optimize prod's resource domains for SPDY/HTTP2).

The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers

They use ETAGs and should be cached.

Jhernandez renamed this task from Make a performance audit of the mobile site. to Make a performance audit of the mobile site.Aug 13 2015, 6:14 PM
Jhernandez removed bmansurov as the assignee of this task.
Jhernandez updated the task description. (Show Details)
Jhernandez edited a custom field.

I'm pushing this again for next sprint, and updated the task description:

After ResourceLoader made scripts async the performance profile has probably changed a lot and we should re-run this audit and see what else we can find out.

See initial description and comments for the previous audit and discussion.

Let's see what else we can find out now that the performance profile has changed this much.

Had a look and don't fully follow how images are blocking the firstpaint? I did a quick test using WebPageTest and a Nexus 5 (they have a couple of real phones that we can use for testing, that is really cool!) and it looks like this for me:

http://www.webpagetest.org/video/compare.php?tests=150818_W7_abc0d7e94a3d1f62d29af41ff4f3f99f-r:1-c:0

You can scroll the screenshots and it will correlate to the waterfall graph below so we can see when assets are loaded and what's visible for the user on the phone. If we could sit down together we could go through WebPageTest and how we can use it. For now it's great to manually run tests to get the data, but it would be really great if we could automate it in the future and push the metrics to Graphite.

About sharding domains: How does our traffic on mobile looks like, how high percentage is using SPDY? Would be cool if we could get rid of the Initial Connection and the SSL Negotiation for upload.wikimedia.org (http://calendar.perfplanet.com/2013/spdy-domain-sharding/).

Not 100% sure but it looks like the upload.wikimedia.org takes 2 RTT for SSL?

Ran a few tests:
http://www.webpagetest.org/result/150825_9V_1AYZ/
http://www.webpagetest.org/result/150825_G5_1BVC/
http://www.webpagetest.org/result/150825_5Z_1BZ6/
Feel free to analyse them and run your own analysis.

Chatted with @Peter today, worth noting that first paint is never going to be better on mobile than desktop due to speed. @Peter has also suggested that Speed index may be worth exploring as a new metric (aim for 1000 - metric of when we think a user feels a screen is ready).

We also chatted about the size of HTML such as navboxes on larger pages, and whether instead of hiding them in css we should be trimming them from the HTML. Definitely seems worth exploring and measuring for a select group of pages...

More when I've had time to digest, just wanted to update the remotees.

I chatted to Peter yesterday and he suggested using slower connection (2G) and emulating real mobile devices (currently limited locations but Dulles is good). here's my analysis @Peter please feel free to correct me with my naive takeaways and maybe we can discuss this tomorrow and take this further. Right now I'm focusing on first view and first paint, given that improving on that is our current quarterly goal. I've just looked at load time so far.

@Jhernandez @bmansurov @phuedx please feel free to continue where I'm leaving off so we can get this card wrapped up.

Goal: How is our first paint on a super slow connection
Report: http://www.webpagetest.org/result/150825_9V_1AYZ/
Page used: Barack Obama
Page HTML size: 1MB
Conditions: Dulles, VA - Nexus 5 - Chrome - 2G

This was a bit of disaster over 9 runs. I thought this was a blip and run it a second time and results are consistent - the page fails to load.
Looking at the network tab the HTML just fails to load (only 67.8 KB get downloaded in one of the tests, 98.4 KB in another and 89.1 KB in a third). The HTML for the full article is actually 1MB. First paint happens around 32.5s-40s and all requests get cancelled .
(see http://www.webpagetest.org/video/compare.php?tests=150825_9V_1AYZ-r:8-c:0)

On one of the test runs [http://www.webpagetest.org/result/150825_9V_1AYZ/1/details/] it manages to download the css/js but it gives up downloading the HTML.

Takeaways:
Big pages of HTML on mobile 2G connections do not fully render - we need to provide a better solution for these browsers. We should investigate this further and identify why this happens and ways to solve it.

We could explore ways to reduce HTML size - e.g. using MobileFormatter again to strip HTML we do not render e.g. navboxes rather than relying on css - we may find this enables rendering on articles such as Barack Obama.

Goal: I decided to try a smaller page with the same kind of connection. If we can't give people big pages how do we fare on stub articles?
Report: http://www.webpagetest.org/result/150826_Y4_1898/
Page used: Tona (beer)
Page HTML size: 15K
Conditions: Dulles, VA - Nexus 5 - Chrome - 2G

Page didn't fully load and lots of HTTP errors but the page did render UI (which never happened in previous example)
Looking closely you can see the CSS and HTML block the first paint which happens at 14.5 seconds. Content downloads in 1207 ms. 2085 ms for first byte for the HTML.

Takeaways:

  • The JS startup module doesn't block any more.
  • Reducing page HTML will still not solve rendering of Wikipedia on slower connections but it will at least visually not appear broken.
  • We should explore if time to first byte for mobile is the same as desktop and if not why not. We should profile where things slow down.

3rd Test: 3G on a large page
Page used: Facebook
Conditions: Dulles, VA - Chrome - 3G
Report: http://www.webpagetest.org/result/150825_G5_1BVC/

First paint kicks in around 3 seconds. Single requests for the HTML and CSS block it.
Time to byte for css and js is around 901 ms. It's only 320 ms for the HTML. It seems there might be an opportunity to dig deeply into whether we can improve that time to first byte.
CSS takes 401 ms to download. The startup module 574 ms so the bulk of the request is in waiting for the server to respond.

In some cases the request for mediawiki/jquery appears to block the first paint but I don't understand why (@Peter am I looking at this correctly?)

Takeaways:

  • Can we improve time to first byte for resource loader requests?
  • Given the css is completely in our control we should minimise top loaded css as much as possible to reduce the content download as much as possible.

Re-ran the original test with the similar settings (except, the location is changed from New York to Central Asia). Here are the results:

110 requests
1.6 MB transferred
Finish: 20.49 s
DOMContentLoaded: 17.08 s
Load: 20.49 s
First paint: 4.27 s

I also ran the same test with similar settings at webpagetest.org and here are the results:
http://www.webpagetest.org/result/150827_4T_1XZ/ The 9 tests ran about an hour but without any data unfortunately.

In conclusion, I didn't notice noticeable speed improvements after the async change.

@bmansurov when I view that I get "First View: Test Data Missing"
Could you clarify what you mean by "I didn't notice noticeable speed improvements after the async change." This doesn't seem to be consistent with the values you reported.

Values you reported now:
DOMContentLoaded: 17.08 s
Load: 20.49 s
First paint: 4.27 s

Values reported before:
DOMContentLoaded: 16.15s
Load event: 17.45s
First paint: 12.79s

Seems first paint has radically decreased and everything else has suffered - any ideas why?

110 requests
1.6 MB transferred
Finish: 20.49 s
DOMContentLoaded: 17.08 s
Load: 20.49 s
First paint: 4.27 s

Yes, the data is missing, so I just compared the results from Chrome dev tools. True, the first paint is faster, but the other values are about the same. I'm not sure why, probably related to my location. To me the first paint is just a perceived speed gain, but the real gain would be the last paint.

Good news: First paint is no longer a problem and much better on mobile than desktop given the same connection.

Here are my conclusions on where the best gains now sit:

  • Size of HTML and CSS are the main blockers to first paint
    • Let's explore compressing HTML before sending it T110612
    • HTML micro-optimisations such as T100377
    • Using MobileFormatter again to remove HTML from page rather than hiding it in CSS in theory should impact first paint but needs testing. T110613
    • CSS micro-optimisations to css in the head. T97289
  • Images are a huge bottleneck. They start downloading at the same time as the startup module. This slows down retrieval of the startup module and css and thus impacts first paint and loading of further code.
    • T19577 will help subsequent page loads but not first view.
    • With help from @Peter we ran a test [1] with images disabled [2] on Barack Obama on 2G connection. We only did 2 pages but first paint halved from 40s to 20s. This is huge. We should explore this. T110615
    • The JS startup module in current implementation blocks further loading of any other code. It's 49.3KB - can we reduce it in any way? We should run an audit on jQuery but also mediawiki so we are clear on whether this is an avenue worth exploring - T100254

[1] http://www.webpagetest.org/result/150827_ZB_1A46/
[2] Using this Set script`:

setCookie https://en.m.wikipedia.org enwikidisableImages=1
navigate https://en.m.wikipedia.org/wiki/Barack_Obama

Out of those in priority order here's my top 3 things I think we should focus on:

Thanks @Jdlrobson! That's awesome.

Good news: First paint is no longer a problem and much better on mobile than desktop given the same connection.

Here are my conclusions on where the best gains now sit:

  • Size of HTML and CSS are the main blockers to first paint
    • Let's explore compressing HTML before sending it T110612

As @Gilles says I don't think this will help given we gzip it. It may even make gzipping more inefficient. We could probably test it out.

  • Using MobileFormatter again to remove HTML from page rather than hiding it in CSS in theory should impact first paint but needs testing. T110613

I thought we're not doing this because it slowed the backend performance quite a bit? We could probably experiment and see if it is worth it, definitely could bring a huge cut on html size on certain articles.

  • Images are a huge bottleneck. They start downloading at the same time as the startup module. This slows down retrieval of the startup module and css and thus impacts first paint and loading of further code.
    • T19577 will help subsequent page loads but not first view.
    • With help from @Peter we ran a test [1] with images disabled [2] on Barack Obama on 2G connection. We only did 2 pages but first paint halved from 40s to 20s. This is huge. We should explore this. T110615
    • The JS startup module in current implementation blocks further loading of any other code. It's 49.3KB - can we reduce it in any way? We should run an audit on jQuery but also mediawiki so we are clear on whether this is an avenue worth exploring - T100254

[1] http://www.webpagetest.org/result/150827_ZB_1A46/
[2] Using this Set script`:

setCookie https://en.m.wikipedia.org enwikidisableImages=1
navigate https://en.m.wikipedia.org/wiki/Barack_Obama

Have we ever explored lazy-loading images if there are more than a certain number? Certainly seems like a very interesting improvement for big articles. It may break the gallery though.

Out of those in priority order here's my top 3 things I think we should focus on:

Agreed, moved them to next sprint and fixed projects, etc.

Closing off for now, may reopen in the future :)