-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
403 lines (322 loc) · 13.7 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Introduction to Browser Internals</title>
<meta name="description" content="Introduction to Browser Internals">
<meta name="author" content="Artur Ciocanu">
<link href="resources/css.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="resources/reset.css">
<link rel="stylesheet" href="resources/main.css">
<link rel="stylesheet" href="resources/zenburn.css">
<style>
.highlight {
color: #FF8000;
}
</style>
</head>
<body>
<div class="linear" id="reveal">
<div class="slides">
<section style="display: block;" class="present">
<br><br>
<h1>Browser Internals</h1>
<h2 class="inverted">An Introduction</h2>
<script>
// Delicously hacky. Look away.
if( navigator.userAgent.match( /(iPhone|iPad|iPod|Android)/i ) )
document.write( '<p style="color: rgba(0,0,0,0.3); text-shadow: none;">('+'Tap to navigate'+')</p>' );
</script>
</section>
<section class="future" style="display: block;">
<h2>Main functionality</h2>
<p align="left">
The main function of a browser is to present the web resource you choose, by requesting it from the server and displaying it in the browser window. The resource is usually an HTML document, but may also be a PDF, image, or some other type of content.
</p>
</section>
<section class="future" style="display: block;">
<h2>Common User Interface</h2>
<p align="left">
All the browsers have common user interface, although it is not defined in any formal specification:
<ul>
<li>Address bar for inserting a URI</li>
<li>Back and forward buttons</li>
<li>Bookmarking options</li>
<li>Refresh and stop buttons for refreshing or stopping the loading of current documents</li>
<li>Home button that takes you to your home page</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>The browser's high level structure</h2>
<p align="center">
<img src="resources/browser-components.png" style="width:600px;height:439px"/>
</p>
</section>
<section class="future" style="display: block;">
<h2>User Interface</h2>
<p align="left">
Includes the address bar, back/forward button, bookmarking menu, etc. Every part of the browser display except the window where you see the requested page.
</p>
</section>
<section class="future" style="display: block;">
<h2>Browser Engine</h2>
<p align="left">
Marshals actions between the UI and the rendering engine.
</p>
</section>
<section class="future" style="display: block;">
<h2>Rendering engine</h2>
<p align="left">
Responsible for displaying requested content. For example if the requested content is HTML, the rendering engine parses HTML and CSS, and displays the parsed content on the screen.
</p>
</section>
<section class="future" style="display: block;">
<h2>Networking</h2>
<p align="left">
For network calls such as HTTP requests, using different implementations for different platform behind a platform-independent interface.
</p>
</section>
<section class="future" style="display: block;">
<h2>UI backend</h2>
<p align="left">
Used for drawing basic widgets like combo boxes and windows. This backend exposes a generic interface that is not platform specific. Underneath it uses operating system user interface methods.
</p>
</section>
<section class="future" style="display: block;">
<h2>JavaScript engine</h2>
<p align="left">
Used to parse and execute JavaScript code.
</p>
</section>
<section class="future" style="display: block;">
<h2>Data Persistence</h2>
<p align="left">
This is a persistence layer. The browser may need to save all sorts of data locally, such as cookies. Browsers also support storage mechanisms such as localStorage, IndexedDB, WebSQL and FileSystem.
</p>
</section>
<section class="future" style="display: block;">
<h2>Rendering engines</h2>
<p align="center">
Main flow
</p>
<p align="center">
<img src="resources/rendering-engines-flow.png" style="width:990px;height:166px"/>
</p>
</section>
<section class="future" style="display: block;">
<h2>WebKit rendering engine</h2>
<p align="center">
<img src="resources/webkit-flow.png" style="width:990px;height:466px"/>
</p>
</section>
<section class="future" style="display: block;">
<h2>Gecko rendering engine</h2>
<p align="center">
<img src="resources/gecko-flow.png" style="width:990px;height:466px"/>
</p>
</section>
<section class="future" style="display: block;">
<h2>A note on browser parsers</h2>
<p align="left">
<ul>
<li>HTML Parser - custom build, fault tolerant and re-entrant (discussed later)</li>
<li>CSS Parser - has BNF defined grammar</li>
<li>JavaScript Parser - has BNF defined grammar</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>HTML parsing</h2>
<p align="center">
<img src="resources/html-parsing-flow.png" style="width:408px;height:500px"/>
</p>
</section>
<section class="future" style="display: block;">
<h2>HTML parsing - dynamic markup insertion</h2>
<p align="left">
<ul style="color:#FF8800">
<li>document.open()</li>
<li>document.close()</li>
<li>document.write()</li>
<li>document.writeln()</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>HTML parsing - dynamic markup insertion</h2>
<p align="left">
<span class="highlight">document.write()</span> and friends blocks HTML parser, which blocks render tree construction, which subsequentely blocks layout and paint phase. In the end all of this leads to to big delays in the critical rendering path.
</p>
</section>
<section class="future" style="display: block;">
<h2>HTML parsing - example</h2>
<p align="left">
<pre style="font-size:30px">
<code language="HTML">
<html>
<body>
<p>
Hello World
</p>
<div>
<img src="example.png"/>
</div>
</body>
</html>
</code>
</pre>
</p>
</section>
<section class="future" style="display: block;">
<h2>HTML parsing - example</h2>
<p align="center">
<img src="resources/dom-tree-example.png" style="width:600px;height:319px"/>
</p>
</section>
<section class="future" style="display: block;">
<h2>Quick quiz</h2>
<p align="left">
Why it's recommended to have CSS files referenced in the HEAD and JavaScript files just before the BODY closing tag?
</p>
</section>
<section class="future" style="display: block;">
<h2>CSS</h2>
<p align="left">
<ul>
<li>Tells the browser what should be part of the render tee (element with display:none is not part of the render tree)</li>
<li>Has to be downloaded and parsed, no incremental CSSOM construction, unlike HTML parsing</li>
<li>Blocks rendering</li>
<li>Since JavaScript might need CSSOM data, CSS also blocks JavaScript execution</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>JavaScript</h2>
<p align="left">
<ul>
<li>SCRIPT tag blocks HTML parser</li>
<li>HTML 5 adds <span class="highlight">async</span> and <span class="highlight">defer</span> to mitigate HTML parser blocking</li>
<li>Execution is single threaded</li>
<li>Interaction with outside world is asynchronous. AJAX request, user events, etc all are handled asynchronously</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>JavaScript</h2>
<p align="left">
<ul>
<li>Single threaded, means no <span class="highlight">Thread.sleep()</span> or equivalent</li>
<li>You can't "block" JavaScript execution. You can ONLY defer execution via
<span class="highlight">setInterval()</span> or <span class="highlight">setTimeout()</span></li>
<li>Browser uses event queue for EVERYTHING, user events, timer events, networks events, paint/redraw etc</li>
<li>If processing an event queue item takes too long the browser freezes</li>
<li>Race conditions are still possible, especially when using AJAX and shared variables</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>JavaScript</h2>
<p align="left">
<ul>
<li>There is no block level scoping, if not declared with <span class="highlight">var</span> in a function, it's globally accessible</li>
<li>Immediately Invoked Function Expression AKA <span class="highlight">(function(){}())</span> is used to avoid global namespace pollution</li>
<li><span class="highlight">try / catch / finally</span> not so useful in asynchronous context</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>Demo time</h2>
<p align="left">
JavaScript + Web APIs + timer events + event queue visualization
</p>
</section>
<section class="future" style="display: block;">
<h2>Page loading</h2>
<p align="left">
<ul>
<li>DOM ready is abused, place element just before closing BODY tag and you should be good</li>
<li>DOM ready fired when DOM tree is constructed</li>
<li>Window load fired when DOM tree is constructed and all resources have been loaded</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>Waiting for DOM elements</h2>
<p align="left">
Usually when script is added to HEAD, but depends on HTML element being available. There are two approaches:
<ul>
<li>"Polling" via <span class="highlight">setInterval()</span></li>
<li><span class="highlight">MutationObserver</span> or <span class="highlight">Mutation Events (this has been deprecated)</span>.
Using <span class="highlight">MutationObserver</span> we can find out which elements are added, removed, inserted into DOM.</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>FOUC aka Flickering</h2>
<p align="left">
FOUC - Flash of unstyled content. FOUC root causes are:
<ul>
<li>Dynamically added stylesheets</li>
<li>Replacing visible parts of the page after it was rendered</li>
</ul>
</p>
</section>
<section class="future" style="display: block;">
<h2>Fighting FOUC</h2>
<p align="left">
<ul>
<li>DO NOT add stylesheets dynamically</li>
<li>DO NOT replace big chunks of the page after it has been rendered</li>
<li>If you absolutely have to do it, make sure you hide parts of the page, do the work and then display the new content. Most modern libraries employ this technique, Modernizr being on of them.</li>
</ul>
</p>
</section>
<section class="future" style="display: none;">
<h2>Conclusions</h2>
Browsers are really, really complex beasts. These can be seen as OS inside OS. Studying source code of open source browsers can be quite daunting, but rewarding. 'Cause the knowledge you gain from studying how stuff works under the hood leads to "mechanical sympathy".
</section>
<section class="future" style="display: none;">
<h2>Resources</h2>
<ul>
<li><a href="http://www.html5rocks.com/en/tutorials/internals/howbrowserswork">How Browsers Work by Tali Garsiel and Paul Irish</a></li>
<li><a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ">What the heck is the event loop anyway? by Philip Roberts</a></li>
<li><a href="https://developers.google.com/web/fundamentals/">Google Developer Web Fundamentals</a></li>
</ul>
</section>
<section class="future" style="display: none;">
<h1>THE END</h1>
</section>
</div>
<!-- The navigational controls UI -->
<aside style="display: block;" class="controls">
<a class="left" href="#">◄</a>
<a class="right enabled" href="#">►</a>
<a class="up" href="#">▲</a>
<a class="down" href="#">▼</a>
</aside>
<div style="display: block;" class="progress"><span style="width: 0px;"></span></div>
</div>
<!--<div style="position: absolute; bottom: 10px; right: 100%; margin-right: -120px">-->
<div style="position: absolute; bottom: 10px; left: 100%; margin-left: -120px">
</div>
<script src="resources/reveal.js"></script>
<script src="resources/highlight.js"></script>
<script>
// Parse the query string into a key/value object
var query = {};
location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
} );
Reveal.initialize({
controls: true,
progress: true,
history: true,
mouseWheel: false,
rollingLinks: true,
theme: query.theme || 'default', // default/neon
transition: 'linear' // query.transition || 'default'
});
hljs.initHighlightingOnLoad();
</script>
</body></html>