TURNING MOODLEWEBINTOA PROGRESSIVE WEB …...Web App stands for any web app, like Moodle! Pstands...
Transcript of TURNING MOODLEWEBINTOA PROGRESSIVE WEB …...Web App stands for any web app, like Moodle! Pstands...
TURNING MOODLE WEB INTO APROGRESSIVE WEB APP (PWA)
June2018
MitxelMorianaDeveloper@3iPuntMoodlePartner
WHAT IS A PWA ?
WebAppstandsforanywebapp,likeMoodle!
P standsforprogressiveor“optionallyenhanced”:
if browser supports this cool feature {use it
} else {// no problem! Do nothing
}
TYPICAL EXAMPLES OF “PROGRESSIVENESS”
if('serviceWorker'innavigator){register our Service Worker
}
if('serviceWorker'innavigator&&'PushManager'inwindow){wecanusethe Push APIinour Service Worker
}
if('caches'inwindow){we canusethe CacheStorage APItoaccess storages/caches(i.e.:key-value pairs,request-responsespairs)shared by the window andthe Service Worker
}
THE SERVICE WORKER (I)
Notbeconfusedwithasharedworker
Event-drivenscript (writteninJS)run(whenneeded)bythebrowserinthebackground (i.e.:initsowncontext/thread,nottiedtoapage,nodirectDOMaccess).
Allowsfortheinterception(onfetchevent)ofnavigation/requestswithinits“scope”(usually,butnotnecessarily,thewwwroot ofoursite).
THE SERVICE WORKER (II)
Allowsfor:• Cachingresponses(andservingthem)atclientlevel• Servingfallbackresponsestoerrors(oranycustomcondition)
• Pre-caching ofresponses/resources• Backgrounddatasynchronization(periodic datasyncis“experimental)
• Pushnotifications
Ideally==whenpossible==ifwedoitright;• Fasternavigation• Offlinenavigation• Happierusers(also,happierdevelopers)
TURNING MOODLE INTO A PWACAUSE STUDY OF ELE.ME(MPA)
Skeletonscreen+PRPLpattern(Preload criticalresources, Render initialroute, Pre-cache remainingroutes, Lazy-load remainingroutes).
Results:• Loadingtimedecreasedby11.6%acrossallpre-cachedpages• Loadingtimedecreasedonaverageby6.35%acrossallpages.• Time-to-consistently-interactivedroppedto4.93secondsona3Gnetworkonfirstload
Moreinfo:https://h5.ele.me/https://medium.com/elemefe/upgrading-ele-me-to-progressive-web-app-2a446832e509
TURNING MOODLE INTO A PWATHE OFFLINE FALLBACK VIEW
Pre-cacheanofflineviewanduseitasanofflineresponsefallback(fornon-cachedviewrequest/responses).
TURNING MOODLE INTO A PWACACHING STATIC CONTENT (I)CachingJS,CSS,images,fonts…whenrequestedatleastonce.
Moodleservesoptimizedstaticcontentusingspecificscripts:theme/styles.php – serves“theonehugeCSSofeachtheme”theme/font.php – serves“thefontsusedinCSS”theme/yui_combo.php – serves“yui Javascript andCSS”theme/image.php – serves“theonethemeandpluginimages”lib/javascript.php – serves“optimised JS”lib/requirejs.php – serves“optimised JSforRequireJS”
TheURLstothesescriptscontaintheme/script“versioning”parameters:Newversions=>differentrequestURL=>noconflict updatedvscached
TURNING MOODLE INTO A PWACACHING STATIC CONTENT (II)Choosingthe“right”servingandcachingstrategy/recipe:
DoestheURL(includingparameters)alwaysreturnsthesamecontent?
ifyes {Use“cacheonly”(ifpre-cached!)or“cachefirst”servingstrategies(anddynamicallycachethem)
}elseifnotalways,buttoloadthemostrecentversionISNOTessential{Use“stalewhilerevalidate”serving/cachingstrategy(servecachedifexistsbutcheckinbackgroundforanupdateandcacheupdatedresourcewhenneeded)
}elseifnotalways,buttoloadthemostrecentversionISessential{Use“networkfirst”servingstrategy(anddynamicallycachenewestversion,butusethemonlyasafallback)
} elseifnoandnever{Areyousureitisstatic content?Whydoweneedtocacheit?
}
TURNING MOODLE INTO A PWACACHING STATIC CONTENT (III)
LighthouseauditMobileemulated,3Gthrottled“secondvisit”,i.e.withbrowsercachepreserved.
With ServiceWorkerservingcachedstaticcontent:1260ms (firstmeaningfulpaint)Without ServiceWorker:1430ms (firstmeaningfulpaint)
“Firstmeaningfulpaint”was170ms faster =improvement of~10%inthe“user-perceivedloadingexperience”
TURNING MOODLE INTO A PWACACHING STATIC CONTENT (IV)
WITHSW WITHOUTSW
TURNING MOODLE INTO A PWAHOME SCREEN &MANIFEST.JSON (I)manifest.json{
appname andshort_name,icons (icons andsplashscreens),related_applications (web,playstore…),start_url (startingurl,itcouldbetheroot/),display(standalone=“appish”,browser…),scope(scopeurl,likeforexampletheroot/)backgroundandtheme_color(#f98012),...
}+<linkrel="manifest"href="/manifest.json">+convenientmetatags…+https+¿useconditions?=Browserpromptstheusertoinstallthehomescreen/Addtohomescreenmenuoptionappears
MOBILE
TURNING MOODLE INTO A PWAHOME SCREEN &MANIFEST.JSON (II)
Youcansetthemanifest.json inawaythattheusercanbepromptedtoinstallthemobileappfromthestores (insteadofasa“link”tothePWA)
¿MoreconvenientforcustomersthathavetheirownMoodleMobileapp?
{…related_applications:[{ platform:web},{platform:play,id:com… }]prefer_related_applications:true
}
MOBILE
TURNING MOODLE INTO A PWAHOME SCREEN &MANIFEST.JSON (III)
DESKTOP (CHROMEAPPS)MOBILEHOMESCREEN
MOBILESPLASHSCREENEXAMPLE
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (I)
Oneidea…CachingthemostusedviewsinagivenMoodleinstance…
Whichviewsarethemost“used”inagivenMoodleinstance?
ANALYTICScantellusà
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (II)
PROBLEM!Manyroutesservedifferentcontentwhenauthenticated/not-authenticated.Eg:• Whilenotauthenticatedallroutes“serves”(redirectto)theloginpage.• User-specificcontent(e.g.:samecourseroute,differentuser/userrole).
Wecouldevaluatethesessioncookiecredentialsinourservingstrategies…Butdowereallywanttocachetheresponse(froman“authenticated”context)andmakeitpubliclyavailabletoanyonewithaccesstothebrowser?
¿Appshelltotherescue?
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (III)
TheAppShellapproach(asIunderstandit)->Refactorparty!
• Removealluser-specific/authentication-neededdatafromALLTHEVIEWSANDLAYOUTS
• Rendertheviewspecificinformationusingasynchronouslycalledwebservices(withtheproperloginandcapabilitieschecks)
• Renderthelayout“user-related”elementsandinformationthesameway(e.g.:theusermenu,thecoursenavigationpanel…)
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (IV)
Refactoringparty withthemod_url view.php ->/mod/url/view.php
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (V)
+webservicetoservethemod_url view.php content(all“view”cases)
mod/url/classes/external.phpload_view
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (VI)App-shelled mod_url view >>>
User,session… relatedinformation removedfrom theviewsNouser menu,nonavigationmenu,nofooter user-relatedlinks,nomod_url view-specificdata…
This is our “appshell”,let’scachethis!(stalewhilereval?cachefirst?)
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (VII)Then we loadasynchronouslythe actualcontent behind authandcapabilities checks
This is the mod_url viewcontent loaded from awebservice.
Dothe same with theinformation removedfrom thelayout!->webservice +asyncloading
TURNING MOODLE INTO A PWACACHING PAGE VIEWS (VIII)
Lighthouse audit (without refactoring the layout,just the mod_url view)
Appshellapproach:“Firstmeaningul paint”~600ms (halfthetime)
Caveats:Theactualcontent”appears”muchlater(+1secatleast)(onload)
TURNING MOODLE INTO A PWAADDING THE SERVICE WORKER TO THE MOODLE CORE?
• Allowforpluginstodefinetheirscopeandtiepluginroutestodifferentcachingstrategies/precaching (ServiceWorker API?).
• Createaphp scriptthatbuildsandservesa“revisioned”sw.js collectingandincludingallthoseplugindefinitionsacrossalltheMoodleinstanceplugins.
• Addadminsettingstoeasilyenable/disabletheinclusionoftheserviceworker.
• AddadminsettingstoeasilyincludeJScodethatunregisterspreviouslyadded
serviceworkersand/orforceclientstocleartheirstoragesandcaches(incase
somethingwentwrong…).
THANKS TO (POWERED BY)…
• 3iPunt: PauPlana,Ebrahim Mesleh &AntoniBertran
• 3iPunt“MoodleTeam”:
EvaPereira, RaúlMartínez&RoserPruaño
• All developers that have been documenting their
experiences with Service Workers since 2015.