Upload
others
View
21
Download
0
Embed Size (px)
Citation preview
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.