what does the browser pre-loader do?
DESCRIPTION
Slides from talk at London Webstandards (Sept 2014) on what the browser preloader is, how it works and why we need itTRANSCRIPT
![Page 1: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/1.jpg)
https://www.flickr.com/photos/benjreay/14713228051
What does the browser pre-loader do?
@andydavies Sept 2014
![Page 2: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/2.jpg)
The Preloader!
A.K.A.!
look-ahead or speculative pre-parser
![Page 3: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/3.jpg)
What if you could make your pages load 20% faster?https://www.flickr.com/photos/chrisjohnbeckett/10446312055
![Page 4: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/4.jpg)
preloading is the single biggest performance improvement browsers have ever made
Steve Souders, April 2013
https://hacks.mozilla.org/2013/03/capturing-improving-performance-of-the-adaptive-web/comment-page-1/#comment-2060698www.stevesouders.com/blog/2013/04/26/i/
![Page 5: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/5.jpg)
most destructive “performance enhancement”!I think there’s ever been
Matt Wilcox, creator of Adaptive Images, March 2013
Matt’s point is a bit more nuanced than this, read the full discussion:!https://hacks.mozilla.org/2013/03/capturing-improving-performance-of-the-adaptive-web/comment-page-1/#comment-2060698
![Page 6: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/6.jpg)
What’s our greatest enemy?
https://www.flickr.com/photos/54459164@N00/5218183788
![Page 7: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/7.jpg)
The browser that just won’t die?
![Page 8: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/8.jpg)
The explosion in device diversity?
http://opensignal.com/reports/2014/android-fragmentation/
![Page 9: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/9.jpg)
… or maybe latency is our greatest enemy
https://www.flickr.com/photos/jjvaca/728072059
![Page 10: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/10.jpg)
At best network packets travel at roughly 2/3 speed of light
https://www.flickr.com/photos/98640399@N08/9287370881
![Page 11: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/11.jpg)
London to New York Round Trip Time = 56ms over fibre!
https://www.flickr.com/photos/dpapworth/482125035https://www.flickr.com/photos/lwr/6979975029
![Page 12: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/12.jpg)
TCP and the Lower Bound of Web Performance John Rauser
Might take more than one round trip
71kB
143kB
214kB
285kB
1 2 3 4 5 6 7 8 9 10 11
(TCP Segments)
Round Trips
Size
![Page 13: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/13.jpg)
So what’s this got to do with the preloader?
![Page 14: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/14.jpg)
Let’s pretend we’re a browser (with the preloader switched off)
https://www.flickr.com/photos/mozillaeu/11171168996
![Page 15: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/15.jpg)
Two key rules to remember
Constructing CSS Object Model (CSSOM) blocks JavaScript execution!!
JavaScript blocks DOM construction
![Page 16: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/16.jpg)
GET example.html HTTP/1.1
![Page 17: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/17.jpg)
GET example.html HTTP/1.1
![Page 18: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/18.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 19: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/19.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 20: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/20.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
GET /styles.css HTTP/1.1
![Page 21: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/21.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 22: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/22.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
GET /more-styles.css HTTP/1.1
![Page 23: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/23.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 24: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/24.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
GET /script.js HTTP/1.1
![Page 25: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/25.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 26: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/26.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
Must wait for:!1. CSS download and OM construction!2. JS download and execution
![Page 27: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/27.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 28: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/28.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
GET /another-script.js HTTP/1.1
![Page 29: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/29.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 30: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/30.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
Must wait for:!1. JS download and execution
![Page 31: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/31.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 32: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/32.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
GET /image.jpg HTTP/1.1
![Page 33: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/33.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
![Page 34: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/34.jpg)
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link href="styles.css" rel="stylesheet"> <link href="more-styles.css" rel="stylesheet"> <script src="script.js"></script> <script src="another-script.js"></script> <title>HTML Example</title> </head> <body> <h1>Title</h1> <p>Some introductory text and picture! <img src="image.jpg"/></p> <p>Some more text and another picture! <img src="image-2.jpg"/></p> </body> </html>
example.html
GET /image-2.jpg HTTP/1.1
![Page 35: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/35.jpg)
What does the waterfall look like?
WebPagetest - IE7, Cable, Korea
scripts download in series
![Page 36: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/36.jpg)
What if we decouple resource discovery from DOM construction?
When DOM construction is blocked !! e.g. waiting for script to download and execute!!
Search rest of document for external resources!! e.g. <link rel=“stylesheet”…>, <script src=…>, <img src=…>!!
Download and cache discovered resources ready for DOM construction
![Page 37: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/37.jpg)
IE 7 (doesn’t have a preloader)
IE 11 (has a preloader)
scripts download in series
parallel download, execution still in series
![Page 38: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/38.jpg)
link rel=“stylesheet” ✓ ✓ ✓ ✓ ✓<script src= ✓ ✓ ✓ ✓ ✓<img> ✓ ✓ ✓ ✓ ✓@import ✓ ✓ ✓<video poster> ✓<picture> <img> ✓ ✓
What gets preloaded?
http://yoavweiss.github.io/preloader-velocity-nyc-talk
![Page 39: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/39.jpg)
Script inserted resources aren’t discoverable
<script type="text/javascript"> function() { var js = document.createElement('script'); js.async = true; js.src = 'script.js'; var e = document.getElementsByTagName('script')[0]; e.parentNode.insertBefore(js, first); })(); </script>
Browser won’t discover script until outer script inserts it into DOM
![Page 40: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/40.jpg)
Non-blocking loading using async attribute
!
<script async src="script.js"></script>
Widely supported (82%) and discoverable by preloader
![Page 41: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/41.jpg)
Limits to what preloader can discover
HTML
CSS
DOM
CSSOM
Render!Tree Layout PaintJavaScript
![Page 42: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/42.jpg)
Limits to what preloader can discover
HTML
CSS
DOM
CSSOM
Render!Tree Layout PaintJavaScript
Fonts and background images discovered when render tree builds
![Page 43: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/43.jpg)
Possible workarounds?
dataURIs (will make CSS larger)!
HTTP/2 or SPDY server push!
<link rel=“subresource… (Chrome only and effectively broken)
![Page 44: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/44.jpg)
Download order != Document orderhttps://www.flickr.com/photos/add1sun/4993432274
![Page 45: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/45.jpg)
Browsers can prioritise download order
Based on:!
! Resource type - CSS, JS, image etc.!
! Visibility!
! Element attributes e.g. <script async, defer!
! W3C Resource Priorities
![Page 46: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/46.jpg)
W3C Resource Priorities - adds lazyload attribute (also look at Ilya Grigorik’s proposal for Resource Hints)
![Page 47: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/47.jpg)
Prioritisation sometimes has unexpected consequences
Major UK retailer’s site in Chrome
![Page 48: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/48.jpg)
Prioritisation sometimes has unexpected consequences
These JS resources are at the foot of the body!(perhaps they should merge them into fewer resources but…)
![Page 49: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/49.jpg)
Prioritisation sometimes has unexpected consequences
Downloading the JS blocks the hero image
![Page 50: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/50.jpg)
Some edge cases you might come across
![Page 51: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/51.jpg)
Watch out for the parser restarting
![Page 52: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/52.jpg)
Watch out for the parser restarting
Content-Type: text/html !
charset isn’t specified in HTTP response so IE9 assumes ISO 8859-1 !
As it parses the HTML it then finds !
<meta charset=“utf-8"> !
Similar issues can occur with <base>
![Page 53: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/53.jpg)
Do odd things and you may get odd behaviour!<html> <head> <script> var file = window.innerWidth < 1000 ? "mobile.css" : "desktop.css"; document.write('<link rel="stylesheet" type="text/css" href="css/' + file + '"/>'); </script> </head> <body> <img src="img/gallery-img1.jpg" /> <img src="img/gallery-img2.jpg" /> <img src="img/gallery-img3.jpg" /> <img src="img/gallery-img4.jpg" /> <img src="img/gallery-img5.jpg" /> <img src="img/gallery-img6.jpg" /> </body> </html> This is based on a suggested Stack Overflow answer!
![Page 54: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/54.jpg)
Do odd things and you may get odd behaviour!
IE 9Download of CSS blocked by images
![Page 55: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/55.jpg)
Can use Cuzillion to test simple scenarios
https://www.stevesouders.com/cuzillion/
![Page 56: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/56.jpg)
Latency is web performance enemy #1!
Preloader helps hide the latency!
Can only ‘see’ resources in markup!
May not load resources in order we intend!
Getting methods to hint our intent to browsers
![Page 57: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/57.jpg)
https://www.flickr.com/photos/auntiep/5024494612
!
@andydavies!!
http://slideshare.net/andydavies!
![Page 58: What does the browser pre-loader do?](https://reader031.vdocuments.net/reader031/viewer/2022013100/54682220af7959f9288b6fe1/html5/thumbnails/58.jpg)