please dont touch-3.6-jsday
DESCRIPTION
More and more often we talks about optimizing the server-side software, but thetrue optimization must be done on the client where 80% of the time is spentby users. The talk explains the main techniques to optimizeWeb site using HTTP protocols and rules to the base but rarelyused.TRANSCRIPT
![Page 1: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/1.jpg)
Please Don’t Touch the Slow Parts V3.6
[email protected]://www.ideato.it/
[email protected]://www.cleancode.it/
![Page 2: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/2.jpg)
Approved by Steve Souders
![Page 3: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/3.jpg)
![Page 4: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/4.jpg)
faster
![Page 5: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/5.jpg)
WEBfaster
![Page 6: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/6.jpg)
Faster == Better?
![Page 7: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/7.jpg)
We have to wait
![Page 8: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/8.jpg)
... All the time
![Page 9: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/9.jpg)
“Savings in timefeels like simplicity”
![Page 10: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/10.jpg)
“Time is the only commodity that matters”
![Page 11: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/11.jpg)
Psychology of webperformance
http://www.websiteoptimization.com/speed/tweak/psychology-web-performance/
5-8SECONDS
![Page 12: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/12.jpg)
Faster web, more clicks
http://www.stevesouders.com/blog/2009/07/27/wikia-fast-pages-retain-users/
![Page 13: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/13.jpg)
Faster web, better SEO
http://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html
![Page 14: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/14.jpg)
Faster web is hot
![Page 15: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/15.jpg)
Say web, Say browser
![Page 16: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/16.jpg)
How browsers work
![Page 17: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/17.jpg)
User clicks on a link
![Page 18: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/18.jpg)
Browser resolves domain name
www.google.com
72.14.234.104
DNS
UDP
domaindomain
![Page 19: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/19.jpg)
Browser connects to web server
TCP/IP
72.14.234.104
WEB
domaindomain connectconnect
![Page 20: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/20.jpg)
Browser sends arequest for a page
HTTP
GET /language_tools?hl=enHost: www.google.com
domaindomain connectconnect sendsend
WEB
![Page 21: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/21.jpg)
Browser receives a response with the page
HTTP
200 OK
domaindomain connectconnect sendsend receivereceive
WEB
![Page 22: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/22.jpg)
Browser renders the new page
domaindomain connectconnect sendsend receivereceive renderrender
![Page 23: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/23.jpg)
Rendering is complexrenderrender
![Page 24: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/24.jpg)
Rendering isloading resources
renderrender
csscsscsscss
imgimgimgimg
csscsscsscss
imgimgimgimg
javascriptjavascriptjavascriptjavascript
javascriptjavascriptjavascriptjavascript
flashflashflashflash
![Page 25: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/25.jpg)
Each resource is another web request
renderrender
![Page 26: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/26.jpg)
Requests areprocessed in parallel
renderrender
![Page 27: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/27.jpg)
Rendering is parsingrenderrender
HTML
CSS
DOM TREE
STYLE STRUCT
<html> <head> <title>Title</title> </head> <body> <div>This is a Text</div> <div id="hidden">Hidden</div>
body { padding: 0;}#hidden { display: none;}
- document - elem: html - elem: head - elem: title - text: Title - elem: body - elem: div - text: This is a Text - elem: div - attr: id=hidden - text: Hidden
- selector: body rule: display: block # default css padding-bottom: 0px # site css padding-left: 0px # site css padding-right: 0px # site css padding-top: 0px # site css- selector: hidden rule: display: none # site css
![Page 28: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/28.jpg)
Rendering is layoutrenderrender
DOM TREE
STYLE STRUCT
- document - elem: html - elem: head - elem: title - text: Title - elem: body - elem: div - text: This is a Text - elem: div - attr: id=hidden - text: Hidden
- selector: body rule: display: block # default css padding-bottom: 0px # site css padding-left: 0px # site css padding-right: 0px # site css padding-top: 0px # fsite css- selector: hidden rule: display: none # site css
- root - body - block - inline: This is - inline: a Text
RENDER TREE
reflow
![Page 29: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/29.jpg)
Rendering is paintingrenderrender
- root - body - block - inline: This is - inline: a Text
RENDER TREEThis is
a Text
repaint
![Page 30: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/30.jpg)
Rendering is execution
mouse movedmouse moved mouse pressedmouse pressed mouse releasedmouse released key pressedkey pressed key releasedkey released
renderrender
INPUT
OS
EVENT QUEUE
![Page 31: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/31.jpg)
Execution in one thread
mouse movedmouse moved mouse pressedmouse pressed mouse releasedmouse released key pressedkey pressed key releasedkey released
renderrender
EVENT QUEUE
JavascriptJavascript
ExecutionExecution
NativeNativeBrowserBrowserActionAction
![Page 32: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/32.jpg)
Once upon a time...
Few resources
Static pages
Less javascript
![Page 33: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/33.jpg)
Most time on serverdomaindomain connectconnect sendsend receivereceive renderrender
![Page 34: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/34.jpg)
Solution is faster serverside
domaindomain connectconnect sendsend receivereceive renderrender
![Page 35: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/35.jpg)
Ajax revolution
![Page 36: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/36.jpg)
Ajax revolution
performance
![Page 37: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/37.jpg)
Page updating
One time(classic) WEB
![Page 38: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/38.jpg)
On demand(ajax) WEB
... later ...
Page updating
![Page 39: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/39.jpg)
Continuous(polling)
WEB
Page updating
![Page 40: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/40.jpg)
Push(comet)
WEB
Page updating
![Page 41: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/41.jpg)
Most time on browserdomaindomain connectconnect sendsend receivereceive renderrender
![Page 42: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/42.jpg)
Golden rule of faster web
80% of the end user response time is spent
on the front-end
![Page 43: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/43.jpg)
Start there.
Golden rules of faster web
![Page 44: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/44.jpg)
Why webslow parts?
![Page 45: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/45.jpg)
Easy to understand
![Page 46: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/46.jpg)
Each part has its rules
![Page 47: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/47.jpg)
Which parts are slow?
![Page 48: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/48.jpg)
Network is slow
![Page 49: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/49.jpg)
Less stuffFewer requests
Concatenate js/cssCss spritesInline images
Too many resources
![Page 50: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/50.jpg)
Less stuffCache requests
Expires headerRevving FilesExternal js/cssRemove etags
Resourcesre-downloaded
![Page 51: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/51.jpg)
Smaller stuffCompress responses
Content-EncodingGzipDeflate
Resources are too big
![Page 52: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/52.jpg)
Smaller stuffMinify responses
js, css, htmlremove formattingremove commentsoptimize imagesuse tools
Resources are too big
![Page 53: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/53.jpg)
Closer stuffUse a CDN
Resources are too far
reduce latency
![Page 54: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/54.jpg)
Closer stuffFlush document
early
Server can be slow
Chunked encoding
![Page 55: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/55.jpg)
Browser is slow
![Page 56: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/56.jpg)
Scripts block loading
javascriptjavascriptjavascriptjavascript
csscsscsscss
javascriptjavascriptjavascriptjavascript
imgimgimgimg
flashflashflashflash
document.writelocation.hrefscripts order
htmlhtmlhtmlhtml
imgimgimgimg
![Page 57: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/57.jpg)
csscsscsscss
Put scripts at bottom
javascriptjavascriptjavascriptjavascript
javascriptjavascriptjavascriptjavascript
imgimgimgimg
imgimgimgimg
flashflashflashflash
htmlhtmlhtmlhtml
![Page 58: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/58.jpg)
csscsscsscss
Unloaded stylesblock page rendering
htmlhtmlhtmlhtml
imgimgimgimg
imgimgimgimg
flashflashflashflash
![Page 59: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/59.jpg)
csscsscsscss
htmlhtmlhtmlhtml
imgimgimgimg
imgimgimgimg
flashflashflashflash
Put styles at top
![Page 60: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/60.jpg)
Indeed... scripts block everything
![Page 61: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/61.jpg)
Load scripts asynchronously
var scriptTag = document.createElement("script")scriptTag.src = "http://www.example.org/js/lib.js"
document.getElementsByTagName("head")[0] .appendChild(scriptTag)
![Page 62: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/62.jpg)
Yield with timers
// doSomethingLong() is too slow, split it
doSomething()
setTimeout(function() { doSomethingElse()}, 50)
![Page 63: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/63.jpg)
Browser I/Ois slow
![Page 64: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/64.jpg)
Browser I/Ois slow
DOM
DoG
![Page 65: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/65.jpg)
is alive
Collections to arraysCache values to variables
DOM access triggers a live query
DOM
![Page 66: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/66.jpg)
triggers events
Event Delegation
Events execute JS code
DOM
![Page 67: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/67.jpg)
Reflow is expensive
Batch DOMchanges “offline”
Cloned elementDocument FragmentDisplay: none
![Page 68: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/68.jpg)
Reflow is expensive
Batch CSS changes
One class to rule em allDynamic style property
![Page 69: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/69.jpg)
Inefficient element location
CSS are bottom-up!
Be specific on the “right”
#header li a direction
![Page 70: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/70.jpg)
Inefficient element location
Go native in DOM
getElementByIdXpathquerySelectorAll
![Page 71: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/71.jpg)
Rules pitfalls
![Page 72: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/72.jpg)
Panta reiBrowserscope
http://www.browserscope.org/
![Page 73: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/73.jpg)
Expect the unexpected
empty cacheno compression
![Page 74: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/74.jpg)
Know your usersTrack user capabilities
![Page 75: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/75.jpg)
Conflicting rulesDNS vs ParallelInline vs ExternalConcatenated vs Reuse
![Page 76: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/76.jpg)
All that glittersis not gold
![Page 77: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/77.jpg)
Everything is atradeoff
![Page 78: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/78.jpg)
performance bringscomplexity
![Page 79: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/79.jpg)
know the rules but...
![Page 80: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/80.jpg)
leave complexityto computers
![Page 81: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/81.jpg)
use librariesduring development
![Page 82: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/82.jpg)
Use toolsat build time
http://code.google.com/speed/tools.html
![Page 83: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/83.jpg)
Code smartat run time
http://www.slideshare.net/ajaxexperience2009/david-wei-and-changhao-jiang-presentation
AdaptiveOptimization
![Page 84: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/84.jpg)
http://abetterbrowser.org/
9
![Page 85: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/85.jpg)
Questions?
Rate us on joind.inhttp://joind.in/3364
![Page 86: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/86.jpg)
12, 14 May - Verona
www.phpday.it
![Page 87: Please dont touch-3.6-jsday](https://reader038.vdocuments.mx/reader038/viewer/2022102901/555838d6d8b42ac6078b4a1b/html5/thumbnails/87.jpg)
27, 28 June - Florence
Come and see“don't touch the... mobile parts“
www.bettersoftware.it