SlideShare une entreprise Scribd logo
Even Faster Web Sites Performance Best Practices
For Web Developers Original Steve Souders
download
https://ebookbell.com/product/even-faster-web-sites-performance-
best-practices-for-web-developers-original-steve-souders-4642610
Explore and download more ebooks at ebookbell.com
Here are some recommended products that we believe you will be
interested in. You can click the link to download.
Even Faster Web Sites Steve Souders
https://ebookbell.com/product/even-faster-web-sites-steve-
souders-48132392
Even Faster Web Sites Steve Souders
https://ebookbell.com/product/even-faster-web-sites-steve-
souders-48121340
Nginx Http Server Adopt Nginx For Your Web Applications To Make The
Most Of Your Infrastructure And Serve Pages Faster Than Ever Clment
Nedelcu
https://ebookbell.com/product/nginx-http-server-adopt-nginx-for-your-
web-applications-to-make-the-most-of-your-infrastructure-and-serve-
pages-faster-than-ever-clment-nedelcu-1960504
Words At Work Powerful Business Writing Skills Deliver Increased Sales
Improved Results And Even A Promotion Or Two Write Faster Series Book
1 Mcdaniel
https://ebookbell.com/product/words-at-work-powerful-business-writing-
skills-deliver-increased-sales-improved-results-and-even-a-promotion-
or-two-write-faster-series-book-1-mcdaniel-55709518
Halloween 03 Tales From Even Darker Places Foster Ray Caile
https://ebookbell.com/product/halloween-03-tales-from-even-darker-
places-foster-ray-caile-61758306
Italian Cooking In Your Instant Pot 60 Flavorful Homestyle Favorites
Made Faster Than Ever Tawnie Graham
https://ebookbell.com/product/italian-cooking-in-your-instant-
pot-60-flavorful-homestyle-favorites-made-faster-than-ever-tawnie-
graham-51139210
Nginx Http Server Fourth Edition Harness The Power Of Nginx To Make
The Most Of Your Infrastructure And Serve Pages Faster Than Ever
Before Fourth Martin Fjordvald Clement Nedelcu
https://ebookbell.com/product/nginx-http-server-fourth-edition-
harness-the-power-of-nginx-to-make-the-most-of-your-infrastructure-
and-serve-pages-faster-than-ever-before-fourth-martin-fjordvald-
clement-nedelcu-12070338
Just Sell The Damn Thing The Proven Contrarian Formula To Grow Your
Business Faster Than Ever Doberman Dan
https://ebookbell.com/product/just-sell-the-damn-thing-the-proven-
contrarian-formula-to-grow-your-business-faster-than-ever-doberman-
dan-33706728
Cooking Light Fresh Food Superfast Over 280 Allnew Recipes Faster Than
Ever Editors Of Cooking Light Magazine
https://ebookbell.com/product/cooking-light-fresh-food-superfast-
over-280-allnew-recipes-faster-than-ever-editors-of-cooking-light-
magazine-34949052
Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders
Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders
Even Faster Web Sites
Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders
Even Faster Web Sites
Steve Souders
Beijing • Cambridge • Farnham • Köln • Sebastopol • Taipei • Tokyo
Even Faster Web Sites
by Steve Souders
Copyright © 2009 Steve Souders. All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions
are also available for most titles (http://my.safaribooksonline.com). For more information, contact our
corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com.
Editor: Mary E. Treseler
Production Editor: Sarah Schneider
Copyeditor: Audrey Doyle
Proofreader: Sarah Schneider
Indexer: Lucie Haskins
Cover Designer: Karen Montgomery
Interior Designer: David Futato
Illustrator: Robert Romano
Printing History:
June 2009: First Edition.
O’Reilly and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc. Even Faster Web Sites,
the image of a blackbuck antelope, and related trade dress are trademarks of O’Reilly Media, Inc.
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as
trademarks. Where those designations appear in this book, and O’Reilly Media, Inc. was aware of a
trademark claim, the designations have been printed in caps or initial caps.
While every precaution has been taken in the preparation of this book, the publisher and author assume
no responsibility for errors or omissions, or for damages resulting from the use of the information con-
tained herein.
ISBN: 978-0-596-52230-8
[M]
1243719104
Table of Contents
Credits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
1. Understanding Ajax Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Trade-offs 1
Principles of Optimization 1
Ajax 4
Browser 4
Wow! 5
JavaScript 6
Summary 6
2. Creating Responsive Web Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
What Is Fast Enough? 9
Measuring Latency 10
When Latency Goes Bad 12
Threading 12
Ensuring Responsiveness 13
Web Workers 14
Gears 14
Timers 16
Effects of Memory Use on Response Time 17
Virtual Memory 18
Troubleshooting Memory Issues 18
Summary 19
3. Splitting the Initial Payload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Kitchen Sink 21
Savings from Splitting 22
Finding the Split 23
Undefined Symbols and Race Conditions 24
v
Case Study: Google Calendar 25
4. Loading Scripts Without Blocking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Scripts Block 27
Making Scripts Play Nice 29
XHR Eval 29
XHR Injection 31
Script in Iframe 31
Script DOM Element 32
Script Defer 32
document.write Script Tag 33
Browser Busy Indicators 33
Ensuring (or Avoiding) Ordered Execution 35
Summarizing the Results 36
And the Winner Is 38
5. Coupling Asynchronous Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Code Example: menu.js 42
Race Conditions 44
Preserving Order Asynchronously 45
Technique 1: Hardcoded Callback 46
Technique 2: Window Onload 47
Technique 3: Timer 48
Technique 4: Script Onload 49
Technique 5: Degrading Script Tags 50
Multiple External Scripts 52
Managed XHR 52
DOM Element and Doc Write 56
General Solution 59
Single Script 59
Multiple Scripts 60
Asynchronicity in the Real World 63
Google Analytics and Dojo 63
YUI Loader Utility 65
6. Positioning Inline Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Inline Scripts Block 69
Move Inline Scripts to the Bottom 70
Initiate Execution Asynchronously 71
Use Script Defer 73
Preserving CSS and JavaScript Order 73
Danger: Stylesheet Followed by Inline Script 74
Inline Scripts Aren’t Blocked by Most Downloads 74
vi | Table of Contents
Inline Scripts Are Blocked by Stylesheets 75
This Does Happen 77
7. Writing Efficient JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Managing Scope 79
Use Local Variables 81
Scope Chain Augmentation 83
Efficient Data Access 85
Flow Control 88
Fast Conditionals 89
Fast Loops 93
String Optimization 99
String Concatenation 99
Trimming Strings 100
Avoid Long-Running Scripts 102
Yielding Using Timers 103
Timer Patterns for Yielding 105
Summary 107
8. Scaling with Comet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
How Comet Works 109
Transport Techniques 111
Polling 111
Long Polling 112
Forever Frame 113
XHR Streaming 115
Future Transports 116
Cross-Domain 116
Effects of Implementation on Applications 118
Managing Connections 118
Measuring Performance 119
Protocols 119
Summary 120
9. Going Beyond Gzipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Why Does This Matter? 121
What Causes This? 123
Quick Review 123
The Culprit 123
Examples of Popular Turtle Tappers 124
How to Help These Users? 124
Design to Minimize Uncompressed Size 125
Educate Users 129
Table of Contents | vii
Direct Detection of Gzip Support 130
10. Optimizing Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Two Steps to Simplify Image Optimization 134
Image Formats 135
Background 135
Characteristics of the Different Formats 137
More About PNG 139
Automated Lossless Image Optimization 141
Crushing PNGs 141
Stripping JPEG Metadata 143
Converting GIF to PNG 144
Optimizing GIF Animations 144
Smush.it 144
Progressive JPEGs for Large Images 145
Alpha Transparency: Avoid AlphaImageLoader 146
Effects of Alpha Transparency 146
AlphaImageLoader 148
Problems with AlphaImageLoader 149
Progressively Enhanced PNG8 Alpha Transparency 151
Optimizing Sprites 152
Über-Sprite Versus Modular Sprite 153
Highly Optimized CSS Sprites 154
Other Image Optimizations 155
Avoid Scaling Images 155
Crush Generated Images 155
Favicons 157
Apple Touch Icon 158
Summary 158
11. Sharding Dominant Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Critical Path 161
Who’s Sharding? 163
Downgrading to HTTP/1.0 165
Rolling Out Sharding 168
IP Address or Hostname 168
How Many Domains 168
How to Split Resources 168
Newer Browsers 169
12. Flushing the Document Early . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Flush the Head 171
Output Buffering 173
viii | Table of Contents
Chunked Encoding 175
Flushing and Gzip 176
Other Intermediaries 177
Domain Blocking During Flushing 178
Browsers: The Last Hurdle 178
Flushing Beyond PHP 179
The Flush Checklist 180
13. Using Iframes Sparingly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
The Most Expensive DOM Element 181
Iframes Block Onload 182
Parallel Downloads with Iframes 184
Script Before Iframe 184
Stylesheet Before Iframe 185
Stylesheet After Iframe 186
Connections per Hostname 187
Connection Sharing in Iframes 187
Connection Sharing Across Tabs and Windows 188
Summarizing the Cost of Iframes 190
14. Simplifying CSS Selectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Types of Selectors 191
ID Selectors 192
Class Selectors 193
Type Selectors 193
Adjacent Sibling Selectors 193
Child Selectors 193
Descendant Selectors 193
Universal Selectors 194
Attribute Selectors 194
Pseudo-Classes and Pseudo-Elements 194
The Key to Efficient CSS Selectors 194
Rightmost First 195
Writing Efficient CSS Selectors 195
CSS Selector Performance 197
Complex Selectors Impact Performance (Sometimes) 197
CSS Selectors to Avoid 200
Reflow Time 201
Measuring CSS Selectors in the Real World 202
Appendix: Performance Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Table of Contents | ix
Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders
Credits
Even Faster Web Sites contains six chapters contributed by the following authors.
Dion Almaer is the cofounder of Ajaxian.com, the leading source of the Ajax com-
munity. For his day job, Dion coleads a new group at Mozilla focusing on developer
toolsfortheWeb,somethinghehasbeenpassionateaboutdoingforyears.Heisexcited
for the opportunity, and he gets to work with Ben Galbraith, his partner in crime on
Ajaxian and now at Mozilla. Dion has been writing web applications since Gopher, has
been fortunate enough to speak around the world, has published many articles and
a book, and, of course, covers life, the universe, and everything else on his blog at http:
//almaer.com/blog.
Douglas Crockford was born in the wilds of Minnesota, but left when he was only
six months old because it was just too damn cold. He turned his back on a promising
career in television when he discovered computers. He has worked in learning systems,
small business systems, office automation, games, interactive music, multimedia,
location-based entertainment, social systems, and programming languages. He is the
inventor of Tilton, the ugliest programming language that was not specifically designed
to be an ugly programming language. He is best known for having discovered that there
are good parts in JavaScript. This was an important and unexpected discovery. He
discovered the JSON (JavaScript Object Notation) data interchange format. He is cur-
rently working on making the Web a secure and reliable software-delivery platform.
He has his work cut out for him.
Ben Galbraith is the codirector of developer tools at Mozilla and the cofounder of
Ajaxian.com. Ben has long juggled interests in both business and tech, having written
his first computer program at 6 years old, started his first business at 10, and entered
the IT workforce at 12. He has delivered hundreds of technical presentations world-
wide, produced several technical conferences, and coauthored more than a half-dozen
books. He has enjoyed a variety of business and technical roles throughout his career,
including CEO, CIO, CTO, and Chief Software Architect roles in medical, publishing,
media, manufacturing, advertising, and software industries. He lives in Palo Alto,
California with his wife and five children.
xi
Tony Gentilcore is a software engineer at Google. There, he has helped make the
Google home and search results pages lightning fast. He finds that the days seem to fly
by while writing web performance tools and techniques. Tony is also the creator of the
popular Firefox extension, Fasterfox.
Dylan Schiemann is CEO of SitePen and cofounder of the Dojo Toolkit, an open
source JavaScript toolkit for rapidly building web sites and applications, and is an
expert in the technologies and opportunities of the Open Web. Under his guidance,
SitePen has grown from a small development firm to a leading provider of inventive
tools, skilled software engineers, knowledgeable consulting services, and top-notch
training and advice. Dylan’s commitment to R&D has enabled SitePen to be a major
contributor to and creator of pioneering open source web development toolkits and
frameworks such as Dojo, cometD, Direct Web Remoting (DWR), and Persevere. Prior
to SitePen, Dylan developed web applications for companies such as Renkoo, Infor-
matica, Security FrameWorks, and Vizional Technologies. He is a cofounder of Comet
Daily, LLC, a board member at Dojo Foundation, and a member of the advisory board
at Aptana. Dylan earned his master’s in physical chemistry from UCLA and his B.A. in
mathematics from Whittier College.
Stoyan Stefanov is a Yahoo! frontend developer, focusing on web application
performance. He is also the architect of the performance extension YSlow 2.0 and
cocreator of the Smush.it image optimization tool. Stoyan is a speaker, book author
(Object-Oriented JavaScript from Packt Publishing), and blogger at http://phpied.com,
http://jspatterns.com, and YUIblog.
Nicole Sullivan is an evangelist, frontend performance consultant, and CSS Ninja. She
startedtheObject-OrientedCSSopensourceproject,whichanswersthequestion,How
do you scale CSS for millions of visitors or thousands of pages? She also consulted with
the W3C for their beta redesign, and she is the cocreator of Smush.it, an image opti-
mization service in the cloud. She is passionate about CSS, web standards, and scalable
frontend architecture for large commercial websites. Nicole speaks about performance
at conferences around the world, most recently at The Ajax Experience, ParisWeb, and
Web Directions North. She blogs at http://stubbornella.org.
Nicholas C. Zakas is the author of Professional JavaScript for Web Developers, Second
Edition (Wrox) and coauthor of Professional Ajax, Second Edition (Wrox). Nicholas
is principal frontend engineer for the Yahoo! home page and is also a contributor to
the Yahoo! User Interface (YUI) library. He blogs regularly at his site, http://www
.nczonline.net.
xii | Credits
Preface
Vigilant: alertly watchful, especially to avoid danger
Anyone browsing this book—or its predecessor, High Performance Web Sites—under-
stands the dangers of a slow web site: frustrated users, negative brand perception,
increased operating expenses, and loss of revenue. We have to constantly work to make
our web sites faster. As we make progress, we also lose ground. We have to be alert for
the impact of each bug fix, new feature, and system upgrade on our web site’s speed.
We have to be watchful, or the performance improvements made today can easily be
lost tomorrow. We have to be vigilant.
Vigil: watch kept on a festival eve
According to the Latin root of vigil, our watch ends with celebration. Web sites can
indeed be faster—dramatically so—and we can celebrate the outcome of our care and
attention. It’s true! Making web sites faster is attainable. Some of the world’s most
popular web sites have reduced their load times by 60% using the techniques described
in this book. Smaller web properties benefit as well. Ultimately, users benefit.
Vigilante: a self-appointed doer of justice
It’s up to us as developers to guard our users’ interests. At your site, evangelize per-
formance. Implement these techniques. Share this book with a coworker. Fight for a
faster user experience. If your company doesn’t have someone focused on performance,
appoint yourself to that role. Performance vigilante—I like the sound of that.
How This Book Is Organized
This book is a follow-up to my first book, High Performance Web Sites (O’Reilly). In
that book, I lay out 14 rules for better web performance:
• Rule 1: Make Fewer HTTP Requests
• Rule 2: Use a Content Delivery Network
• Rule 3: Add an Expires Header
• Rule 4: Gzip Components
xiii
• Rule 5: Put Stylesheets at the Top
• Rule 6: Put Scripts at the Bottom
• Rule 7: Avoid CSS Expressions
• Rule 8: Make JavaScript and CSS External
• Rule 9: Reduce DNS Lookups
• Rule 10: Minify JavaScript
• Rule 11: Avoid Redirects
• Rule 12: Remove Duplicate Scripts
• Rule 13: Configure ETags
• Rule 14: Make Ajax Cacheable
I call them “rules” because there is little ambiguity about their adoption. Consider these
statistics for the top 10 U.S. web sites* for March 2007:
• Two sites used CSS sprites.
• 26% of resources had a future Expires header.
• Five sites compressed their HTML, JavaScript, and CSS.
• Four sites minified their JavaScript.
The same statistics for April 2009 show that these rules are gaining traction:
• Nine sites use CSS sprites.
• 93% of resources have a future Expires header.
• Ten sites compress their HTML, JavaScript, and CSS.
• Nine sites minify their JavaScript.
The rules from High Performance Web Sites still apply and are where most web com-
panies should start. Progress is being made, but there’s still more work to be done on
this initial set of rules.
But the Web isn’t standing still, waiting for us to catch up. Although the 14 rules from
High Performance Web Sites still apply, the growth in web page content and Web 2.0
applications introduces a new set of performance challenges. Even Faster Web Sites
provides the best practices needed by developers to make these next-generation web
sites faster.
The chapters in this book are organized into three areas: JavaScript performance
(Chapters 1–7), network performance (Chapters 8–12), and browser performance
(Chapters 13 and 14). A roundup of the best tools for analyzing performance comes in
the Appendix.
* AOL, eBay, Facebook, Google Search, Live Search, MSN.com, MySpace, Wikipedia, Yahoo!, and YouTube,
according to Alexa.
xiv | Preface
Six of the chapters were written by contributing authors:
• Chapter 1, Understanding Ajax Performance, by Douglas Crockford
• Chapter 2, Creating Responsive Web Applications, by Ben Galbraith and Dion
Almaer
• Chapter 7, Writing Efficient JavaScript, by Nicholas C. Zakas
• Chapter 8, Scaling with Comet, by Dylan Schiemann
• Chapter 9, Going Beyond Gzipping, by Tony Gentilcore
• Chapter 10, Optimizing Images, by Stoyan Stefanov and Nicole Sullivan
These authors are experts in each of these areas. I wanted you to hear from them
directly, in their own voices. To help identify these chapters, the name(s) of the con-
tributing author(s) are on the chapter’s opening page.
JavaScript Performance
In my work analyzing today’s web sites, I consistently see that JavaScript is the key to
better-performing web applications, so I’ve started the book with these chapters.
Douglas Crockford wrote Chapter 1, Understanding Ajax Performance. Doug describes
how Ajax changes the way browsers and servers interact, and how web developers need
to understand this new relationship to properly identify opportunities for improving
performance.
Chapter 2, Creating Responsive Web Applications, by Ben Galbraith and Dion Almaer,
ties JavaScript performance back to what really matters: the user experience. Today’s
web applications invoke complex functions at the click of a button and must be eval-
uated on the basis of what they’re forcing the browser to do. The web applications that
succeed will be written by developers who understand the effects of their code on
response time.
I wrote the next four chapters. They focus on the mechanics of JavaScript—the best
way to package it and load it, and where to insert it in your pages. Chapter 3, Splitting
the Initial Payload, describes the situation facing many web applications today: a huge
JavaScriptdownloadatthebeginningofthepagethatblocksrenderingaswellasfurther
downloads. The key is to break apart this monolithic JavaScript for more efficient
loading.
Chapters 4 and 5 go together. In today’s most popular browsers, external scripts block
everything else in the page. Chapter 4, Loading Scripts Without Blocking, explains how
to avoid these pitfalls when loading external scripts. Loading scripts asynchronously
presents a challenge when inlined code depends on them. Luckily, there are several
techniques for coupling inlined code with the asynchronous scripts on which they de-
pend. These techniques are presented in Chapter 5, Coupling Asynchronous Scripts.
Preface | xv
Chapter 6, Positioning Inline Scripts, presents performance best practices that apply to
inline scripts, especially the impact they have on blocking parallel downloads.
I think of Chapter 7, Writing Efficient JavaScript, written by Nicholas C. Zakas, as the
complement to Doug’s chapter (Chapter 1). Whereas Doug describes the Ajax land-
scape, Nicholas zooms in on several specific techniques for speeding up JavaScript.
Network Performance
Web applications aren’t desktop applications—they have to be downloaded over the
Internet each time they are used. The adoption of Ajax has resulted in a new style of
data communication between servers and clients. Some of the biggest opportunities for
growth in the web industry are in emerging markets where Internet connectivity is a
challenge, to put it mildly. All of these factors highlight the need for improved network
performance.
In Chapter 8, Scaling with Comet, Dylan Schiemann describes an architecture that goes
beyond Ajax to provide high-volume, low-latency communication for real-time appli-
cations such as chat and document collaboration.
Chapter 9, Going Beyond Gzipping, describes how turning on compression isn’t enough
to guarantee optimal delivery of your web site’s content. Tony Gentilcore reveals a
little-known phenomenon that severely hinders the network performance of 15% of
the world’s Internet users.
Stoyan Stefanov and Nicole Sullivan team up to contribute Chapter 10, Optimizing
Images. This is a thorough treatment of the topic. This chapter reviews all popular
image formats, presents numerous image optimization techniques, and describes the
image compression tools of choice.
The remaining chapters were written by me. Chapter 11, Sharding Dominant Do-
mains, reminds us of the connection limits in the popular browsers of today, as well as
the next generation of browsers. It includes techniques for successfully splitting
resources across multiple domains.
Chapter 12, Flushing the Document Early, walks through the benefits and many gotchas
of using chunked encoding to start rendering the page even before the full HTML
document has arrived.
Browser Performance
Iframes are an easy and frequently used technique for embedding third-party content
in a web page. But they come with a cost. Chapter 13, Using Iframes Sparingly, explains
the downsides of iframes and offers a few alternatives.
Chapter 14, Simplifying CSS Selectors, presents the theories about how complex selec-
tors can impact performance, and then does an objective analysis to pinpoint the
situations that are of most concern.
xvi | Preface
The Appendix, Performance Tools, describes the tools that I recommend for analyzing
web sites and discovering the most important performance improvements to work on.
Conventions Used in This Book
The following typographical conventions are used in this book:
Italic
Indicates new terms, URLs, email addresses, filenames, file extensions, pathnames,
and directories
Constant width
Indicates commands, options, switches, variables, attributes, keys, functions,
types, classes, namespaces, methods, modules, properties, parameters, values, ob-
jects, events, event handlers, XML tags, HTML tags, macros, the contents of files,
and the output from commands
Constant width bold
Shows commands or other text that should be typed literally by the user
Constant width italic
Shows text that should be replaced with user-supplied values
This icon signifies a tip, suggestion, or general note.
This icon indicates a warning or caution.
Comments and Questions
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 (in the United States or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional
information. You can access this page at:
http://www.oreilly.com/catalog/9780596522308
Preface | xvii
To comment or ask technical questions about this book, send email to:
bookquestions@oreilly.com
For more information about our books, conferences, Resource Centers, and the
O’Reilly Network, see our web site at:
http://www.oreilly.com
Using Code Examples
You may use the code in this book in your programs and documentation. You do not
need to contact us for permission unless you’re reproducing a significant portion of the
code. For example, writing a program that uses several chunks of code from this book
does not require permission. Selling or distributing a CD-ROM of examples from this
book does require permission. Answering a question by citing this book and quoting
example code does not require permission. Incorporating a significant amount of ex-
ample code from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title,
author, publisher, and ISBN. For example: “Even Faster Web Sites, by Steve Souders.
Copyright 2009 Steve Souders, 978-0-596-52230-8.”
If you feel your use of code examples falls outside fair use or the permission given above,
feel free to contact us at permissions@oreilly.com.
Safari® Books Online
When you see a Safari® Books Online icon on the cover of your favorite
technology book, that means the book is available online through the
O’Reilly Network Safari Bookshelf.
Safari offers a solution that’s better than e-books. It’s a virtual library that lets you easily
search thousands of top tech books, cut and paste code samples, download chapters,
and find quick answers when you need the most accurate, current information. Try it
for free at http://my.safaribooksonline.com.
Acknowledgments
I first want to thank the contributing authors: Dion Almaer, Doug Crockford, Ben
Galbraith, Tony Gentilcore, Dylan Schiemann, Stoyan Stefanov, Nicole Sullivan, and
Nicholas Zakas. They’ve made this a special book. Each of them is an expert in his or
her own right. Most of them have written their own books. By sharing their expertise,
they’ve helped create something unique.
xviii | Preface
I want to thank all the reviewers: Julien Lecomte, Matthew Russell, Bill Scott, and Tenni
Theurer. I extend an especially strong thank you to Eric Lawrence and Andy Oram.
Eric reviewed both this book as well as High Performance Web Sites. In both cases, he
provided incredibly thorough and knowledgeable feedback. Andy was my editor on
High Performance Web Sites. More than anyone else, he is responsible for improving
how this book reads, making it flow smoothly from line to line, section to section, and
chapter to chapter.
A special thank you goes to my editor, Mary Treseler. Coordinating a book with mul-
tiple authors is an opportunity that many editors will pass over. I’m glad that she took
on this project and helped guide it from a bunch of ideas to what you’re holding in your
hands now.
I work with many people at Google who have a penchant for web performance. Tony
Gentilcore is the creator of Fasterfox and the author of Chapter 9. He’s also my offi-
cemate. Several times a day we’ll stop to discuss web performance. Steve Lamm, Lind-
sey Simon, and Annie Sullivan are strong advocates for performance who I work with
frequently. Other Googlers who have contributed to what I know about web perform-
ance include Jacob Hoffman-Andrews, Kyle Scholz, Steve Krulewitz, Matt Gundersen,
Gavin Doughtie, and Bryan McQuade.
Many of the insights in this book come from my friends outside Google. They know
that if they tell me about a good performance tip, it’s likely to end up in a book or blog
post. These performance cohorts include Dion Almaer, Artur Bergman, Doug Crock-
ford, Ben Galbraith, Eric Goldsmith, Jon Jenkins, Eric Lawrence, Mark Nottingham,
Simon Perkins, John Resig, Alex Russell, Eric Schurman, Dylan Schiemann, Bill Scott,
Jonas Sicking, Joseph Smarr, and Tenni Theurer.
I’ve inevitably forgotten to mention someone in these lists. I apologize, and want to
thank all of you for taking the time to send me email and talk to me at conferences.
Hearingyourlessonslearnedandsuccessstorieskeepsmegoing.It’simportanttoknow
there are so many of us who are working to make the Web a faster place.
Thank you to my parents for being proud to have a son who’s an author. Most impor-
tantly, thank you to my wife and three daughters. I promise to take a break now.
Preface | xix
Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders
CHAPTER 1
Understanding Ajax Performance
Douglas Crockford
Premature optimization is the root of all evil.
—Donald Knuth
Trade-offs
The design and construction of a computer program can involve thousands of deci-
sions, each representing a trade-off. In difficult decisions, each alternative has signifi-
cant positive and negative consequences. In trading off, we hope to obtain a near
optimal good while minimizing the bad. Perhaps the ultimate trade-off is:
I want to go to heaven, but I don’t want to die.
More practically, the Project Triangle:
Fast. Good. Cheap. Pick Two.
predicts that even under ideal circumstances, it is not possible to obtain fast, good, and
cheap. There must be a trade-off.
In computer programs, we see time versus memory trade-offs in the selection of algo-
rithms. We also see expediency or time to market traded against code quality. Such
trades can have a large impact on the effectiveness of incremental development.
Every time we touch the code, we are trading off the potential of improving the code
against the possibility of injecting a bug. When we look at the performance of programs,
we must consider all of these trade-offs.
Principles of Optimization
When looking at optimization, we want to reduce the overall cost of the program.
Typically, this cost is the perceived execution time of the program, although we could
1
optimize on other factors. We then should focus on the parts of the program that
contribute most significantly to its cost.
For example, suppose that by profiling we discover the cost of a program’s four
modules.
Module A B C D
Cost 54% 4% 30% 12%
If we could somehow cut the cost of Module B in half, we would reduce the total cost
by only 2%. We would get a better result by cutting the cost of Module A by 10%.
There is little benefit from optimizing components that do not contribute significantly
to the cost.
The analysis of applications is closely related to the analysis of algorithms. When look-
ing at execution time, the place where programs spend most of their time is in loops.
The return on optimization of code that is executed only once is negligible. The benefits
of optimizing inner loops can be significant.
For example, if the cost of a loop is linear with respect to the number of iterations, then
we can say it is O(n), and we can graph its performance as shown in Figure 1-1.
Figure 1-1. Performance of a loop
The execution time of each iteration is reflected in the slope of the line: the greater the
cost, the steeper the slope. The fixed overhead of the loop determines the elevation of
its starting point. There is usually little benefit in reducing the fixed overhead. Some-
times there is a benefit in increasing the fixed overhead if the cost of each increment
can be reduced. That can be a good trade-off.
In addition to the plot of execution time, there are three lines—the Axes of Error—that
our line must not intersect (see Figure 1-2). The first is the Inefficiency line. Crossing
this line reduces the user’s ability to concentrate. This can also make people irritable.
The second is the Frustration line. When this line is crossed, the user is aware that he
2 | Chapter 1: Understanding Ajax Performance
is being forced to wait. This invites him to think about other things, such as the desir-
ability of competing web applications. The third is the Failure line. This is when the
user refreshes or closes the browser because the application appears to have crashed,
or the browser itself produces a dialog suggesting that the application has failed and
that the user should take action.
Figure 1-2. The Axes of Error
There are three ways to avoid intersecting the Axes of Error: reduce the cost of each
iteration, reduce the number of iterations, or redesign the application.
When loops become nested, your options are reduced. If the cost of the loop is O(n log
n), O(n2), or worse, reducing the time per iteration is not effective (see Figure 1-3). The
only effective options are to reduce n or to replace the algorithm. Fiddling with the cost
per iteration will be effective only when n is very small.
Figure 1-3. Performance of a nested loop
Programs must be designed to be correct. If the program isn’t right, it doesn’t matter
if it is fast. However, it is important to determine whether it has performance problems
as early as possible in the development cycle. In testing web applications, test with slow
Principles of Optimization | 3
machines and slow networks that more closely mimic those of real users. Testing in
developer configurations is likely to mask performance problems.
Ajax
Refactoring the code can reduce its apparent complexity, making optimization and
other transformations more likely to yield benefits. For example, adopting the YSlow
rules can have a huge impact on the delivery time of web pages (see http://developer
.yahoo.com/yslow/).
Even so, it is difficult for web applications to get under the Inefficiency line because of
the size and complexity of web pages. Web pages are big, heavy, multipart things. Page
replacement comes with a significant cost. For applications where the difference
between successive pages is relatively small, use of Ajax techniques can produce a sig-
nificant improvement.
Instead of requesting a replacement page as a result of a user action, a packet of data
issenttotheserver(usuallyencodedasJSONtext)andtheserverrespondswithanother
packet (also typically JSON-encoded) containing data. A JavaScript program uses that
data to update the browser’s display. The amount of data transferred is significantly
reduced, and the time between the user action and the visible feedback is
also significantly reduced. The amount of work that the server must do is reduced.
The amount of work that the browser must do is reduced. The amount of work that
the Ajax programmer must do, unfortunately, is likely to increase. That is one of the
trade-offs.
The architecture of an Ajax application is significantly different from most other sorts
of applications because it is divided between two systems. Getting the division of labor
right is essential if the Ajax approach is to have a positive impact on performance. The
packets should be as small as possible. The application should be constructed as a
conversationbetweenthebrowserandtheserver,inwhichthetwohalvescommunicate
in a concise, expressive, shared language. Just-in-time data delivery allows the browser
side of the application to keep n small, which tends to keep the loops fast.
A common mistake in Ajax applications is to send all of the application’s data to the
browser. This reintroduces the latency problems that Ajax is supposed to avoid. It also
enlarges the volume of data that must be handled in the browser, increasing n and again
compromising performance.
Browser
Ajax applications are challenging to write because the browser was not designed to be
an application platform. The scripting language and the Document Object Model
(DOM) were intended to support applications composed of simple forms. Surprisingly,
the browser gets enough right that it is possible to use it to deliver sophisticated
4 | Chapter 1: Understanding Ajax Performance
applications. Unfortunately, it didn’t get everything right, so the level of difficulty can
be high. This can be mitigated with the use of Ajax libraries (e.g., http://developer.yahoo
.com/yui/). An Ajax library uses the expressive power of JavaScript to raise the DOM
toapracticallevel,aswellasrepairingmanyofthehazardsthatcanpreventapplications
from running acceptably on the many brands of browsers.
Unfortunately, the DOM API is very inefficient and mysterious. The greatest cost in
running programs tends to be the DOM, not JavaScript. At the Velocity 2008 confer-
ence, the Microsoft Internet Explorer 8 team shared this performance data on how time
is spent in the Alexa 100 pages.*
Activity Layout Rendering HTML Marshaling DOM Format JScript Other
Cost 43.16% 27.25% 2.81% 7.34% 5.05% 8.66% 3.23% 2.5%
The cost of running JavaScript is insignificant compared to the other things that the
browser spends time on. The Microsoft team also gave an example of a more aggressive
Ajax application, the opening of an email thread.
Activity Layout Rendering HTML Marshaling DOM Format JScript Other
Cost 9.41% 9.21% 1.57% 7.85% 12.47% 38.97% 14.43% 3.72%
The cost of the script is still less than 15%. Now CSS processing is the greatest cost.
Understanding the mysteries of the DOM and working to suppress its impact is clearly
a better strategy than attempting to speed up the script. If you could heroically make
the script run twice as fast, it would barely be noticed.
Wow!
There is a tendency among application designers to add wow features to Ajax applica-
tions. These are intended to invoke a reaction such as, “Wow, I didn’t know browsers
could do that.” When used badly, wow features can interfere with the productivity of
users by distracting them or forcing them to wait for animated sequences to play out.
Misused wow features can also cause unnecessary DOM manipulations, which can
come with a surprisingly high cost.
Wow features should be used only when they genuinely improve the experience of the
user. They should not be used to show off or to compensate for deficiencies in func-
tionality or usability.
Design for things that the browser can do well. For example, viewing a database as an
infinitely scrolling list requires that the browser hold on to and display a much larger
set than it can manage efficiently. A better alternative is to have a very effective
* http://en.oreilly.com/velocity2008/public/schedule/detail/3290
Wow! | 5
paginating display with no scrolling at all. This provides better performance and can
be easier to use.
JavaScript
Most JavaScript engines were optimized for quick time to market, not performance, so
it is natural to assume that JavaScript is always the bottleneck. Typically, however, the
bottleneck is not JavaScript, but the DOM, so fiddling with scripts will have little
effectiveness.
Fiddling should be avoided. Programs should be coded for correctness and clarity.
Fiddling tends to work against clarity, which can increase the susceptibility of the
program to attract bugs.
Fortunately, competitive pressure is forcing the browser makers to improve the effi-
ciency of their JavaScript engines. These improvements will enable new classes of
applications in the browser.
Avoid obscure idioms that might be faster unless you can prove that they will have a
noticeable impact on your application. In most cases, they will have no noticeable
impact except to degrade the quality of your code. Do not tune to the quirks of par-
ticular browsers. The browsers are still in development and may ultimately favor better
coding practices.
If you feel you must fiddle, measure first. Our intuitions of the true costs of a program
are usually wrong. Only by measuring can you have confidence that you are having a
positive effect on performance.
Summary
Everything is a trade-off. When optimizing for performance, do not waste time trying
to speed up code that does not consume a significant amount of the time. Measure first.
Back out of any optimization that does not provide an enjoyable benefit.
Browsers tend to spend little time running JavaScript. Most of their time is spent in the
DOM. Ask your browser maker to provide better performance measurement tools.
Code for quality. Clean, legible, well-organized code is easier to get right, easier to
maintain, and easier to optimize. Avoid tricks except when they can be proven to
substantially improve performance.
Ajax techniques, when used well, can make applications faster. The key is in estab-
lishing a balance between the browser and the server. Ajax provides an effective alter-
native to page replacement, turning the browser into a powerful application platform,
but your success is not guaranteed. The browser is a challenging platform and your
intuitions about performance are not reliable. The chapters that follow will help you
understand how to make even faster web sites.
6 | Chapter 1: Understanding Ajax Performance
CHAPTER 2
Creating Responsive Web Applications
Ben Galbraith and Dion Almaer
With the rise of Ajax, web site performance is no longer just about the quick realization
of a web site. An ever-increasing number of web sites, once loaded, will use JavaScript
to dynamically change the page and load new content on the fly. Such sites have much
in common with traditional desktop client programs, and optimizing the performance
of these applications requires a different set of techniques from traditional web sites.
From a high level, user interfaces for web applications and traditional desktop appli-
cations share a common goal: respond to the user’s input as fast as possible. When it
comes to responding to a user’s request to load a web site, the browser itself handles
much of the responsiveness burden. It opens network connections to the requested
site, parses the HTML, requests the associated resources, and so forth. Based on a
careful analysis of this process, we can optimize our pages to render as fast as possible,
but the browser is ultimately in control of loading and realizing the page.
Whenitcomestorespondingtouserinputtothewebsiteitself(whenthatinputdoesn’t
result in the browser loading a new page), we web developers are in control. We must
ensure that the JavaScript that executes as a result of such input is responsive. To better
understand just how much control we have over responsiveness, we’re going to take a
minute to explain how browser user interfaces work.
As shown in Figure 2-1, when a user interacts with a browser, the operating system
receives input from various devices attached to the computer, such as the keyboard or
mouse. It works out which application should receive these inputs, and it packages
them up as individual events and places them in a queue for that application, known
as an event queue.
It’s up to the web browser, like any GUI application, to process the individual events
placed in its queue. It does so by pulling them from the queue in first-in, first-out order
and deciding what to do about the event. Generally, the browser will do one of two
things based on these events: handle the event itself (such as display a menu, browse
7
the Web, show a preference screen, etc.) or execute JavaScript code in the web page
itself (e.g., JavaScript code in an onclick handler in the page), as shown in Figure 2-2.
Figure 2-1. All user input is routed via the operating system into an event queue
Figure 2-2. The browser uses a single thread to process events in the queue and execute user code
The important takeaway here is that this process is essentially single-threaded. That is,
the browser uses a single thread to pull an event from the queue and either do something
8 | Chapter 2: Creating Responsive Web Applications
itself (“Web browsing” in Figure 2-2) or execute JavaScript. As such, it can do only one
of these tasks at a time, and each of these tasks can prevent the other tasks from
occurring.
Any time spent by the browser executing a page’s JavaScript is time that it cannot spend
responding to other user events. It is therefore vital that any JavaScript in a page execute
as fast as possible. Otherwise, the web page and the browser itself may become sluggish
or freeze up entirely.
Note that this discussion of browser and operating system behavior with respect to
input handling and events is a broadly applicable generalization; details vary. Regard-
less of variances, all browsers execute all JavaScript code in a page on a single thread
(excepting the use of Web Workers, discussed later in this chapter), making the de-
veloper practices advocated in this chapter completely applicable.
What Is Fast Enough?
It’s fine to say that code needs to execute “as fast as possible,” but sometimes code
needs to do things that simply take time. For instance, encryption algorithms, complex
graphics rendering, and image manipulation are examples of computations that are
time-consuming to perform, regardless of how much effort a developer puts forth to
make them “as fast as possible.”
However, as Doug mentioned in Chapter 1, developers seeking to create responsive,
high-performance web sites can’t—and shouldn’t—go about achieving that goal by
optimizing every single piece of code as they write it. The opposite is true: a developer
should optimize only what isn’t fast enough.
It is therefore vital to define exactly what is “fast enough” in this context. Fortunately,
that’s already been done for us.
Jakob Nielsen is a well-known and well-regarded expert in the field of web usability;
the following quote* addresses the issue of “fast enough”:
The response time guidelines for web-based applications are the same as for all other
applications. These guidelines have been the same for 37 years now, so they are also not
likely to change with whatever implementation technology comes next.
0.1 second: Limit for users feeling that they are directly manipulating objects in the UI.
For example, this is the limit from the time the user selects a column in a table until that
column should highlight or otherwise give feedback that it’s selected. Ideally, this would
also be the response time for sorting the column—if so, users would feel that they are
sorting the table.
1 second: Limit for users feeling that they are freely navigating the command space
without having to unduly wait for the computer. A delay of 0.2–1.0 seconds does mean
that users notice the delay and thus feel the computer is “working” on the command, as
* http://www.useit.com/papers/responsetime.html
What Is Fast Enough? | 9
opposed to having the command be a direct effect of the users’ actions. Example: If
sorting a table according to the selected column can’t be done in 0.1 seconds, it certainly
has to be done in 1 second, or users will feel that the UI is sluggish and will lose the sense
of “flow” in performing their task. For delays of more than 1 second, indicate to the user
that the computer is working on the problem, for example by changing the shape of the
cursor.
10 seconds: Limit for users keeping their attention on the task. Anything slower than
10 seconds needs a percent-done indicator as well as a clearly signposted way for the user
to interrupt the operation. Assume that users will need to reorient themselves when they
return to the UI after a delay of more than 10 seconds. Delays of longer than 10 seconds
are only acceptable during natural breaks in the user’s work, for example when switching
tasks.
In other words, if your JavaScript code takes longer than 0.1 seconds to execute, your
page won’t have that slick, snappy feel; if it takes longer than 1 second, the application
feels sluggish; longer than 10 seconds, and the user will be extremely frustrated. These
are the definitive guidelines to use for defining “fast enough.”
Measuring Latency
Now that you know the threshold for fast enough, the next step is to explore how you
can measure the speed of JavaScript execution to determine whether it falls outside the
ranges mentioned earlier (we’ll leave it to you to determine just how fast you wish your
page to be; we aim to keep all interface latency smaller than 0.1 seconds).
The easiest, most straightforward, and probably least precise way to measure latency
is via human observation; simply use the application on your target platforms and
ensure that performance is adequate. Since ensuring adequate human interface per-
formance is only about pleasing humans, this is actually a fine way to perform such
measurements (obviously, few humans will be able to quantify delays reliably in terms
of precise whole or fractional second measurements; falling back to coarser categori-
zations such as “snappy,” “sluggish,” “adequate,” and so on does the job).
However, if you desire more precise measurements, there are two options you can
choose: manual code instrumentation (logging) or automated code instrumentation
(profiling).
Manual code instrumentation is really straightforward. Let’s say you have an event
handler registered on your page, as in:
<div onclick="myJavaScriptFunction()"> ... </div>
A simple way to add manual instrumentation would be to locate the definition of
myJavaScriptFunction() and add timing to the function:
function myJavaScriptFunction() {
var start = new Date().getMilliseconds();
// some expensive code is here
10 | Chapter 2: Creating Responsive Web Applications
var stop = new Date().getMilliseconds();
var executionTime = stop - start;
alert("myJavaScriptFunction() executed in " + executionTime +
" milliseconds");
}
The preceding code will produce a pop-up dialog that displays the execution time; one
millisecond represents 1/1,000 of a second, so 100 milliseconds represent the 0.1-
second “snappiness” threshold mentioned earlier.
Many browsers offer a built-in instance named console that provides a
log() function (Firefox makes this available with the popular Firebug
plug-in); we greatly prefer console.log() to alert().
There are tools to perform an automated measurement of code execution time, but
such tools are typically used for a different purpose. Instead of being used to determine
the precise execution duration of a function, such tools—called profilers—are usually
used to determine the relative amount of time spent executing a set of functions; that
is, they are used to find the bottleneck or slowest-running chunks of code.
The popular Firebug extension for Firefox includes a JavaScript code profiler; it gen-
erates output such as that shown in Figure 2-3.
Figure 2-3. Firebug’s profiler
The “Time” column represents the total amount of time the JavaScript interpreter spent
inside a given function during the period of profiling. Often, a function invokes other
Measuring Latency | 11
functions; the “Own Time” column represents the amount of time spent inside a spe-
cific function and not any other functions that it may have invoked.
Whileyoumightthinktheseandtheothertemporal-relatedcolumnsrepresentaprecise
measurement of function execution time, it turns out that profilers are subject to some-
thing like the observer effect in physics: the act of observing the performance of code
modifies the performance of the code.
Profilers can take two basic strategies representing a basic trade-off: either they can
intrude on the code being measured by adding special code to collect performance
statistics (basically automating the creation of code as in the previous listing), or they
can passively monitor the runtime by checking what piece of code is being executed at
a particular moment in time. Of these two approaches, the latter does less to distort
the performance of the code being profiled, but at the cost of lower-quality data.
Firebug subjects results to a further distortion because its profiler executes inside Fire-
fox’s own process, which creates the potential for it to rob the code it is measuring of
performance.
Nevertheless, the “Percent” column of Firebug’s output demonstrates the power of
measuring relative execution time: you can perform a high-level task in your page’s
interface (e.g., click the Send button) and then check Firebug’s profiler to see which
functions spent the most time executing, and focus your optimization efforts on those.
When Latency Goes Bad
It turns out that if your JavaScript code ties up the browser thread for a particularly
long time, most browsers will intervene and give the user the opportunity to interrupt
your code. There is no standard behavior governing how browsers make the
determination to give the user this opportunity. (For details on individual browser
behavior, see http://www.nczonline.net/blog/2009/01/05/what-determines-that-a-script
-is-long-running/.)
The lesson is simple: don’t introduce potentially long-running, poorly performing code
into your web page.
Threading
Once you’ve identified code that performs inadequately, of course the next step is to
go about optimizing it. However, sometimes the task to perform is simply expensive
and cannot be magically optimized to take less time. Are such scenarios fated to bring
sluggish horror to a user interface? Will no solution emerge to keep our users happy?
The traditional solution in such cases is to use threads to push such expensive code off
the thread used to interact with the user. In our scenario, this would let the browser
continue to process events from the event queue and keep the interface responsive while
the long-running code merrily executes on a different thread (and the operating system
12 | Chapter 2: Creating Responsive Web Applications
takes responsibility for making sure that both the browser user interface thread and the
background thread equitably share the computer’s resources).
However, JavaScript doesn’t support threads, so there’s no way for JavaScript code to
create a background thread to execute expensive code. Further, this isn’t likely to
change anytime soon.
Brendan Eich, the creator of JavaScript and Mozilla’s chief technical officer, has made
his position on this issue clear:†
You must be [as tall as an NBA player] to hack on threaded systems, and that means
most programmers should run away crying. But they don’t. Instead, as with most other
sharp tools, the temptation is to show how big one is by picking up the nearest single-
threaded code and jamming it into a multi-threaded embedding, or tempting race-
condition fate otherwise. Occasionally the results are infamous, but too often, with only
virtual fingers and limbs lost, no one learns.
Threads violate abstractions six ways to Sunday. Mainly by creating race conditions,
deadlock hazards, and pessimistic locking overhead. And still they don’t scale up to
handle the megacore teraflop future.
So my default answer to questions such as, “When will you add threads to JavaScript?”
is: “over your dead body!”
Given Brendan’s influence in the industry and on the future of JavaScript (which is
considerable), and the broad degree to which this position is shared, it is safe to say
that threads will not be coming to JavaScript anytime soon.
However, there are alternatives. The basic problem with threads is that different threads
can have access to and modify the same variables. This causes all sorts of problems
when Thread A modifies variables that Thread B is actively modifying, and so on. You
might think these sorts of issues could be kept straight by decent programmers, but it
turns out that, as Brendan said, even the best of us make pretty horrible mistakes in
this department.
Ensuring Responsiveness
What’s needed is a way to have the benefit of threads—tasks executing in parallel—
without the hazards of the threads getting into each other’s business. Google imple-
mented just such an API in its popular Gears browser plug-in: the WorkerPool API. It
essentially allows the main browser JavaScript thread to create background “workers”
that receive some simple “message” (i.e., standalone state, not references to shared
variables) from the browser thread when they are kicked off and return a message upon
completion.
† http://weblogs.mozillazine.org/roadmap/archives/2007/02/threads_suck.html
Ensuring Responsiveness | 13
Experience with this API in Gears has led many browsers (e.g., Safari 4, Firefox 3.1) to
implement support for “workers” natively based on a common API defined in the
HTML 5 specification. This feature is known as “Web Workers.”
Web Workers
Let’s consider how to use the Web Worker API to decrypt a value. The following listing
shows how to create and kick off a worker:
// create and begin execution of the worker
var worker = new Worker("js/decrypt.js");
// register an event handler to be executed when the worker
// sends the main thread a message
worker.onmessage = function(e) {
alert("The decrypted value is " + e.data);
}
// send a message to the worker, in this case the value to decrypt
worker.postMessage(getValueToDecrypt());
Now let’s take a look at the hypothetical contents of js/decrypt.js:
// register a handler to receive messages from the main thread
onmessage = function(e) {
// get the data passed to us
var valueToDecrypt = e.data;
// TODO: implement decryption here
// return the value to the main thread
postMessage(decryptedValue);
}
Any potentially expensive (i.e., long-running) JavaScript operations that your page
performs should be delegated to workers, as that will keep your application running
lickety-split.
Gears
If you find yourself supporting a browser that doesn’t support the Web Worker API,
there are a few alternatives. We mentioned Google’s Gears plug-in in the preceding
section; you can use the Gears plug-in to bring something very much like Web Workers
to Internet Explorer, to older versions of Firefox, and to older versions of Safari.
The Gears worker API is similar but not identical to the Web Worker API. Here are the
previous two code listings converted to the Gears API, starting with the code executed
on the main thread to spawn a worker:
14 | Chapter 2: Creating Responsive Web Applications
// create a worker pool, which spawns workers
var workerPool = google.gears.factory.create('beta.workerpool');
// register the event handler that receives the message from the worker
workerPool.onmessage = function(ignore1, ignore2, e) {
alert("The decrypted value is + " e.body);
}
// create a worker
var workerId = workerPool.createWorkerFromUrl("js/decrypt.js");
// send a message to the worker
workerPool.sendMessage(getValueToDecrypt(), workerId);
And here is the Gears version of js/decrypt.js:
var workerPool = google.gears.workerPool;
workerPool.onmessage = function(ignore1, ignore2, e) {
// get the data passed to us
var valueToDecrypt = e.body;
// TODO: implement decryption here
// return the value to the main thread
workerPool.sendMessage(decryptedValue, e.sender);
}
More on Gears
It is interesting to note some of the history of the Gears Worker Pool because it came
from a very practical place. The Gears plug-in was built by a team at Google that was
trying to push the browser to do more than it currently was able (this was before Google
Chrome—but even with Chrome, Google wants as many users as possible to do great
things with its web applications).
Imagine if you wanted to build Gmail Offline; what would you need? First, you’d need
a way to cache documents locally and to have an intercept so that when the browser
tries to access http://mail.google.com/, it gets the page back instead of a message stating
that you are offline. Second, it needs a way to store your email, both new and old. This
could be done in many forms, but since SQLite is well known and already in most new
browsers and bundled in many operating systems, why not use that? Here’s where the
problem lies.
We have been talking about the issues with a single-threaded browser. Now imagine
operations such as writing new messages to the database or performing long queries.
We can’t freeze the UI while the database does its work—the latency could be enor-
mous! The Gears team needed a way to get around this. Since the Gears plug-in can do
whatever it wants, it can easily work around the lack of threads in JavaScript. But since
the need for concurrency is a general problem, why not give this ability to the outside
world? Hence the “Worker Pool” API, which led to the HTML 5 standard “Web
Workers.”
Ensuring Responsiveness | 15
The two APIs look subtly different, but this is because Web Workers is sort of like
version 2.0 of the pioneering Gears API; Gears should support the standard API soon.
There are already “shim” libraries that bridge the existing Gears API and the standard
Web Worker API, and these shims can be used to work even without Gears or Web
Workers (by using setTimeout(), described in this chapter).
Timers
Another approach, common before Gears and Web Workers, was simply to split up
long-running operations into separate chunks and use JavaScript timers to control the
execution. For example:
var functionState = {};
function expensiveOperation() {
var startTime = new Date().getMilliseconds();
while ((new Date().getMilliseconds() - startTime) < 100) {
// TODO: implement expensive operation in such a way
// that it performs work in iterative chunks that complete
// in less than 100 ms and shove state in "functionState"
// outside this function; good luck with that ;-)
}
if (!functionState.isFinished) {
// re-enter expensiveOperation 10 ms after exiting; experiment
// with larger values to strike the right balance between UI
// responsiveness and performance
setTimeout(expensiveOperation(), 10);
}
}
Splitting up the operation in the manner just illustrated will result in a responsive in-
terface, but as the comment in the listing indicates, it may not be straightforward (or
even feasible) to structure the operation in that way. See “Yielding Using
Timers” on page 103 for more details on using setTimeout() in this manner.
There’s another fundamental issue with this approach. Most modern computers have
multiple “cores,” which means that they have the ability to execute multiple threads in
a truly concurrent fashion (whereas previous computers have only emulated concur-
rency through fast task switching). Implementing task switching manually via Java-
Script as we’ve done in the listing can’t take advantage of such architectures; you are
therefore leaving processing power on the table by forcing one of the cores to do all of
the processing.
Thus, it is possible to perform long-running operations on the browser’s main thread
and maintain a responsive interface, but it’s easier and more efficient to use workers.
16 | Chapter 2: Creating Responsive Web Applications
XMLHttpRequest
A discussion of threading wouldn’t be complete without touching briefly on the famed
enabler of the Ajax revolution: XMLHttpRequest, or “XHR” for short. Using XHR, a web
page may send a message and receive a response entirely from the JavaScript environ-
ment, a feat that enables rich interactivity without loading new pages.
XHR has two basic execution modes: synchronous and asynchronous. In the asyn-
chronous mode, XHR is essentially a Web Worker but with a specialized API; indeed,
coupled with other features of the in-progress HTML 5 specification, you can re-create
the functionality of XHR with a worker. In the synchronous mode, XHR acts as though
it performs all of its work on the browser’s main thread and will therefore introduce
user interface latency that lasts as long as XHR takes to send its request and parse the
response from the server. Therefore, never use XHR in synchronous mode, as it can
lead to unpredictable user interface latency well outside of tolerable ranges.
Effects of Memory Use on Response Time
There’s another key aspect to creating responsive web pages: memory management.
Like many modern high-level languages that abstract away low-level memory manage-
ment, most JavaScript runtimes implement garbage collection (or “GC” for short).
Garbage collection can be a magical thing, relieving developers from tedious details
that feel more like accounting than programming.
However, automatic memory management comes with a cost. All but the most
sophisticated of GC implementations “stop the world” when they perform their col-
lections; that is, they freeze the entire runtime (including what we’ve been calling the
main browser JavaScript thread) while they walk the entire “heap” of created objects,
searching for those that are no longer being used and are therefore eligible for recycling
into unused memory.
For most applications, GC is truly transparent; the runtime is frozen for short enough
periods of time that it escapes the user’s attention entirely. However, as an application’s
memory footprint increases in size, the time required to walk through the entire heap
searching for objects that are no longer in use grows and can eventually reach levels
that a user does notice.
When this occurs, the application begins to be intermittently sluggish on somewhat
regular intervals; as the problem gets worse, the entire browser may freeze on these
intervals. Both cases lead to a frustrating user experience.
Most modern platforms provide sophisticated tools that enable you to monitor the
performance of the runtime’s GC process and to view the current set of objects on the
heap in order to diagnose GC-related problems. Unfortunately, JavaScript runtimes
don’t fall into that category. To make matters worse, no tools exist that can inform
developers when collections occur or how much time they are spending performing
Ensuring Responsiveness | 17
their work; such tools would be very helpful to verify that observed latency is related
to GC.
This tool gap is a serious detriment toward the development of large-scale browser-
hosted JavaScript applications. Meanwhile, developers must guess whether GC is
responsible for UI delays.
Virtual Memory
There is another danger associated with memory: paging. Operating systems have two
classes of memory they make available to applications: physical and virtual. Physical
memory is mapped to extremely fast RAM chips in the underlying computer; virtual
memory is mapped to a much slower mass storage device (e.g., hard drive) that makes
up for its relative pokiness with much larger available storage space.
If your web page’s memory requirements grow sufficiently large, you may force the
operating system to start paging, an extremely slow process whereby other processes
are forced to relinquish their real memory to make room for the browser’s increased
appetite. The term paging is used because all modern operating systems organize mem-
ory into individual pages, the term used to describe the smallest unit of memory that
is mapped to either real or virtual memory. When paging occurs, pages are transferred
from real to virtual memory (i.e., from RAM to a hard drive) or vice versa.
The performance degradation caused by paging is a bit different from GC pauses; pag-
ing results in a general, pervasive sluggishness whereas GC pauses tend to manifest
themselves as discrete, individual pauses that occur in intervals—though the lengths
of the pauses grow over time. Regardless of their differences, either one of these prob-
lems represents significant threats to your goal of creating a responsive user interface.
Troubleshooting Memory Issues
As we mentioned earlier, we know of no good memory troubleshooting tools for
browser-hosted JavaScript applications. The state of the art is to observe the memory
footprint of the browser process (see the section “Measuring Memory Use” at http://
blog.pavlov.net/2008/03/11/firefox-3-memory-usage/ for details on how to measure
process memory usage in Windows and OS X), and if it grows larger than is tolerable
during the course of your application, check whether your code has any opportunities
for memory usage optimizations.
Once you’ve determined that you have a memory problem, you should look for op-
portunities to clean up after yourself where you haven’t yet done so. You can do this
in two ways:
• Use the delete keyword to remove JavaScript objects that are no longer needed
from memory.
• Remove nodes that are no longer necessary from the web page DOM.
18 | Chapter 2: Creating Responsive Web Applications
The following code listing demonstrates how to perform both of these tasks:
var page = { address: "http://some/url" };
page.contents = getContents(page.address);
...
// later, the contents are no longer necessary
delete page.contents;
...
var nodeToDelete = document.getElementById("redundant");
// remove the node from the DOM (which can only be done via
// call to removeChild() from parent node) and
// simultaneously delete the node from memory
delete nodeToDelete.parent.removeChild(nodeToDelete);
Obviously, there is significant room for improvement in the area of memory usage
optimization for web pages. At Mozilla, we are currently developing tools to address
this problem. In fact, by the time you read this, you should be able to find one or more
such tools by visiting http://labs.mozilla.com.
Summary
Ajax ushered in a new era of long-running, JavaScript-centric web pages. Such web
pages are really browser-hosted applications and are subject to the same user interface
guidelines of any other application. It is vital that such applications keep the user
interface responsive by minimizing operations performed on the main application
thread.
Web Workers are a powerful new tool that can be used to offload complex operations
that threaten UI responsiveness. The Gears plug-in and JavaScript timers can be used
when Web Workers are unavailable.
Poorly managed memory can lead to UI performance problems. While there’s a short-
age of good tools to troubleshoot memory problems, developers can generally observe
browser memory usage and take steps to minimize their application’s memory footprint
when problems arise. The good news is that memory troubleshooting tools are in
development.
Summary | 19
Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders
CHAPTER 3
Splitting the Initial Payload
The growing adoption of Ajax and DHTML (Dynamic HTML) means today’s web
pages have more JavaScript and CSS than ever before. Web applications are becoming
more like desktop applications, and just like desktop applications, a large percentage
of the application code isn’t used at startup. Advanced desktop applications have a
plug-in architecture that allows for modules to be loaded dynamically, a practice that
many Web 2.0 applications could benefit from. In this chapter I show some popular
Web 2.0 applications that load too much code upfront, and I discuss approaches for
making pages load more dynamically.
Kitchen Sink
Facebook has 14 external scripts totaling 786 KB uncompressed.* Figuring out how
much of that JavaScript is necessary for the initial page to render is difficult to do, even
for a core Facebook frontend engineer. Some of those 14 external scripts are critical to
rendering the initial page, but others were included because they support Ajax and
DHTML functionality, such as the drop-down menus and the Comment and Like fea-
tures shown in Figure 3-1.
It’s critical to render a web page as quickly as possible. Doing so engages the user and
creates a responsive experience for her. Imagine if the Facebook JavaScript could be
split into two parts: what’s needed to render the initial page, and everything else. Rather
than bog down the user’s first impression with “everything else,” the initial JavaScript
download should include only what’s necessary for the initial rendering. The remaining
JavaScript payload can be loaded later.
* Fourteen scripts are downloaded when logged-in users visit this page. If the user is not logged in, fewer scripts
are used.
21
Figure 3-1. Facebook Ajax and DHTML features
This raises several questions:
• How much does this save?
• How do you find where to split the code?
• What about race conditions?
• How do you download “everything else” later?
The first three questions are tackled in this chapter. How to load “everything else” is
the topic of Chapter 4.
Savings from Splitting
It turns out that Facebook executes only 9% of the downloaded JavaScript functions
by the time the onload event is called. This is computed by using Firebug’s JavaScript
profiler to count all the functions executed up to the onload event.† The counting stops
at the onload event because functionality needed after this point can, and should, be
downloaded after the initial page has rendered. I call this a post-onload download. (See
Chapter 4 for various lazy-loading techniques.)
Table 3-1 shows the percentage of functions downloaded that are not executed before
the onload event for 10 top U.S. web sites. On average, 75% of the functions
† Firebug is the preeminent web development tool, available at http://getfirebug.com/.
22 | Chapter 3: Splitting the Initial Payload
downloaded are not executed during the initial rendering of the page. Thus, if down-
loading of these unexecuted functions was deferred, the size of the initial JavaScript
download would be dramatically reduced.
Admittedly, the 75% estimate might be exaggerated; some of the unexecuted functions
might be required for error handling or other special conditions. The estimate is still
useful to illustrate the point that much of the JavaScript downloaded initially could be
deferred. The average total amount of JavaScript is 252 KB uncompressed. This per-
centage is in terms of function count, not size. If we assume a constant function size,
75% represents an average 189 KB that doesn’t have to be downloaded until after the
onload event, making the initial page render more quickly.
Table 3-1. Percentage of JavaScript functions executed before onload
Web site % of functions not executed JavaScript size uncompressed
http://www.aol.com/ 71% 115 KB
http://www.ebay.com/ 56% 183 KB
http://www.facebook.com/ 91% 786 KB
http://www.google.com/search?q=flowers 56% 15 KB
http://search.live.com/results.aspx?q=flowers 75% 17 KB
http://www.msn.com/ 69% 131 KB
http://www.myspace.com/ 87% 297 KB
http://en.wikipedia.org/wiki/Flowers 79% 114 KB
http://www.yahoo.com/ 88% 321 KB
http://www.youtube.com/ 84% 240 KB
Finding the Split
Firebug’s JavaScript profiler shows the names of all the functions that were executed
by the time of the onload event. This list can be used to manually split the JavaScript
code into one file loaded as part of the initial page rendering and another file to be
downloaded later. However, because some of the unused functions may still be nec-
essary for error-handling and other conditional code paths, splitting the code into an
initialdownloadthatiscompletewithoutundefinedsymbolsisachallenge.JavaScript’s
higher-order features, including function scoping and eval, make the challenge even
more complicated.
Doloto is a system developed by Microsoft Research for automatically splitting Java-
Script into clusters. The first cluster contains the functions needed for initializing the
web page. The remaining clusters are loaded on demand the first time the missing code
needs to execute, or they are lazy-loaded after the initial flurry of JavaScript activity is
over. When applied to Gmail, Live Maps, Redfin, MySpace, and Netflix, Doloto re-
Finding the Split | 23
duced the initial JavaScript download size by up to 50% and reduced the application
load time by 20% to 40%.
Doloto’s decisions about where to split the code are based on a training phase and can
result in the JavaScript being split into multiple downloads. For many web applications,
it is preferable to define a single split at the onload event, after which the remaining
JavaScript is immediately downloaded using the nonblocking techniques described in
Chapter 4. Waiting to start the additional downloads on demand after the user has
pulled down a menu or clicked on a page element forces the user to wait for the addi-
tional JavaScript to arrive. This wait can be avoided if all the additional JavaScript is
downloaded after the initial page rendering. Until Doloto or other systems are publicly
available, developers need to split their code manually. The following section discusses
some of the issues to keep in mind when doing this.
Undefined Symbols and Race Conditions
The challenge in splitting your JavaScript code is to avoid undefined symbols. This
problem arises if the JavaScript being executed references a symbol that has, mistak-
enly, been relegated to a later download. In the Facebook example, for instance, I
suggest that the JavaScript for drop-down menus should be loaded later. But if the
drop-down menu is displayed before the required JavaScript is downloaded, there’s a
window in which the user can click on the drop-down menu and the required JavaScript
won’t be available. My suggestion would then have created a race condition where the
JavaScript is racing to download while the user is racing to click the menu. In most
cases, the JavaScript will win the race, but there is a definite possibility that the user
may click first and experience an undefined symbol error when the (yet to be down-
loaded) drop-down menu function is called.
In a situation where the delayed code is associated with a UI element, the problem can
be avoided by changing the element’s appearance. In this case, the menu could contain
a “Loading…” spinner, alerting the user that the functionality is not yet available.
Another option is to attach handlers to UI elements in the lazy-loaded code. In this
example, the menu would be rendered initially as static text. Clicking on it would not
execute any JavaScript. The lazy-loaded code would both contain the menu function-
ality and would attach that behavior to the menu using attachEvent in Internet Explorer
and addEventListener in all other browsers.‡
In situations where the delayed code is not associated with a UI element, the solution
to this problem is to use stub functions. A stub function is a function with the same
name as the original function but with an empty function body or temporary code in
place of the original. The previous section described Doloto’s ability to download
additional JavaScript modules on demand. Doloto implements this on-demand feature
‡ See http://www.quirksmode.org/js/events_advanced.html for more information.
24 | Chapter 3: Splitting the Initial Payload
by inserting stub functions in the initial download that, when invoked, dynamically
download additional JavaScript code. When the additional JavaScript code is down-
loaded, the original function definitions overwrite the stub functions.
A simpler approach is to include an empty stub function for each function that is ref-
erenced but relegated to the later download. If necessary, the stub function should
return a stub value, such as an empty string. If the user tries to invoke a DHTML feature
before the full function implementation is downloaded, nothing happens. A slightly
more advanced solution has each stub function record the user’s requests and invokes
those actions when the lazy-loaded JavaScript arrives.
Case Study: Google Calendar
A good example of splitting the initial payload is Google Calendar. Figure 3-2 shows
the HTTP requests that are made when Google Calendar is requested. I call these
charts HTTP waterfall charts. Each horizontal bar represents one request. The resource
type is shown on the left. The horizontal axis represents time, so the placement of the
bars shows at what point during page load each resource was requested and received.
Figure 3-2. Google Calendar HTTP waterfall chart
Google Calendar requests five scripts totaling 330 KB uncompressed. The payload is
split into an initial script of 152 KB that is requested early (the third bar from the top).
The blocking behavior of this script is mitigated by the fact that it contains less than
half of the total JavaScript. The rest of the JavaScript payload is requested last, after
the page has been allowed to render.
By splitting their JavaScript, the Google Calendar team creates a page that renders more
quickly than it would have if all of the JavaScript were loaded in one file. Splitting a
web application’s JavaScript is not a simple task. It requires determining the functions
needed for initial rendering, finding all required code dependencies, stubbing out other
functions, and lazy-loading the remaining JavaScript. Further automation for these
tasks is needed. Microsoft’s Doloto project describes such a system, but as of this writ-
ing, it’s not available publicly. Until tools such as this are made available, developers
will have to roll up their sleeves and do the heavy lifting themselves.
Case Study: Google Calendar | 25
This chapter has focused on splitting JavaScript, but splitting CSS stylesheets is also
beneficial. The savings are less than those gained by splitting JavaScript because the
total size of stylesheets is typically less than JavaScript, and downloading CSS does not
have the blocking characteristics that downloading JavaScript has.§ This is another
opportunity for further research and tool development.
§ Firefox 2 is the one exception.
26 | Chapter 3: Splitting the Initial Payload
CHAPTER 4
Loading Scripts Without Blocking
SCRIPT tags have a negative impact on page performance because of their blocking
behavior. While scripts are being downloaded and executed, most browsers won’t
download anything else. There are times when it’s necessary to have this blocking, but
it’s important to identify situations when JavaScript can be loaded independent of the
rest of the page.
When these opportunities arise, we want to load the JavaScript in such a way that it
does not block other downloads. Luckily, there are several techniques for doing this
that make pages load faster. This chapter explains these techniques, compares how
they affect the browser and performance, and describes the circumstances that make
one approach preferred over another.
Scripts Block
JavaScript is included in a web page as an inline script or an external script. An inline
script includes all the JavaScript in the HTML document itself using the SCRIPT tag:
<script>
function displayMessage(msg) {
alert(msg);
}
</script>
External scripts pull in the JavaScript from a separate file using the SCRIPT SRC attribute:
<script src='A.js'></script>
The SRC attribute specifies the URL of the external file that needs to be loaded. The
browser reads the script file from the cache, if available, or makes an HTTP request to
fetch the script.
Normally, most browsers download components in parallel, but that’s not the case for
external scripts. When the browser starts downloading an external script, it won’t start
any additional downloads until the script has been completely downloaded, parsed,
and executed. (Any downloads that were already in progress are not blocked.)
27
Figure 4-1 shows the HTTP requests for the Scripts Block Downloads example.*
Scripts Block Downloads
http://stevesouders.com/cuzillion/?ex=10008&title=Scripts+Block+Downloads
This page has two scripts at the top, A.js and B.js, followed by an image, a stylesheet,
and an iframe. The scripts are each programmed to take one second to download and
one second to execute. The white gaps in the HTTP profile indicate where the scripts
are executed. This shows that while scripts are being downloaded and executed, all
other downloads are blocked. Only after the scripts have finished are the image, style-
sheet, and iframe merrily downloaded in parallel.
Figure 4-1. Scripts block parallel downloads
The reason browsers block while downloading and executing a script is that the script
may make changes to the page or JavaScript namespace that affect whatever follows.
The typical example cited is when A.js uses document.write to alter the page. Another
example is when A.js is a prerequisite for B.js. The developer is guaranteed that scripts
are executed in the order in which they appear in the HTML document so that A.js is
downloaded and executed before B.js. Without this guarantee, race conditions could
result in JavaScript errors if B.js is downloaded and executed before A.js.
Although it’s clear that scripts must be executed sequentially, there’s no reason they
have to be downloaded sequentially. That’s where Internet Explorer 8 comes in. The
behavior shown in Figure 4-1 is true for most browsers, including Firefox 3.0 and earlier
and Internet Explorer 7 and earlier. However, Internet Explorer 8’s download profile,
shown in Figure 4-2, is different. Internet Explorer 8 is the first browser that supports
downloading scripts in parallel.
Figure 4-2. Internet Explorer 8 downloads scripts without blocking
* This and other examples are generated from Cuzillion, a tool I built specifically for this chapter. See the
Appendix for more information about Cuzillion.
28 | Chapter 4: Loading Scripts Without Blocking
The ability of Internet Explorer 8 to download scripts in parallel makes pages load
faster, but as shown in Figure 4-2, it doesn’t entirely solve the blocking problem. It is
true that A.js and B.js are downloaded in parallel, but the image and iframe are still
blocked until the scripts are downloaded and executed. Safari 4 and Chrome 2 are
similar—they download scripts in parallel, but block other resources that follow.†
What we really want is to have scripts downloaded in parallel with all the other com-
ponents in the page. And we want this in all browsers. The techniques discussed in the
next section explain how to do just that.
Making Scripts Play Nice
There are several techniques for downloading external scripts without having your page
suffer from their blocking behavior. One technique I don’t suggest doing is inlining all
of your JavaScript. In a few situations (home pages, small amounts of JavaScript),
inlining your JavaScript is acceptable, but generally it’s better to serve your JavaScript
in external files because of the page size and caching benefits derived. (For more
information about these trade-offs, see High Performance Web Sites, “Rule 8: Make
JavaScript and CSS External.”)
The techniques listed here provide the benefits of external scripts without the slow-
downs imposed from blocking:
• XHR Eval
• XHR Injection
• Script in Iframe
• Script DOM Element
• Script Defer
• document.write Script Tag
The following sections describe each of these techniques in more detail, followed by a
comparison of how they affect the browser and which technique is best under different
circumstances.
XHR Eval
In this technique, an XMLHttpRequest (XHR) retrieves the JavaScript from the server.
When the response is complete, the content is executed using the eval command as
shown in this example page.
† As of this writing, Firefox does not yet support parallel script downloads, but that is expected soon.
Making Scripts Play Nice | 29
Another Random Document on
Scribd Without Any Related Topics
Eylau.
Combat de
Ziegelhoff, livré
le 7 février au
soir.
Combat dans
l'intérieur de la
ville d'Eylau.
carte no
40), et devant lequel on arrive au sortir
des bois dont la route de Landsberg à Eylau est
couverte. Les généraux Bagowout et Barklay de Tolly étaient en
position sur ce plateau, prêts à renouveler le combat de la veille. Le
général Benningsen, sentant bien qu'il était serré de trop près pour
ne pas être amené à une bataille, tenait beaucoup à occuper ce
plateau, sur lequel on pouvait recevoir avec avantage l'armée
française débouchant de la région boisée. Il tenait de plus à protéger
l'arrivée de sa grosse artillerie, à laquelle il avait ordonné de faire un
détour. Par tous ces motifs sa résistance sur ce point devait être
opiniâtre.
La cavalerie de Murat, secondée par l'infanterie
du maréchal Soult, déboucha des bois avec sa
hardiesse accoutumée, et s'avança sur le plateau
de Ziegelhoff. La brigade Levasseur, composée des
46e
et 28e
régiments de ligne, la suivit résolument,
pendant que la brigade Viviès, filant à droite, essayait à travers des
lacs gelés de tourner la position. La brigade Levasseur, que le feu
d'une nombreuse artillerie excitait à brusquer l'attaque, hâta le pas.
Une première ligne d'infanterie ennemie fut d'abord repoussée à la
baïonnette. Mais la cavalerie russe, chargeant à propos sur la gauche
de la brigade, renversa le 28e
, avant qu'il eût le temps de se former
en carré. Elle sabra beaucoup de nos fantassins, et enleva une aigle.
Le combat bientôt rétabli, se continua de part et
d'autre avec acharnement. Cependant la brigade
Viviès ayant débordé la position des Russes, ceux-
ci la quittèrent pour se retirer dans la ville même
d'Eylau. Le maréchal Soult y pénétra en même temps qu'eux.
Napoléon ne voulait pas qu'on leur laissât la ville d'Eylau, pour le cas
incertain, mais probable, d'une grande bataille. On entra donc
baïonnette baissée dans Eylau. Les Russes s'y défendirent
opiniâtrement de rue en rue. On tourna la ville, et on trouva une de
leurs colonnes établie dans un cimetière, devenu fameux depuis par
de terribles souvenirs, et qui était situé en dehors à droite. La
Les Russes
s'arrêtent le 7
au soir au delà
d'Eylau, et
paraissent
disposés à livrer
bataille.
État de l'armée
française la
veille de la
bataille d'Eylau.
brigade Viviès emporta ce cimetière après un combat des plus rudes.
Les Russes se replièrent au delà d'Eylau. De toutes les rencontres
d'arrière-garde, celle-ci avait été la plus sanglante, et elle avait coûté
au corps du maréchal Soult des pertes considérables. On se jeta un
peu en désordre dans la ville d'Eylau, les soldats se dispersant pour
vivre, et surprenant dans les maisons beaucoup de Russes qui
n'avaient pas eu le temps de s'enfuir.
La première opinion que conçut Murat, et qu'il
transmit à Napoléon, c'est que les Russes, ayant
perdu le point d'appui d'Eylau, iraient en chercher
un plus éloigné. Cependant quelques officiers
égarés dans cette mêlée, avaient aperçu les
Russes établis un peu au delà d'Eylau, et allumant
leurs feux de bivouac pour y passer la nuit. Cette
observation, confirmée par de nouveaux rapports, ne permit aucun
doute sur l'importance de la journée du lendemain 8 février; et en
effet, elle en a acquis une qui lui assure l'immortalité dans les
siècles.
Il devenait évident que les Russes, s'arrêtant
cette fois après le combat du soir, et n'employant
pas la nuit à marcher, étaient résolus à engager le
lendemain une action générale. L'armée française
était harassée de fatigue, fort réduite en nombre
par la rapidité des marches, travaillée par la faim, et transie de froid.
Mais il fallait livrer bataille, et ce n'était pas en semblable occasion,
que soldats, officiers, généraux, avaient coutume de sentir leurs
souffrances.
Napoléon se hâta de dépêcher le soir même plusieurs officiers aux
maréchaux Davout et Ney pour les ramener, l'un à sa droite, l'autre à
sa gauche. Le maréchal Davout avait continué de suivre l'Alle jusqu'à
Bartenstein, et il ne se trouvait plus qu'à trois ou quatre lieues. Il
répondit qu'il arriverait dès la pointe du jour vers la droite d'Eylau
(droite de l'armée française), prêt à donner dans le flanc des Russes.
Effectif des
corps
composant
l'armée
française à la
bataille d'Eylau.
Le maréchal Ney, qu'on avait dirigé sur la gauche, de façon à tenir
les Prussiens à distance, et à pouvoir fondre sur Kœnigsberg dans le
cas où les Russes se jetteraient derrière la Prégel, le maréchal Ney
était en marche sur Kreutzbourg. On fit courir après lui, sans être
aussi assuré de l'amener à temps sur le champ de bataille, qu'on
l'était d'y voir paraître le maréchal Davout.
Privée du corps de Ney, l'armée française
s'élevait tout au plus à cinquante et quelques mille
hommes, bien que les Russes l'aient portée à 80
mille dans leurs relations, et un historien français,
ordinairement digne de foi, à 68[19]. Le corps du
maréchal Davout, dont l'effectif présentait 26 mille
hommes à Awerstaedt, sensiblement diminué par les combats livrés
depuis, par les maladies, par la dernière marche de la Vistule à
Eylau, par les détachements laissés sur la Narew, était fort de 15
mille hommes environ. Le corps du maréchal Soult, le plus nombreux
de toute l'armée, très-réduit également par la dyssenterie, la
marche, les combats d'arrière-garde, ne pouvait pas être évalué à
plus de 16 ou 17 mille hommes. Celui du maréchal Augereau, affaibli
d'une quantité de traînards et de maraudeurs qui s'étaient dispersés
pour vivre, n'en comptait que 6 à 7 mille au bivouac d'Eylau, dans la
soirée du 7 février. La garde, mieux traitée, plus retenue par la
discipline, n'avait laissé personne en arrière. Toutefois elle ne
s'élevait qu'à 6 mille hommes. Enfin la cavalerie de Murat, composée
d'une division de cuirassiers et de trois divisions de dragons, ne
présentait guère que 10 mille cavaliers dans le rang. C'était donc
une force totale de 53 à 54 mille combattants, capables de tout, il
est vrai, quoique accablés de fatigue, et épuisés par la faim. Si le
maréchal Ney arrivait à temps, il devenait possible d'opposer 63
mille hommes à l'ennemi, tous présents au feu. Il ne fallait pas
espérer de voir arriver le corps de Bernadotte, demeuré à une
distance de trente lieues.
Napoléon, qui pendant cette nuit dormit à peine trois ou quatre
heures sur une chaise, dans la maison du maître de poste, plaça le
Raisons qui
décident le
général
Benningsen à
livrer bataille.
Force de l'armée
russe.
corps du maréchal Soult à Eylau même, partie dans l'intérieur, partie
à droite et à gauche de la ville, le corps d'Augereau et la garde
impériale un peu en arrière, toute la cavalerie sur les ailes, attendant
qu'il fît jour pour arrêter ses dispositions.
Le général Benningsen s'était enfin déterminé à
livrer bataille. Il se trouvait en plaine, ou à peu
près, terrain excellent pour ses fantassins, peu
manœuvriers mais solides, et pour sa cavalerie qui
était nombreuse. Sa grosse artillerie, à laquelle il
avait fait faire un détour, pour qu'elle ne gênât pas
ses mouvements, venait de le rejoindre. C'était un précieux renfort.
De plus il était tellement poursuivi, qu'il se voyait forcé d'interrompre
sa marche pour tenir tête aux Français. Il faut, à une armée qui bat
en retraite, un peu d'avance, afin qu'elle puisse dormir et manger. Il
faut aussi qu'elle n'ait pas l'ennemi trop près d'elle, car essuyer une
attaque en route, le dos tourné, est la plus dangereuse manière de
recevoir une bataille. Il est donc un moment où ce qu'il y a de plus
sage est de choisir son terrain et de s'y arrêter pour combattre. C'est
la résolution que prit le général Benningsen le 7 au soir. Il fit halte
au delà d'Eylau, résolu à soutenir une lutte acharnée. Son armée,
qui s'élevait à 78 ou 80 mille hommes, et à 90
mille avec les Prussiens, lors de la reprise des
hostilités, avait fait des pertes assez notables dans
les derniers combats, mais fort peu dans les marches, car une armée
qui se retire sans être en déroute, est ralliée par l'ennemi qui la
poursuit, tandis que l'armée poursuivante, n'ayant pas les mêmes
motifs de se serrer, laisse toujours une partie de son effectif en
arrière. En défalquant les pertes essuyées à Mohrungen, à Bergfried,
à Waltersdorf, à Hoff, à Heilsberg, à Eylau même[20], on peut dire
que l'armée du général Benningsen était réduite à 80 mille hommes
environ, dont 72 mille Russes et 8 mille Prussiens. Ainsi en attendant
l'arrivée du général Lestocq et du maréchal Ney, 72 mille Russes
allaient combattre 54 mille Français. Les Russes avaient de plus une
artillerie formidable, évaluée à 4 ou 500 bouches à feu. La nôtre
montait tout au plus à 200, la garde comprise. Il est vrai qu'elle était
Champ de
bataille d'Eylau.
Ordre de
bataille adopté
par les Russes.
supérieure à toutes les artilleries de l'Europe, même à celle des
Autrichiens. Le général Benningsen se décida donc à attaquer dès la
pointe du jour. Le caractère de ses soldats était énergique, comme
celui des soldats français, mais conduit par d'autres mobiles. Il n'y
avait chez les Russes ni cette confiance dans le succès, ni cet amour
de la gloire, qui se voyait chez les Français, mais un certain
fanatisme d'obéissance, qui les portait à braver aveuglément la mort.
Quant à la dose d'intelligence chez les uns et les autres, il n'est pas
nécessaire d'en faire remarquer la différence.
Depuis qu'on avait débouché sur Eylau, le pays
se montrait uni et découvert. La petite ville
d'Eylau, située sur une légère éminence, et
surmontée d'une flèche gothique, était le seul point saillant du
terrain. À droite de l'église, le sol, s'abaissant quelque peu,
présentait un cimetière. En face, il se relevait sensiblement, et sur ce
relèvement marqué de quelques mamelons, on apercevait les Russes
en masse profonde. Plusieurs lacs, pourvus d'eau au printemps,
desséchés en été, gelés en hiver, actuellement effacés par la neige,
ne se distinguaient en aucune manière du reste de la plaine. À peine
quelques granges réunies en hameaux, et des lignes de barrière
servant à parquer le bétail, formaient-elles un point d'appui ou un
obstacle, sur ce morne champ de bataille. Un ciel gris, fondant par
intervalles en une neige épaisse, ajoutait sa tristesse à celle des
lieux, tristesse qui saisit les yeux et les cœurs, dès que la naissance
du jour, très-tardive en cette saison, eut rendu les objets visibles.
Les Russes étaient rangés sur deux lignes, fort
rapprochées l'une de l'autre, leur front couvert par
trois cents bouches à feu, qui avaient été
disposées sur les parties saillantes du terrain. En
arrière, deux colonnes serrées, appuyant comme deux arcs-boutants
cette double ligne de bataille, semblaient destinées à la soutenir, et à
l'empêcher de plier sous le choc des Français. Une forte réserve
d'artillerie était placée à quelque distance. La cavalerie se trouvait
partie en arrière, partie sur les ailes. Les Cosaques, ordinairement
Disposition
opposée par
Napoléon à celle
des Russes.
dispersés, tenaient cette fois au corps même de l'armée. Il était
évident qu'à l'énergie, à la dextérité des Français, les Russes avaient
voulu, sur ce terrain découvert, opposer une masse compacte,
défendue sur son front par une nombreuse artillerie, fortement
étayée par derrière, une véritable muraille enfin, lançant une pluie
de feux. Napoléon, à cheval dès la pointe du jour, s'était établi de sa
personne dans le cimetière à la droite d'Eylau. Là, protégé à peine
par quelques arbres, il voyait parfaitement la position des Russes,
lesquels, déjà en bataille, avaient ouvert le feu par une canonnade,
qui devenait à chaque instant plus vive. On pouvait prévoir que le
canon serait l'arme de cette journée terrible.
Grâce à la position d'Eylau, qui s'allongeait en
face des Russes, Napoléon pouvait donner moins
de profondeur à sa ligne de bataille, moins de
prise par conséquent aux coups de l'artillerie. Deux
des divisions du maréchal Soult furent placées à
Eylau, la division Legrand en avant et un peu à gauche, la division
Leval partie à gauche de la ville, sur une éminence que surmontait
un moulin, partie à droite au cimetière même. La troisième division
du maréchal Soult, la division Saint-Hilaire, fut établie plus à droite
encore, à une assez grande distance du cimetière, au village de
Rothenen, qui formait le prolongement de la position d'Eylau. Dans
l'intervalle qui séparait le village de Rothenen de la ville d'Eylau,
intervalle laissé ouvert pour y faire déboucher le reste de l'armée, se
tenait un peu en arrière le corps d'Augereau, rangé sur deux lignes,
et formé des divisions Desjardins et Heudelet. Augereau, tourmenté
de la fièvre, les yeux rouges et enflés, mais oubliant ses souffrances
au bruit du canon, était monté à cheval pour se mettre à la tête de
ses troupes. Plus en arrière de ce même débouché, venaient
l'infanterie et la cavalerie de la garde impériale, les divisions de
dragons et de cuirassiers, prêtes les unes et les autres à se
présenter à l'ennemi par la même issue, et en attendant un peu
abritées du canon par l'enfoncement du terrain. Enfin à l'extrême
droite de ce champ de bataille, au delà et en avant de Rothenen, au
La bataille
d'Eylau
commence par
un violent
combat
d'artillerie.
hameau de Serpallen, devait entrer en action le corps du maréchal
Davout, de manière à donner dans le flanc des Russes.
Napoléon étant donc sur un ordre mince, et sa ligne ayant
l'avantage d'être couverte à gauche par les bâtiments d'Eylau, à
droite par ceux de Rothenen, le combat d'artillerie par lequel il
voulait démolir l'espèce de muraille que lui opposaient les Russes
était beaucoup moins redoutable pour lui que pour eux. Il avait fait
sortir des corps et mettre en bataille toutes les bouches à feu de
l'armée, il y avait joint les quarante pièces de la garde, et il allait
ainsi riposter à la formidable artillerie des Russes par une artillerie
très-inférieure en nombre, mais très-supérieure en habileté.
Les Russes avaient commencé le feu. Les
Français leur avaient répondu presque aussitôt par
une violente canonnade, exécutée à demi-portée
de canon. La terre tremblait sous cette détonation
épouvantable. Les artilleurs français, non-
seulement plus adroits, mais tirant sur une masse
vivante, qui leur servait de but, y exerçaient d'horribles ravages. Nos
boulets emportaient des files entières. Les boulets des Russes, au
contraire, lancés avec moins de justesse, et frappant sur des
bâtiments, ne nous causaient pas un dommage égal à celui que
l'ennemi éprouvait. Bientôt le feu prit à la ville d'Eylau, et au village
de Rothenen. Les lueurs de l'incendie vinrent joindre leur horreur à
l'horreur du carnage. Quoiqu'il tombât beaucoup moins de Français
que de Russes, il en tombait beaucoup encore, surtout dans les
rangs de la garde impériale, immobile dans le cimetière. Les
projectiles, passant par-dessus la tête de Napoléon, et quelquefois
bien près de lui, perçaient les murs de l'église ou brisaient les
branches des arbres au pied desquels il s'était placé pour diriger la
bataille.
Cette canonnade durait depuis long-temps, et les deux armées la
supportaient avec une tranquillité héroïque, ne faisant aucun
mouvement, et se bornant à serrer les rangs à mesure que le canon
Arrivée du
maréchal
Davout à
Serpallen.
y produisait des vides. Les Russes parurent les premiers éprouver
une sorte d'impatience[21]. Désirant accélérer le résultat par la prise
d'Eylau, ils s'ébranlèrent, pour enlever la position du moulin, située à
la gauche de la ville. Une partie de leur droite se forma en colonne,
et vint nous attaquer. La division Leval, composée des brigades
Ferey et Viviès, la repoussa vaillamment, et par sa contenance ne
permit pas aux Russes d'espérer un succès s'ils renouvelaient leurs
efforts.
Quant à Napoléon, il ne tentait rien de décisif, ne voulant pas
compromettre, en le portant en avant, le corps du maréchal Soult,
qui faisait bien assez de tenir Eylau sous une affreuse canonnade, ne
voulant pas non plus hasarder ni la division Saint-Hilaire, ni le corps
d'Augereau, contre le centre de l'ennemi, car c'eût été les exposer à
se briser contre un rocher brûlant. Il attendait pour agir que le
maréchal Davout, dont le corps arrivait sur la droite, se fit sentir
dans le flanc des Russes.
Ce lieutenant, exact autant qu'intrépide, était
parvenu en effet au village de Serpallen. La
division Friant marchait en tête. Elle déboucha la
première, rencontra les Cosaques, qu'elle eut
bientôt ramenés, et occupa le village de Serpallen
par quelques compagnies d'infanterie légère. (Voir la carte no
40.) À
peine était-elle établie dans le village et dans les terrains à droite,
que l'une des masses de cavalerie qui étaient placées sur les ailes de
l'armée russe, se détacha pour venir à elle. Le général Friant, usant
avec intelligence et sang-froid des avantages que lui offrait le hasard
des lieux, rangea les trois régiments dont se composait alors sa
division, derrière les longues et solides barrières en bois employées
à parquer les troupeaux. Abrité derrière ce retranchement naturel, il
fusilla à bout portant les escadrons russes, et les força de se retirer.
Ils se replièrent, mais ils revinrent bientôt, accompagnés d'une
colonne de neuf à dix mille hommes d'infanterie. C'était l'une des
deux colonnes serrées qui servaient d'arcs-boutants à la ligne de
bataille des Russes, qui se portait maintenant à la gauche de cette
Le corps du
maréchal
Davout ayant
produit sur la
gauche des
ligne pour reprendre Serpallen. Le général Friant n'avait pas plus de
cinq mille hommes à lui opposer. Toujours abrité derrière les
barrières en bois dont il s'était couvert, et maître de se déployer
sans craindre d'être chargé par la cavalerie, il accueillit les Russes
par un feu si nourri et si bien dirigé, qu'il leur fit essuyer une perte
considérable. Leurs escadrons ayant voulu le tourner, il forma le 33e
en carré sur sa droite, et les arrêta par la contenance inébranlable
de ses fantassins. Ne pouvant se servir de sa cavalerie, qui consistait
en quelques chasseurs à cheval, il y suppléa par une nuée de
tirailleurs, qui, profitant avec adresse des moindres accidents du
terrain, allèrent fusiller les Russes sur leurs flancs, et les obligèrent à
se retirer vers les hauteurs en arrière de Serpallen, entre Serpallen
et Klein-Sausgarten. En se retirant sur ces hauteurs, les Russes se
couvrirent par une nombreuse artillerie, dont le feu plongeant était
malheureusement très-meurtrier. La division Morand, à son tour,
était arrivée sur le champ de bataille. Le maréchal Davout
s'emparant de la première brigade, celle du général Ricard, vint la
placer au delà et à gauche de Serpallen, puis il disposa la seconde,
composée du 51e
et du 61e
, à droite du village, de manière à
soutenir ou la brigade Ricard, ou la division Friant. Celle-ci s'était
portée à droite de Serpallen, vers Klein-Sausgarten. Dans ce même
moment la division Gudin forçait le pas pour entrer en ligne. Ainsi les
Russes, par le mouvement de notre droite, avaient été contraints de
replier leur gauche, de Serpallen sur Klein-Sausgarten.
L'effet attendu dans le flanc de l'armée ennemie était donc
produit. Napoléon, de la position qu'il occupait, avait vu
distinctement les réserves russes se diriger vers le corps du
maréchal Davout. L'heure d'agir était venue, car si on n'intervenait
pas, les Russes pouvaient se jeter en masse sur le maréchal Davout,
et l'écraser. Napoléon donna sur-le-champ ses ordres. Il prescrivit à
la division Saint-Hilaire, qui était à Rothenen, de se
porter en avant, pour donner la main, vers
Serpallen, à la division Morand. Il commanda aux
deux divisions Desjardins et Heudelet du corps
Russes l'effet
attendu,
Napoléon fait
attaquer leur
centre par la
division Saint-
Hilaire et le
corps
d'Augereau.
Destruction
presque totale
d'Augereau, de déboucher par l'intervalle qui
séparait Rothenen d'Eylau, de se lier à la division
Saint-Hilaire, et toutes ensemble de former une
ligne oblique du cimetière d'Eylau à Serpallen. Le
résultat de ce mouvement devait être de culbuter
les Russes, en renversant leur gauche sur leur
centre, et d'abattre ainsi, en commençant par son
extrémité, la longue muraille qu'on avait devant
soi.
Il était dix heures du matin. Le général Saint-Hilaire s'ébranla,
quitta Rothenen, et se déploya obliquement dans la plaine, sous un
terrible feu d'artillerie, sa droite à Serpallen, sa gauche vers le
cimetière. Augereau s'ébranla presque en même temps, non sans un
triste pressentiment du sort réservé à son corps d'armée, qu'il voyait
exposé à se briser contre le centre des Russes, solidement appuyé à
plusieurs mamelons. Tandis que le général Corbineau lui transmettait
les ordres de l'Empereur, un boulet perça le flanc de ce brave officier,
l'aîné d'une famille héroïque. Le maréchal Augereau se mit
immédiatement en marche. Les deux divisions Desjardins et
Heudelet débouchèrent entre Rothenen et le cimetière, en colonnes
serrées, puis le défilé franchi, se formèrent en bataille, la première
brigade de chaque division déployée, la seconde en carré. Tandis
qu'elles s'avançaient, une rafale de vent et de neige vint frapper tout
à coup la face des soldats et leur dérober la vue du champ de
bataille. Les deux divisions, au milieu de cette espèce de nuage, se
trompèrent de direction, donnèrent un peu à gauche, et laissèrent à
leur droite un large espace entre elles et la division Saint-Hilaire. Les
Russes, peu incommodés de la neige qu'ils recevaient à dos, et
voyant s'avancer les deux divisions d'Augereau sur les mamelons
auxquels ils appuyaient leur centre, démasquèrent à l'improviste une
batterie de 72 bouches à feu qu'ils tenaient en réserve. La mitraille
vomie par cette redoutable batterie était si
épaisse, qu'en un quart d'heure la moitié du corps
d'Augereau fut abattue. Le général Desjardins,
commandant la première division, fut tué; le
du corps
d'Augereau.
général Heudelet, commandant la seconde, reçut
une blessure presque mortelle. Bientôt l'état-major
des deux divisions fut mis hors de combat. Tandis
qu'elles essuyaient ce feu épouvantable, obligées de se reformer en
marchant, tant leurs rangs étaient éclaircis, la cavalerie russe, se
précipitant dans l'espace qui les séparait de la division Morand,
fondit sur elles en masse. Ces braves divisions résistèrent toutefois,
mais elles furent obligées de rétrograder vers le cimetière d'Eylau,
cédant le terrain sans se rompre, sous les assauts répétés de
nombreux escadrons. Tout à coup la neige, ayant cessé de tomber,
permit d'apercevoir ce douloureux spectacle. Sur six ou sept mille
combattants, quatre mille environ, morts ou blessés, jonchaient la
terre. Augereau, atteint lui-même d'une blessure, plus touché au
reste du désastre de son corps d'armée que du péril, fut porté dans
le cimetière d'Eylau aux pieds de Napoléon, auquel il se plaignit, non
sans amertume, de n'avoir pas été secouru à temps. Une morne
tristesse régnait sur les visages, dans l'état-major impérial.
Napoléon, calme et ferme, imposant aux autres l'impassibilité qu'il
s'imposait à lui-même, adressa quelques paroles de consolation à
Augereau, puis il le renvoya sur les derrières, et prit ses mesures
pour réparer le dommage. Lançant d'abord les chasseurs de sa
garde, et quelques escadrons de dragons qui étaient à sa portée,
pour ramener la cavalerie ennemie, il fit appeler Murat, et lui
ordonna de tenter un effort décisif sur la ligne d'infanterie qui
formait le centre de l'armée russe, et qui profitant du désastre
d'Augereau, commençait à se porter en avant. Au premier ordre,
Murat était accouru au galop.—Eh bien, lui dit Napoléon, nous
laisseras-tu dévorer par ces gens-là?—Alors il prescrivit à cet
héroïque chef de sa cavalerie de réunir les chasseurs, les dragons,
les cuirassiers, et de se jeter sur les Russes avec quatre-vingts
escadrons, pour essayer tout ce que pouvait l'élan d'une pareille
masse d'hommes à cheval, chargeant avec fureur une infanterie
réputée inébranlable. La cavalerie de la garde fut portée en avant,
prête à joindre son choc à celui de la cavalerie de l'armée. Le
moment était critique, car si l'infanterie russe n'était pas arrêtée, elle
Charge de toute
la réserve de
cavalerie sur
l'infanterie
russe.
Murat culbute
l'infanterie
russe, et hache
le centre de leur
ligne.
allait aborder le cimetière, centre de la position, et Napoléon n'avait
pour le défendre que les six bataillons à pied de la garde impériale.
Murat part au galop, réunit ses escadrons, puis
les fait passer entre le cimetière et Rothenen, à
travers ce même débouché par lequel le corps
d'Augereau avait déjà marché à une destruction
presque certaine. Les dragons du général Grouchy
chargent les premiers, pour déblayer le terrain, et
en écarter la cavalerie ennemie. Ce brave officier, renversé sous son
cheval, se relève, se met à la tête de sa seconde brigade, et réussit
à disperser les groupes de cavaliers qui précédaient l'infanterie
russe. Mais pour renverser celle-ci, il ne faut pas moins que les gros
escadrons vêtus de fer du général d'Hautpoul. Cet officier, qui se
distinguait par une habileté consommée dans l'art de manier une
cavalerie nombreuse, se présente avec vingt-quatre escadrons de
cuirassiers, que suit toute la masse des dragons. Ces cuirassiers,
rangés sur plusieurs lignes, s'ébranlent, et se précipitent sur les
baïonnettes russes. Les premières lignes, arrêtées par le feu, ne
pénètrent pas, et se repliant à droite et à gauche, viennent se
reformer derrière celles qui les suivent, pour charger de nouveau.
Enfin l'une d'elles, lancée avec plus de violence, renverse sur un
point l'infanterie ennemie, et y ouvre une brèche, à travers laquelle
cuirassiers et dragons pénètrent à l'envi les uns des autres. Comme
un fleuve qui a commencé à percer une digue, l'emporte bientôt tout
entière, la masse de nos escadrons ayant une fois entamé
l'infanterie des Russes, achève en peu d'instants de renverser leur
première ligne. Nos cavaliers se dispersent alors
pour sabrer. Une affreuse mêlée s'engage entre
eux et les fantassins russes. Ils vont, viennent, et
frappent de tous côtés ces fantassins opiniâtres.
Tandis que la première ligne d'infanterie est ainsi
culbutée, et hachée, la seconde se replie à un bois,
qui se voyait au fond du champ de bataille. Il restait là une dernière
réserve d'artillerie. Les Russes la mettent en batterie, et tirent
confusément sur leurs soldats et sur les nôtres, s'inquiétant peu de
Le combat étant
rétabli au
centre,
Napoléon attend
le résultat de
l'action engagée
sur les ailes.
mitrailler amis et ennemis, pourvu qu'ils se débarrassent de nos
redoutables cavaliers. Le général d'Hautpoul est frappé à mort par
un biscaïen. Pendant que notre cavalerie est ainsi aux prises avec la
seconde ligne de l'infanterie russe, quelques parties de la première
se relèvent çà et là pour tirer encore. À cette vue, les grenadiers à
cheval de la garde, conduits par le général Lepic, l'un des héros de
l'armée, s'élancent à leur tour, pour seconder les efforts de Murat. Ils
partent au galop, chargent les groupes d'infanterie qu'ils aperçoivent
debout, et, parcourant le terrain en tous sens, complètent la
destruction du centre de l'armée russe, dont les débris achèvent de
s'enfuir vers les bouquets de bois qui lui ont servi d'asile.
Durant cette scène de confusion, un tronçon détaché de cette
vaste ligne d'infanterie, s'était avancé jusqu'au cimetière même.
Trois ou quatre mille grenadiers russes, marchant droit devant eux,
avec ce courage aveugle d'une troupe plus brave qu'intelligente,
viennent se heurter contre l'église d'Eylau, et menacent le cimetière
occupé par l'état-major impérial. La garde à pied, immobile jusque-
là, avait essuyé la canonnade sans rendre un coup de fusil. C'est
avec joie qu'elle voit naître une occasion de combattre. Un bataillon
est commandé: deux se disputent l'honneur de marcher. Le premier
en ordre, conduit par le général Dorsenne, obtient l'avantage de se
mesurer avec les grenadiers russes, les aborde sans tirer un coup de
fusil, les joint à la baïonnette, les refoule les uns sur les autres,
tandis que Murat, apercevant cet engagement, lance sur eux deux
régiments de chasseurs sous le général Bruyère. Les malheureux
grenadiers russes, serrés entre les baïonnettes des grenadiers de la
garde, et les sabres de nos chasseurs, sont presque tous pris ou
tués, sous les yeux de Napoléon, et à quelques pas de lui.
Cette action de cavalerie, la plus extraordinaire
peut-être de nos grandes guerres, avait eu pour
résultat de culbuter le centre des Russes, et de le
repousser à une assez grande distance. Il aurait
fallu avoir sous la main une réserve d'infanterie,
afin d'achever la défaite d'une troupe qui, après
Vaillante
conduite de la
division Saint-
Hilaire et du
corps du
maréchal
Davout.
s'être couchée à terre, se relevait pour faire feu. Mais Napoléon
n'osait pas disposer du corps du maréchal Soult, réduit à une moitié
de son effectif, et nécessaire à la garde d'Eylau. Le corps d'Augereau
était presque détruit. Les six bataillons de la garde à pied restaient
seuls comme réserve, et au milieu des chances si diverses de cette
journée, fort éloignée encore de sa fin, c'était une ressource qu'il
fallait conserver précieusement. À gauche le maréchal Ney, marchant
depuis plusieurs jours côte à côte avec les Prussiens, pouvait les
devancer, ou en être devancé sur le champ de bataille, et huit ou dix
mille hommes, survenant à l'improviste, devaient apporter à l'une
des deux armées un renfort peut-être décisif. À droite, le maréchal
Davout se trouvait engagé avec la gauche des Russes dans un
combat acharné, dont le résultat était encore inconnu.
Napoléon, immobile dans ce cimetière où l'on avait accumulé les
cadavres d'un grand nombre de ses officiers, plus grave que de
coutume, mais commandant à son visage comme à son âme, ayant
sa garde derrière lui, et devant lui les chasseurs, les dragons, les
cuirassiers reformés, prêts à se dévouer de nouveau, Napoléon
attendait l'événement, avant de prendre une détermination
définitive. Jamais, ni lui, ni ses soldats n'avaient assisté à une action
aussi disputée.
Mais le temps des défaites n'était pas venu, et la
fortune, rigoureuse un moment pour cet homme
extraordinaire, le traitait encore en favori. À cette
heure, le général Saint-Hilaire, avec sa division, le
maréchal Davout avec son corps, justifiaient la
confiance que Napoléon avait mise en eux. La
division Saint-Hilaire, accueillie comme le corps
d'Augereau, et au même instant, par un horrible feu de mitraille et
de mousqueterie, avait eu cruellement à souffrir. Aveuglée aussi par
la neige, elle n'avait point aperçu une masse de cavalerie accourant
sur elle au galop, et un bataillon du 10e
léger, assailli avant d'avoir
pu se former, avait été renversé sous les pieds des chevaux. La
division Morand, extrême gauche de Davout, découverte par
Subite
apparition du
général prussien
Lestocq sur le
champ de
bataille.
Friant et Gudin
arrêtent les
Prussiens.
l'accident arrivé au bataillon du 10e
léger, s'était vue ramenée en
arrière, pendant deux ou trois cents pas. Mais bientôt Davout et
Morand l'avaient reportée en avant. Dans cet intervalle, le général
Friant soutenait à Klein-Sausgarten une lutte héroïque, et, secondé
par la division Gudin, il occupait définitivement cette position
avancée sur le flanc des Russes. Il venait même de pousser des
détachements jusqu'au village de Kuschitten, situé sur leurs
derrières. C'était le moment où, la journée étant presque achevée,
et l'armée russe presque à moitié détruite, la bataille semblait devoir
se terminer en notre faveur.
Mais l'événement que redoutait Napoléon s'était
réalisé. Le général Lestocq, poursuivi à outrance
par le maréchal Ney, paraissait sur ce champ de
carnage, avec 7 ou 8 mille Prussiens, jaloux de se
venger du dédain des Russes. Le général Lestocq,
devançant à peine d'une heure ou deux le corps du
maréchal Ney, avait tout juste le temps de porter un coup, avant
d'être atteint lui-même. Il débouche sur le champ de bataille à
Schmoditten, passe derrière la double ligne des Russes, maintenant
brisée par le feu de nos artilleurs, par le sabre de nos cavaliers, et se
présente à Kuschitten, en face de la division Friant, qui, dépassant
Klein-Sausgarten, avait déjà refoulé la gauche de l'ennemi sur son
centre. Le village de Kuschitten était occupé par quatre compagnies
du 108e
, et par le 51e
, qui avait été détaché de la division Morand,
pour aller au soutien de la division Friant. Les
Prussiens, ralliant les Russes autour d'eux, fondent
impétueusement sur le 51e
et sur les quatre
compagnies du 108e
ne parviennent pas à les
rompre, mais les ramènent fort en arrière de Kuschitten. Après ce
premier avantage, les Prussiens se portent au delà de Kuschitten afin
de ressaisir les positions du matin. Ils marchent déployés sur deux
lignes. Les réserves russes ralliées, forment sur leurs ailes deux
colonnes serrées. Une nombreuse artillerie les précède. Ils
s'avancent ainsi en traversant les derrières du champ de bataille,
Horrible état de
l'armée russe à
la fin du jour.
Le général
Benningsen
délibère s'il doit
tenter un
dernier effort.
La subite arrivée
du maréchal
pour regagner le terrain perdu, et ramener le maréchal Davout sur
Klein-Sausgarten, et de Klein-Sausgarten sur Serpallen. Mais les
généraux Friant et Gudin, ayant le maréchal Davout à leur tête,
accourent. La division Friant tout entière, les 12e
, 21e
, 25e
régiments
appartenant à la division Gudin se placent en avant, couverts par
toute l'artillerie du troisième corps. Vainement les Russes et les
Prussiens veulent-ils renverser cet obstacle formidable, ils n'y
peuvent réussir. Les Français, appuyés à des bois, à des marécages,
à des monticules, ici déployés en ligne, là dispersés en tirailleurs,
opposent une opiniâtreté invincible à ce dernier effort des coalisés.
Le maréchal Davout, parcourant les rangs jusqu'à la fin du jour,
contient ses soldats en leur disant: Les lâches iront mourir en
Sibérie; les braves mourront ici en gens d'honneur.—L'attaque des
Prussiens et des Russes ralliés s'arrête, le terrain perdu sur leur flanc
gauche n'est pas reconquis. Le corps du maréchal Davout reste
ferme dans cette position de Klein-Sausgarten, d'où il menace les
derrières de l'ennemi.
Les deux armées étaient épuisées. Ce jour si sombre devenait à
chaque instant plus sombre encore, et allait se terminer en une
affreuse nuit. Le carnage était horrible. Près de 30
mille Russes, atteints par les projectiles ou le sabre
des Français, jonchaient la terre, les uns morts, les
autres blessés plus ou moins gravement. Beaucoup
de leurs soldats commençaient à s'en aller à la débandade[22]. Le
général Benningsen, entouré de ses lieutenants,
délibérait s'il fallait reprendre l'offensive, et tenter
un nouvel effort. Mais, d'une armée de 80 mille
hommes, il ne lui en restait pas 40 mille en état de
combattre, les Prussiens compris. S'il avait
succombé dans cet engagement désespéré, il
n'aurait pas eu de quoi couvrir la retraite. Néanmoins il hésitait
encore, lorsqu'on vint lui annoncer un dernier et grave incident. Le
maréchal Ney, qui avait suivi de près les Prussiens,
arrivant le soir sur notre gauche comme le
Ney décide la
retraite des
Russes.
Position
occupée par
l'armée
française le soir
de la bataille
d'Eylau.
maréchal Davout était arrivé le matin sur notre
droite, débouchait enfin vers Althof.
Ainsi les combinaisons de Napoléon, retardées
par le temps, n'en avaient pas moins amené sur les deux flancs de
l'armée russe les forces qui devaient décider la victoire. L'ordre de
retraite ne pouvait plus dès lors être différé, car le maréchal Davout,
s'étant maintenu à Klein-Sausgarten, n'avait pas beaucoup à faire
pour rencontrer le maréchal Ney, qui s'était avancé jusqu'à
Schmoditten, et la jonction de ces deux maréchaux aurait exposé les
Russes à être enveloppés. L'ordre de se retirer fut donné à l'instant
même par le général Benningsen. Toutefois pour assurer la retraite il
voulut contenir le maréchal Ney, et essayer de lui enlever le village
de Schmoditten. Les Russes marchèrent sur ce village, à la faveur de
la nuit, et en grand silence, pour surprendre les troupes du maréchal
Ney, arrivées tard sur ce champ de bataille où l'on avait de la peine à
se reconnaître. Mais celles-ci étaient sur leurs gardes. Le général
Marchand, avec le 6e
léger et le 39e
de ligne, laissant approcher les
Russes, puis les accueillant par un feu à bout portant, les arrêta net.
Il courut ensuite sur eux à la baïonnette, et les fit renoncer à toute
attaque sérieuse. Dès ce moment ils se mirent définitivement en
retraite.
Napoléon discernant à la direction des feux du maréchal Davout et
du maréchal Ney, le véritable état des choses, se savait maître du
champ de bataille, mais il n'était pas assuré cependant de ne pas
avoir une seconde bataille à livrer, la nuit ou le lendemain. Il
occupait cette plaine légèrement relevée, qui
s'étendait au delà d'Eylau, ayant devant lui et au
centre sa cavalerie et sa garde, à gauche en avant
d'Eylau les deux divisions Legrand et Leval du
corps du maréchal Soult, à droite la division Saint-
Hilaire qui se liait avec le corps du maréchal
Davout porté au delà de Klein-Sausgarten, l'armée française
décrivant ainsi une ligne oblique sur le terrain que les Russes avaient
possédé le matin. Fort au delà, sur la gauche, le maréchal Ney isolé,
Disposition
morale de
l'armée.
se trouvait sur les derrières de la position que l'ennemi abandonnait
en toute hâte.
Napoléon, certain d'être victorieux, mais triste au fond du cœur,
était demeuré au milieu de ses troupes, ordonnant qu'on allumât des
feux, et qu'on ne quittât pas les rangs, même pour aller chercher
des vivres. On distribuait aux soldats un peu de pain et d'eau-de-vie,
et, quoiqu'il n'y en eût pas assez pour tous, on ne les entendait pas
se plaindre. Moins joyeux qu'à Austerlitz ou à Iéna,
ils étaient pleins de confiance, fiers d'eux-mêmes,
prêts à recommencer cette lutte terrible, si les
Russes en avaient le courage et la force.
Quiconque, en ce moment, leur eût donné le pain et l'eau-de-vie
dont ils manquaient, les eût retrouvés aussi gais que de coutume.
Deux artilleurs du corps du maréchal Davout ayant été absents de
leur compagnie pendant cette journée, et étant arrivés trop tard
pour assister à la bataille, leurs camarades s'assemblèrent le soir au
bivouac, les jugèrent, et n'ayant pas goûté leurs raisons, leur
infligèrent sur ce terrain glacé et sanglant, le châtiment burlesque
que les soldats appellent la savate[23].
Il n'y avait en grande abondance que des munitions. Le service de
l'artillerie, exécuté avec une activité rare, avait déjà remplacé les
munitions consommées. Le service des ambulances se faisait avec
non moins de zèle. On avait ramassé un grand nombre de blessés,
et on administrait aux autres quelques secours sur place, en
attendant qu'on pût les transporter à leur tour. Napoléon, accablé de
fatigue, debout cependant, présidait aux soins donnés à ses soldats.
Sur les derrières de l'armée tout n'offrait pas une contenance
aussi ferme. Beaucoup de traînards qui manquaient à l'effectif le
matin, par suite de la rapidité des marches, avaient entendu le
retentissement de cette épouvantable bataille, avaient aperçu
quelques houras de Cosaques, et s'étaient repliés, répandant sur les
routes des nouvelles fâcheuses. Les braves accouraient se ranger
Journée qui suit
la bataille
d'Eylau.
Pertes des
Russes et des
Français à la
bataille d'Eylau.
auprès de leurs camarades, les autres s'en allaient dans les diverses
directions qu'avait parcourues l'armée.
Le lendemain le jour commençant à luire, on
découvrit cet affreux champ de bataille, et
Napoléon lui-même fut ému, au point de le laisser
apercevoir dans le bulletin qu'il publia. Sur cette
plaine glacée, des milliers de morts et de mourants cruellement
mutilés, des milliers de chevaux abattus, une innombrable quantité
de canons démontés, de voitures brisées, de projectiles épars, des
hameaux en flammes, tout cela se détachant sur un fond de
neige[24], présentait un spectacle saisissant et terrible. «Ce
spectacle, s'écriait Napoléon, est fait pour inspirer aux princes
l'amour de la paix, et l'horreur de la guerre!»—Singulière réflexion
dans sa bouche, et sincère au moment où il la laissait échapper.
Une particularité frappa tous les yeux. Soit penchant à revenir aux
choses du passé, soit aussi économie, on avait voulu rendre l'habit
blanc aux troupes. On en avait fait l'essai sur quelques régiments,
mais la vue du sang sur les habits blancs décida la question.
Napoléon rempli de dégoût et d'horreur déclara qu'il ne voulait que
des habits bleus, quoi qu'il pût en coûter.
L'aspect de ce champ de bataille abandonné par
l'ennemi rendit à l'armée le sentiment de sa
victoire. Les Russes s'étaient retirés, laissant sur le
terrain 7 mille morts, et plus de 5 mille blessés,
que le vainqueur généreux se hâta de relever
après les siens. Outre les 12 mille morts ou mourants abandonnés à
Eylau, ils emmenaient avec eux environ 15 mille blessés, plus ou
moins gravement atteints. Ils avaient eu par conséquent 26 ou 27
mille hommes hors de combat. Nous tenions 3 à 4 mille prisonniers,
24 pièces de canon, 16 drapeaux. Leur perte totale était donc de 30
mille hommes. Les Français avaient eu environ 10 mille hommes
hors de combat, dont 3 mille morts et 7 mille blessés[25], perte bien
inférieure à celle de l'armée russe, et qui s'explique par la position
Napoléon
pousse les
Russes jusqu'à
Kœnigsberg.
de nos troupes rangées en ordre mince, par l'habileté de nos
artilleurs et de nos soldats. Ainsi dans cette journée fatale, près de
40 mille hommes des deux côtés avaient été atteints par le feu et le
fer. C'est la population d'une grande ville détruite en un jour! Triste
conséquence des passions des peuples! passions terribles, qu'il faut
s'appliquer à bien diriger, mais non pas chercher à éteindre!
Napoléon, dès le 9 au matin, avait porté ses
dragons et ses cuirassiers en avant, afin de courir
après les Russes, de les jeter sur Kœnigsberg, et
de les refouler pour tout l'hiver au delà de la
Prégel. Le maréchal Ney, qui n'avait pas eu
beaucoup à faire dans la journée d'Eylau, fut chargé de soutenir
Murat. Les maréchaux Davout et Soult devaient suivre à peu de
distance. Napoléon resta de sa personne à Eylau pour panser les
plaies de sa brave armée, pour la nourrir, et mettre tout en ordre sur
ses derrières. Cela importait plus qu'une poursuite, que ses
lieutenants étaient très-capables d'exécuter eux-mêmes.
En marchant on acquit plus complétement encore la conviction du
désastre essuyé par les Russes. À mesure qu'on avançait, on trouvait
les villages et les bourgs de la Prusse orientale remplis de blessés;
on apprenait le désordre, la confusion, le triste état enfin de l'armée
fugitive. Néanmoins les Russes, en comparant cette bataille à celle
d'Austerlitz, étaient fiers de la différence. Ils convenaient de leur
défaite, mais ils se dédommageaient de cet aveu, en ajoutant que la
victoire avait coûté cher aux Français.
On ne s'arrêta que sur les bords de la Frisching, petite rivière qui
coule de la ligne des lacs à la mer, et Murat poussa ses escadrons
jusqu'à Kœnigsberg. Les Russes réfugiés en toute hâte, les uns au
delà de la Prégel, les autres à Kœnigsberg même, faisaient mine de
vouloir s'y défendre, et avaient braqué sur les murs une nombreuse
artillerie. Les habitants épouvantés se demandaient s'ils allaient
éprouver le sort de Lubeck. Heureusement pour eux Napoléon
voulait mettre un terme à ses opérations offensives. Il avait envoyé
les cavaliers de Murat jusqu'aux portes de Kœnigsberg, mais il ne se
proposait pas d'y conduire son armée elle-même. Il n'aurait pas fallu
moins que cette armée tout entière, pour tenter avec espoir de
succès une attaque de vive force, sur une grande ville, pourvue de
quelques ouvrages, et défendue par tout ce qui restait de troupes
russes et prussiennes. Une attaque même heureuse sur cette riche
cité, ne valait pas les chances qu'on aurait courues, si la tentative
eût échoué. Napoléon ayant poussé ses corps jusqu'aux bords de la
Frisching, tint à les y laisser quelques jours, pour bien constater sa
victoire, et puis songea à se retirer pour reprendre ses
cantonnements. Sans doute il n'avait pas obtenu l'immense résultat
dont il s'était d'abord flatté, et qui ne lui aurait certainement point
échappé, si une dépêche interceptée n'avait révélé ses desseins aux
Russes; mais il les avait menés battant pendant cinquante lieues,
leur avait détruit neuf mille hommes dans une suite de combats
d'arrière-garde, et les trouvant à Eylau formés en une masse
compacte, couverts d'artillerie, résolus jusqu'au désespoir, forts avec
les Prussiens de 80 mille soldats, sur une plaine où aucune
manœuvre n'était possible, il les avait attaqués avec 54 mille, les
avait détruits à coups de canon, et avait paré à tous les accidents de
la journée avec un imperturbable sang-froid, pendant que ses
lieutenants s'efforçaient de le rejoindre. Les Russes ce jour-là
avaient eu tous leurs avantages, la solidité, l'immobilité au feu; lui
n'avait pas eu tous les siens, sur un terrain où il était impossible de
manœuvrer; mais il avait opposé à leur ténacité un invincible
courage, une force morale au-dessus des horreurs du plus affreux
carnage. L'âme de ses soldats s'était montrée dans cette journée
aussi forte que la sienne! Assurément il pouvait être fier de cette
épreuve. D'ailleurs pour 12 ou 13 mille hommes qu'il avait perdus
pendant ces huit jours, il en avait détruit 36 mille à l'ennemi. Mais il
devait sentir en ce moment ce que c'était que la puissance du
climat, du sol, des distances, car, possédant plus de 300 mille
hommes en Allemagne, il n'avait pas pu en réunir plus de 54 mille
sur le lieu de l'action décisive. Il devait après une telle victoire faire
de graves réflexions, compter davantage avec les éléments et la
fortune, et moins entreprendre à l'avenir sur l'invincible nature des
Napoléon quitte
les environs de
Kœnigsberg, et
les bords de la
Prégel, pour
reprendre ses
cantonnements
de la Vistule.
choses. Ces réflexions il les fit, et elles lui inspirèrent, comme on va
en juger bientôt, la conduite la mieux calculée, la plus
admirablement prévoyante. Plût au ciel qu'elles fussent restées pour
toujours gravées dans sa mémoire!
Quoique victorieux et garanti pour plusieurs mois de toute
tentative contre ses cantonnements, il avait cependant une chose à
craindre, c'étaient les récits mensongers des Russes, l'effet de ces
récits sur l'Autriche, sur la France, sur l'Italie, sur l'Espagne, sur
l'Europe en un mot, qui, voyant depuis trois mois sa marche deux
fois arrêtée, tantôt par les boues, tantôt par les frimas, serait portée
à le croire moins irrésistible, moins fatalement heureux, tiendrait
pour douteuse la victoire pourtant la plus incontestable, la plus
cruellement efficace, et pourrait enfin être tentée de méconnaître sa
fortune.
Il résolut de montrer ici le caractère qu'il avait déployé pendant la
journée même d'Eylau, et, certain de sa force, d'attendre que
l'Europe, mieux éclairée, la sentît comme lui. Après
avoir passé quelques jours sur la Frisching,
l'ennemi ne sortant pas de ses lignes, il prit le parti
de rétrograder pour rentrer dans ses
cantonnements. La température était toujours
froide, mais sans descendre à plus de 2 ou 3
degrés au-dessous de la glace. Il en profita pour
évacuer ses blessés en traîneau. Plus de six mille
subirent, sans en souffrir sensiblement, ce singulier voyage de
quarante à cinquante lieues, jusqu'à la Vistule. Un soin extrême
apporté à les rechercher tous dans les villages environnants, permit
d'en constater le véritable nombre. Il était conforme à celui que
nous avons mentionné plus haut. Quand tout fut évacué, blessés,
malades, prisonniers, artillerie prise à l'ennemi, Napoléon
commença, le 17 février, son mouvement rétrograde, le maréchal
Ney avec le sixième corps, Murat avec la cavalerie faisant l'arrière-
garde, les autres corps conservant leur position accoutumée dans
l'ordre de marche, le maréchal Davout à droite, le maréchal Soult au
Motifs qui
décident
Napoléon à
changer la
position de ses
cantonnements.
centre, le maréchal Augereau à gauche, enfin le maréchal
Bernadotte, qui avait rejoint, formant l'extrême gauche, le long du
Frische-Haff.
Napoléon ayant remonté l'Alle jusque près des lacs d'où elle sort,
et d'où sort aussi la Passarge, changea de direction, et, au lieu de
prendre la route de Varsovie, prit celle de Thorn, Marienbourg et
Elbing, voulant désormais s'appuyer à la basse Vistule. Les derniers
événements avaient modifié ses idées quant au choix de sa base
d'opération. Voici les motifs de ce changement.
La position entre les branches de l'Ukra, de la
Narew, du Bug, qu'il avait d'abord adoptée, était
une conséquence de l'occupation de Varsovie. Elle
avait l'avantage de couvrir cette capitale, et, si
l'ennemi se portait le long du littoral, de permettre
plus aisément de le déborder, de le tourner, de
l'acculer à la mer, ce que Napoléon venait d'essayer, et ce qu'il aurait
certainement exécuté, sans l'enlèvement de ses dépêches. Mais,
cette manœuvre une fois dévoilée, il n'était pas probable que les
Russes avertis s'exposassent à un danger qu'ils venaient d'éviter par
une sorte de miracle. La position choisie en avant de Varsovie ne
présentait donc plus le même avantage, et elle offrait un
inconvénient grave, celui d'obliger l'armée à s'étendre
démesurément, pour couvrir à la fois Varsovie et le siége de Dantzig,
siége qui devenait l'opération urgente, à laquelle il fallait consacrer
les loisirs de l'hiver. En se plaçant, en effet, à Varsovie, on était
obligé de laisser le corps de Bernadotte à grande distance, avec peu
de chances de le rallier au gros de l'armée; et si on marchait en
avant, on était forcé en outre de laisser le cinquième corps, celui de
Lannes, à la garde de Varsovie. On agissait par conséquent avec
deux corps de moins. L'éloignement du corps de Bernadotte serait
devenu à l'avenir d'autant plus regrettable, qu'on allait être contraint
de lui adjoindre de nouvelles forces, pour seconder et couvrir le
siége de Dantzig.
Nouvelle
position prise
par Napoléon.
Napoléon prit donc la résolution de s'éloigner de
Varsovie, de confier la garde de cette capitale au
cinquième corps, aux Polonais, aux Bavarois (la
soumission des places de la Silésie rendait ces
derniers disponibles), et de s'établir avec la plus grande partie de ses
troupes, en avant de la basse Vistule, derrière la Passarge, ayant
Thorn à sa droite, Elbing à sa gauche, Dantzig sur ses derrières, son
centre à Osterode, ses avant-postes entre la Passarge et l'Alle. (Voir
les cartes nos
37 et 38.) Dans cette position il couvrait lui-même le
siége de Dantzig, sans avoir besoin de détacher pour cet objet
aucune partie de ses forces. Si, en effet les Russes, voulant secourir
Dantzig, venaient chercher une bataille, il pouvait leur opposer tous
ses corps réunis, celui de Bernadotte compris, et même une partie
des troupes de Lefebvre, que rien ne l'empêchait d'attirer à lui dans
un cas pressant, ainsi qu'il l'avait fait en 1796, lorsqu'il leva le siége
de Mantoue pour courir aux Autrichiens. Il ne lui manquait un jour
de bataille que le cinquième corps, qui, de quelque manière qu'on
opérât, était indispensable sur la Narew, afin de défendre Varsovie.
Cette nouvelle position, d'ailleurs, donnait lieu à des combinaisons
savantes, fécondes en grands résultats, ignorées de l'ennemi, tandis
que celles qui auraient eu Varsovie pour base, lui étaient toutes
connues. Cantonné derrière la Passarge, Napoléon se trouvait à
quinze lieues seulement de Kœnigsberg. Supposez que les Russes,
attirés par l'isolement apparent dans lequel on laissait Varsovie,
s'avançassent sur cette capitale, on courait derrière eux à
Kœnigsberg, on s'emparait de cette ville, et puis se rabattant par un
mouvement à droite sur leurs derrières, on les jetait sur la Narew et
la Vistule, dans les marécages de l'intérieur, avec autant de certitude
de les détruire, que dans le cas du mouvement vers la mer. Si, au
contraire, ils attaquaient de front les cantonnements sur la Passarge,
on avait, comme nous venons de le dire, outre la force naturelle de
ces cantonnements, la masse entière de l'armée à leur opposer. La
position était donc excellente pour le siége de Dantzig, excellente
pour les opérations futures, car elle faisait naître des combinaisons
nouvelles, dont le secret n'était pas dévoilé.
Caractère de la
guerre que
Napoléon faisait
en ce moment.
Répartition de
l'armée entre
les divers
cantonnements.
C'est assurément un spectacle imposant et
instructif, que celui de ce général impétueux, qui
n'était propre, au dire de ses détracteurs, qu'à la
guerre offensive, porté d'un seul bond du Rhin à la
Vistule, s'arrêtant tout à coup devant les difficultés
des lieux et des saisons, s'enfermant dans un espace étroit, y faisant
la guerre froide, lente, méthodique, y disputant pied à pied de
petites rivières, après avoir franchi les plus gros fleuves sans
s'arrêter, se réduisant enfin à couvrir un siége, et placé à une aussi
vaste distance de son empire, en présence de l'Europe qu'étonnait
cette nouvelle manière de procéder, que le doute commençait à
gagner, conservant une fermeté inébranlable, n'étant pas même
séduit par le désir de frapper un coup d'éclat, et sachant ajourner ce
coup au moment où la nature des choses le rendrait sûr et possible:
c'est, disons-nous, un spectacle digne d'intérêt, de surprise,
d'admiration, c'est une précieuse occasion d'étude et de réflexions,
pour quiconque est sensible aux combinaisons des grands hommes,
et se plaît à les méditer!
Napoléon vint donc se placer entre la Passarge
et la basse Vistule (voir la carte no
38), le corps du
maréchal Bernadotte à gauche sur la Passarge,
entre Braunsberg et Spanden; le corps du
maréchal Soult au centre, entre Liebstadt et
Mohrungen; le corps du maréchal Davout à droite, entre Allenstein
et Hohenstein, au point où l'Alle et la Passarge sont le plus
rapprochées; le corps du maréchal Ney en avant-garde, entre la
Passarge et l'Alle, à Guttstadt; le quartier général et la garde à
Osterode, dans une position centrale, où Napoléon pouvait réunir
toutes ses forces en quelques heures. Il attira le général Oudinot à
Osterode, avec les grenadiers et voltigeurs, formant une réserve
d'infanterie de 6 à 7 mille hommes. Il répandit la cavalerie sur ses
derrières, entre Osterode et la Vistule, depuis Thorn jusqu'à Elbing,
pays qui abondait en toute sorte de fourrages.
Dissolution du
corps
d'Augereau.
Dans l'énumération des corps cantonnés derrière
la Passarge, nous n'avons pas désigné celui
d'Augereau. Napoléon en avait prononcé la
dissolution. Augereau venait de quitter l'armée,
déconcerté de ce qui lui était arrivé dans la journée d'Eylau,
imputant mal à propos son échec à la jalousie de ses camarades,
qui, selon lui, n'avaient pas voulu le soutenir, se disant fatigué,
malade, usé! L'Empereur le renvoya en France, avec des
témoignages de satisfaction, qui étaient de nature à le consoler. Mais
craignant que dans le septième corps, à moitié détruit, il ne restât
quelque chose du découragement manifesté par le chef, il en
prononça la dissolution, après y avoir prodigué les récompenses. Il
en répartit les régiments entre les maréchaux Davout, Soult et Ney.
Des 12 mille hommes dont se composait le septième corps, il y en
avait eu 7 mille présents à Eylau, et sur ces 7 mille, deux tiers mis
hors de combat. Les survivants, joints à ceux qui étaient demeurés
en arrière, devaient fournir 7 à 8 mille hommes de renfort aux divers
corps de l'armée.
Napoléon plaça le cinquième corps sur l'Omulew, à quelque
distance de Varsovie. Lannes étant toujours malade, il avait mandé,
avec regret d'en priver l'Italie, mais avec une grande satisfaction de
le posséder en Pologne, le premier de ses généraux, Masséna, qui
n'avait pas pu s'entendre avec Joseph à Naples. Il lui donna le
commandement du cinquième corps. Les siéges de la Silésie
avançant, grâce à l'énergie et à la fertilité d'esprit du général
Vandamme, Schweidnitz ayant été pris, Neisse et Glatz restant seuls
à prendre, Napoléon en profita pour amener sur la Vistule la division
bavaroise Deroy, forte de 6 à 7 mille hommes d'assez bonnes
troupes, laquelle fut cantonnée à Pultusk, entre la position du
cinquième corps sur l'Omulew et Varsovie. Les bataillons polonais de
Kalisch et de Posen avaient été envoyés à Dantzig. Napoléon
rassembla ceux de Varsovie, organisés par le prince Poniatowski, à
Neidenbourg, de manière à maintenir la communication entre le
quartier général et les troupes campées sur l'Omulew. Ils étaient là
sous les ordres du général Zayonscheck. Il demanda en outre que
Distribution
générale des
forces de
l'armée.
l'on organisât un corps de cavalerie de mille à deux mille Polonais,
afin de courir après les Cosaques. Ces diverses troupes polonaises
destinées à lier la position de la grande armée sur la Passarge, avec
celle de Masséna sur la Narew, n'étaient pas capables assurément
d'arrêter une armée russe qui aurait pris l'offensive, mais elles
suffisaient pour empêcher les Cosaques de pénétrer entre Osterode
et Varsovie, et pour exercer dans ce vaste espace une active
surveillance. Concentré ainsi derrière la Passarge, et en avant de la
basse Vistule, couvrant dans une position inattaquable le siége de
Dantzig, qui allait enfin commencer, pouvant par une menace sur
Kœnigsberg, arrêter tout mouvement offensif sur Varsovie, Napoléon
était dans une situation à ne rien craindre. Rejoint par les
retardataires laissés en arrière, et par le corps de Bernadotte,
renforcé par les grenadiers et voltigeurs d'Oudinot, il pouvait en
quarante-huit heures réunir 80 mille hommes sur l'un des points de
la Passarge. Cette situation était fort imposante, surtout si on la
compare à celle des Russes, qui n'auraient pas pu mettre 50 mille
hommes en ligne. Mais c'est une remarque digne d'être répétée,
quoique déjà faite par nous, qu'une armée de plus de 300 mille
hommes, répandue depuis le Rhin jusqu'à la Vistule, administrée
avec une habileté qu'aucun capitaine n'a jamais égalée, fût dans
l'impossibilité de fournir plus de 80 mille combattant sur le même
champ de bataille. Il y avait 80 à 90 mille hommes
capables d'agir offensivement entre la Vistule et la
Passarge, 24 mille sur la Narew, d'Ostrolenka à
Varsovie, en y comprenant les Polonais et les
Bavarois, 22 mille sous Lefebvre devant Dantzig et
Colberg, 28 mille sous Mortier, en Italiens, Hollandais et Français,
répandus depuis Brême et Hambourg jusqu'à Stralsund et Stettin, 15
mille en Silésie tant Bavarois que Wurtembergeois, 30 mille dans les
places, depuis Posen jusqu'à Erfurt et Mayence, 7 ou 8 mille
employés aux parcs, 15 mille blessés de toutes les époques, 60 et
quelques mille malades et maraudeurs, enfin 30 à 40 mille recrues
en marche, ce qui faisait à peu près 330 mille hommes à la grande
armée, dont 270 mille Français, et environ 60 mille auxiliaires,
Italiens, Hollandais, Allemands et Polonais.
Mars 1807.
Grand nombre
de maraudeurs
à la suite de
l'armée.
Ce qui paraîtra singulier, c'est ce
nombre énorme de 60 mille malades
ou maraudeurs, nombre, il est vrai,
très-approximatif[26], difficile à fixer, mais digne de
l'attention des hommes d'État, qui étudient les
secrets ressorts de la puissance des nations. Il n'y avait pas dans ces
soixante mille absents qualifiés de malades, la moitié qui fût aux
hôpitaux. Les autres étaient en maraude. Nous avons déjà dit que
beaucoup de soldats manquaient dans les rangs à la bataille d'Eylau,
par suite de la rapidité des marches, et que les impressions
produites par cette terrible bataille se répandant au loin, les lâches
et la valetaille avaient fui à toutes jambes, en criant que les Français
étaient battus. Depuis il s'était joint à eux beaucoup d'hommes, qui,
sous prétexte de maladies ou de blessures légères, demandaient à
se rendre aux hôpitaux, mais se gardaient bien d'y aller, parce qu'on
y était retenu, surveillé, soigné même jusqu'à l'ennui. Ils avaient
passé la Vistule, vivaient dans les villages, à droite et à gauche de la
grande route, de manière à échapper à la surveillance générale qui
contenait dans l'ordre toutes les parties de l'armée. Ils vivaient ainsi
aux dépens du pays, qu'ils ne ménageaient pas, les uns vrais lâches,
dont une armée, même héroïque, a toujours une certaine quantité
dans ses rangs, les autres fort braves au contraire, mais pillards par
nature, aimant la liberté et le désordre, et prêts à revenir au corps
dès qu'ils apprenaient la reprise des opérations. Napoléon, averti de
cet état de choses, par la différence entre le nombre d'hommes
réputés aux hôpitaux, et le nombre de ceux que les dépenses de M.
Daru prouvaient y être véritablement, porta sur cet abus une
sérieuse attention. Il employa pour le réprimer la police des autorités
polonaises, puis la gendarmerie d'élite attachée à sa garde, comme
la seule troupe qui fût assez respectée pour se faire obéir. Jamais
néanmoins on ne put complétement détruire sur la ligne d'opération
cette lèpre attachée aux grandes armées. Et pourtant l'armée dont il
s'agissait ici, était celle du camp de Boulogne, la plus solide, la plus
disciplinée, la plus brave qui fut jamais! Dans la campagne
d'Austerlitz, les maraudeurs s'étaient à peine fait voir. Mais la rapidité
des mouvements, la distance, le climat, la saison, le carnage enfin,
Quelques
démonstrations
des Russes
contre nos
cantonnements.
relâchant les liens de la discipline, cette vermine, triste effet de la
misère dans un grand corps, commençait à pulluler. Napoléon y
pourvut cette fois par une immense prévoyance, et par les victoires
qu'il remporta bientôt. Mais des défaites peuvent en quelques jours
faire dégénérer un pareil mal en dissolution des armées. Ainsi dans
les succès même de cette belle et terrible campagne de 1807,
apparaissaient plusieurs des symptômes d'une campagne à jamais
fatale et mémorable, celle de 1812.
Le retour dans les cantonnements fut signalé par
quelques mouvements de la part des Russes. Leurs
rangs étaient singulièrement éclaircis. Il ne leur
restait pas cinquante mille hommes capables
d'agir. Cependant le général Benningsen, tout
enorgueilli de n'avoir pas perdu à Eylau jusqu'au
dernier homme, et, suivant son usage, se disant vainqueur, voulut
donner à ses vanteries une apparence de vérité. Il quitta donc
Kœnigsberg, dès qu'il apprit que l'armée française se retirait sur la
Passarge. Il vint montrer de fortes colonnes le long de cette rivière,
surtout dans son cours supérieur, vers Guttstadt, en face de la
position du maréchal Ney. Il s'adressait mal, car cet intrépide
maréchal, privé de l'honneur de combattre à Eylau, et impatient de
s'en dédommager, reçut vigoureusement les corps qui se
présentèrent à lui, et leur fit essuyer une perte notable. Dans le
même moment, le corps du maréchal Bernadotte, cherchant à
s'établir sur la basse Passarge, et obligé pour cela d'occuper
Braunsberg, s'empara de cette ville, où il fît prisonniers deux mille
Prussiens. Ce fut la division Dupont qui eut le mérite de cette
brillante expédition. Les Russes ayant néanmoins continué de
s'agiter, et paraissant vouloir se porter sur la haute Passarge,
Napoléon, dans les premiers jours de mars, prit le parti de faire sur
la basse Passarge une démonstration offensive, de façon à inquiéter
le général Benningsen pour la sûreté de Kœnigsberg. C'est à regret
que Napoléon se décidait à un tel mouvement, car c'était révéler aux
Russes le danger qu'ils couraient en s'élevant sur notre droite pour
menacer Varsovie. Sachant bien qu'une manœuvre démasquée est
Importance
attachée aux
approvisionnem
ents dans la
position où se
trouvait
Napoléon.
une ressource perdue, Napoléon aurait voulu ne pas agir du tout, ou
agir d'une manière décisive, en marchant sur Kœnigsberg avec
toutes ses forces. Mais, d'une part, il fallait obliger l'ennemi à se
tenir tranquille, afin de l'être soi-même dans ses quartiers d'hiver; de
l'autre, on n'avait ni en vivres ni en munitions de quoi tenter une
opération de quelque durée. Napoléon se résigna donc à une simple
démonstration sur la basse Passarge, exécutée le 3 mars par les
corps des maréchaux Soult et Bernadotte, qui passèrent cette rivière
pendant que le maréchal Ney à Guttstadt poussait rudement le corps
ennemi dirigé sur la haute Passarge. Les Russes perdirent dans ces
mouvements simultanés environ 2 mille hommes, et, en voyant leur
ligne de retraite sur Kœnigsberg compromise, se hâtèrent de se
retirer et de rendre la tranquillité à nos cantonnements.
Tels furent les derniers actes de cette campagne d'hiver. Le froid
long-temps retardé commençait à se faire sentir; le thermomètre
était descendu à 8 et 10 degrés au-dessous de la glace. On allait
avoir en mars le temps auquel on aurait dû s'attendre en décembre
et en janvier.
Napoléon, qui ne s'était décidé que malgré lui à ordonner les
dernières opérations, écrivit au maréchal Soult: «C'est bien un des
inconvénients que j'avais sentis des mouvements actuels, que
d'éclairer les Russes sur leur position. Mais ils me pressaient trop sur
ma droite. Résolu à laisser passer le mauvais temps, et à organiser
les subsistances, je ne suis point autrement fâché de cette leçon
donnée à l'ennemi. Avec l'esprit de présomption dont je le vois
animé, je crois qu'il ne faut que de la patience, pour lui voir faire de
grandes fautes.» (Osterode, 6 mars.)
Si Napoléon avait eu alors assez de vivres et de
moyens de transport pour traîner après lui de quoi
nourrir l'armée pendant quelques jours, il eût
immédiatement terminé la guerre, ayant affaire à
un ennemi assez malavisé pour venir se jeter sur la
droite de ses quartiers. Aussi toute la question
Efforts pour se
procurer des
vivres et des
moyens de
transport.
consistait-elle à ses yeux dans un approvisionnement, qui lui permît
de refaire ses soldats épuisés par les privations, et de les réunir
quelques jours, sans être exposé à les voir mourir de faim, ou à
laisser une moitié d'entre eux en arrière, comme il lui était arrivé à
Eylau. Les villes du littoral, notamment celle d'Elbing, pouvaient lui
fournir des vivres pour les premiers moments de son établissement,
mais de telles ressources ne lui suffisaient pas. Il voulait donc en
amener de grandes quantités, qui descendraient de Varsovie par la
Vistule, ou viendraient de Bromberg par le canal de Nackel, et puis
seraient par terre transportées de la Vistule aux divers
cantonnements de l'armée sur la Passarge. Il
donna les ordres les plus précis à cet égard, pour
amasser d'abord à Bromberg et à Varsovie les
approvisionnements nécessaires, pour créer
ensuite les moyens de transport qui devaient servir
à terminer le trajet de la Vistule aux bords de la
Passarge. Son intention était de commencer par fournir chaque jour
la ration entière à ses soldats, et puis de former à Osterode, centre
de ses quartiers, un magasin général, qui renfermât quelques
millions de rations, en pain, riz, vin, eau-de-vie. Il voulut utiliser à
cet effet le zèle des Polonais, qui jusqu'ici lui avaient rendu peu de
services militaires, et dont il désirait tirer au moins quelques services
administratifs. Comme il avait M. de Talleyrand à Varsovie, il le
chargea de s'entendre avec le gouvernement provisoire, qui dirigeait
les affaires de la Pologne. Il lui écrivit donc la lettre suivante, en lui
envoyant ses pleins pouvoirs pour conclure des marchés à quelque
prix que ce fût.
Osterode, 12 mars, 10 heures du soir.
«Je reçois votre lettre du 10 mars à 3 heures après midi. J'ai
300 mille rations de biscuit à Varsovie. Il faut huit jours pour
venir de Varsovie à Osterode; faites des miracles, mais qu'on
m'en expédie par jour 50 mille rations. Tâchez aussi de me faire
expédier par jour 2 mille pintes d'eau-de-vie. Aujourd'hui le sort
de l'Europe et les plus grands calculs dépendent des
subsistances. Battre les Russes, si j'ai du pain, est un
enfantillage. J'ai des millions, je ne me refuse pas d'en donner.
Tout ce que vous ferez sera bien fait, mais il faut qu'au reçu de
cette lettre on m'expédie, par terre et par Mlawa et Zakroczin, 50
mille rations de biscuit et 2 mille pintes. C'est l'affaire de 80
voitures par jour en les payant au poids de l'or. Si le patriotisme
des Polonais ne peut pas faire cet effort, ils ne sont pas bons à
grand'chose. L'importance de ce dont je vous charge là est plus
considérable que toutes les négociations du monde. Faites
appeler l'ordonnateur, le gouverneur, le général Lemarois, les
hommes les plus influents du gouvernement. Donnez de l'argent;
j'approuve tout ce que vous ferez. Du biscuit et de l'eau-de-vie,
c'est tout ce qu'il nous faut. Ces 300 mille rations de biscuit et
ces 18 ou 20 mille pintes d'eau-de-vie qui peuvent nous arriver
dans quelques jours, voilà ce qui déjouera les combinaisons de
toutes les puissances.»
M. de Talleyrand assembla les membres du gouvernement
polonais, pour tâcher d'en obtenir les vivres et les charrois dont on
avait besoin. Les denrées ne manquaient pas en Pologne, car avec
de l'argent comptant fourni aux juifs, on était sûr d'en trouver. Mais
les moyens de transport étaient fort difficiles à organiser. On voulut
d'abord s'en procurer dans le pays même, en payant des prix
considérables; puis on finit par acheter des charrettes et des
chevaux, et on parvint ainsi à établir des relais aboutissant des bords
de la Vistule à ceux de la Passarge. Les vivres circulaient en bateaux
sur la Vistule; débarqués ensuite à Varsovie, à Plock, à Thorn, à
Marienwerder, ils étaient transportés à Osterode, centre des
cantonnements, ou sur les caissons des régiments, ou sur les
voitures du pays, ou sur celles qu'on avait soi-même achetées et
pourvues de chevaux. On rechercha en les payant des bœufs dans
toute la Silésie, et on les fit venir sur pied à Varsovie. On tâcha de
recueillir des vins et des spiritueux sur le littoral du nord, où le
commerce les apporte en quantité considérable, et en qualité
supérieure. On en avait à Berlin, à Stettin, à Elbing; on les achemina
par eau jusqu'à Thorn. Napoléon eût attaché beaucoup de prix à se
Situation des
troupes dans les
cantonnements.
Arrivée des
renforts
organisés en
régiments
provisoires.
procurer deux ou trois cent mille bouteilles de vin, pour réjouir le
cœur de ses soldats. Il avait près de lui une précieuse ressource en
ce genre, mais elle était renfermée dans la place de Dantzig, où se
trouvaient plusieurs millions de bouteilles d'excellents vins, c'est-à-
dire de quoi en fournir à l'armée pendant quelques mois. Ce n'était
pas un médiocre stimulant pour prendre cette forteresse.
Ces soins si actifs, consacrés à
l'approvisionnement de l'armée, ne pouvaient pas
produire un effet immédiat; mais, dans l'intervalle,
on vivait sur la Nogath, sur Elbing, sur les districts
mêmes qu'on occupait, et l'industrie de nos soldats suppléant à ce
qui manquait, on était parvenu à se procurer le nécessaire.
Beaucoup de vivres cachés avaient été découverts, et avaient permis
d'attendre les arrivages réguliers de la Vistule. On était logé dans les
villages, et on ne bivouaquait plus, ce qui était un grand
soulagement pour des troupes qui venaient de bivouaquer pendant
cinq mois de suite, depuis octobre jusqu'à février. Aux avant-postes,
on vivait dans des baraques, dont ce pays de forêts fournissait en
abondance les matériaux et le chauffage. Quelques vins, quelques
eaux-de-vie, trouvés à Elbing, et distribués avec ordre, rendaient à
nos soldats un peu de gaieté. Les premiers jours passés, ils avaient
fini par être mieux que sur la Narew, car le pays était meilleur, et ils
espéraient bien, au retour de la belle saison, se dédommager des
peines présentes, et terminer en un jour de bataille la terrible lutte
dans laquelle ils étaient engagés.
Les régiments provisoires, qui amenaient les
recrues, commençaient à paraître sur la Vistule.
Plusieurs d'entre eux, déjà rendus sur le théâtre de
la guerre, avaient été passés en revue, dissous, et
répartis entre les régiments auxquels ils
appartenaient. Les soldats voyaient ainsi leurs
rangs se remplir, entendaient parler de renforts nombreux qui se
préparaient sur les derrières de l'armée, et se confiaient davantage
dans la vigilance suprême qui pourvoyait à tous leurs besoins. La
Soins pour
remonter la
cavalerie.
Travaux de
défense sur la
Passarge et la
Vistule.
cavalerie continuait d'être l'objet des soins les plus
attentifs. Napoléon avait formé des détachements
à pied de tous les cavaliers démontés, et il les
avait envoyés en Silésie, pour aller y chercher les
chevaux dont cette province abondait.
Des travaux immenses s'exécutaient sur la
Passarge et la Vistule, afin d'assurer la position de
l'armée. Tous les ponts sur la Passarge avaient été
détruits, deux exceptés, l'un pour l'usage du corps
du maréchal Bernadotte à Braunsberg, l'autre pour
l'usage du corps du maréchal Soult à Spanden. De vastes têtes de
pont étaient ajoutées à chacun des deux, afin de pouvoir déboucher
au delà, Napoléon répétant sans cesse à ses lieutenants, qu'une
ligne n'était facile à défendre que lorsqu'on était en mesure de la
franchir à son tour pour prendre l'offensive contre celui qui
l'attaquait[27]. Deux ponts sur la Vistule, l'un à Marienbourg, l'autre à
Marienwerder, assuraient la communication avec les troupes du
maréchal Lefebvre, chargées du siége de Dantzig. On pouvait donc
aller à elles, ou les amener à soi, et présenter partout à l'ennemi une
masse compacte. Le maréchal Lefebvre se rapprochait de Dantzig,
en attendant la grosse artillerie tirée des places de la Silésie, pour
commencer ce grand siége, qui devait être l'occupation et la gloire
de l'hiver. Les ouvrages de Sierock, de Praga, de Modlin, destinés à
consolider la position de Varsovie, se poursuivaient également.
C'est du petit bourg d'Osterode que Napoléon ordonnait toutes ces
choses. Ses soldats ayant du pain, des pommes de terre, de la
viande, de l'eau-de-vie, du chaume pour s'abriter, du bois pour se
chauffer, ne souffraient pas. Mais les officiers qui ne parvenaient à se
procurer que la nourriture et le logement du soldat, même avec leur
solde exactement payée, étaient exposés à beaucoup de privations.
Napoléon avait voulu leur donner l'exemple de la résignation, en
restant au milieu d'eux. Les officiers de chaque corps, envoyés à
Osterode, pouvaient dire qu'ils ne l'avaient pas trouvé mieux établi
que le dernier d'entre eux. Aussi, répondant à son frère Joseph, qui
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
More than just a book-buying platform, we strive to be a bridge
connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.
Join us on a journey of knowledge exploration, passion nurturing, and
personal growth every day!
ebookbell.com

Contenu connexe

PDF
The Actionscript 30 Quick Reference Guide For Developers And Designers Using ...
PPT
Lavorare con java 6
PDF
Production Kubernetes: Building Successful Application Platforms 1st Edition ...
PDF
WebSphere solution guide WebSphere Application Server Express version 5 0 1st...
PDF
Intraenterprise Business Process Management Ibm Redbooks
PDF
La puissance des backlinks dans le SEO..
PDF
Mercurial The Definitive Guide 1st Edition Bryan O'Sullivan
PDF
Programming Logic And Design Comprehensive 6th Edition 6th Edition Joyce Farrell
The Actionscript 30 Quick Reference Guide For Developers And Designers Using ...
Lavorare con java 6
Production Kubernetes: Building Successful Application Platforms 1st Edition ...
WebSphere solution guide WebSphere Application Server Express version 5 0 1st...
Intraenterprise Business Process Management Ibm Redbooks
La puissance des backlinks dans le SEO..
Mercurial The Definitive Guide 1st Edition Bryan O'Sullivan
Programming Logic And Design Comprehensive 6th Edition 6th Edition Joyce Farrell

Similaire à Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders (20)

PDF
iOS 11 Swift Programming Cookbook Solutions and Examples for iOS Apps 1st Edi...
PDF
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET...
PDF
Deploy automatic in the cloud
PDF
Hacking Kubernetes Threat Driven Analysis and Defense 1st Edition Andrew Martin
PDF
Rapport Projet Application Web De Domotique Arduino - Liotard Roulleau
PDF
Twitter API Up and Running 1st Edition Kevin Makice
PDF
CSS cookbook Description based on print version record Updated for Firefox 3 ...
PDF
The Ring programming language version 1.9 book - Part 3 of 210
PDF
Android VoIP/SIP Softphone
PDF
Projet de-recherche-Tuteuré
PDF
Guide nvivo 9
PDF
Ms es 70-291_1.0_fr
PDF
réaliser une plateforme d’automatisation et de génération des rapports de test
PDF
The Ring programming language version 1.9 book - Part 1 of 210
PDF
Apache Web Server Index
PDF
The Ring programming language version 1.3 book - Part 1 of 88
PDF
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...
PDF
C 6 0 Cookbook Solutions for C Developers 4th Edition Jay Hilyard
PDF
The Ring programming language version 1.10 book - Part 3 of 212
PDF
Christophe blaess shells-linux_et_unix_par_la_pratique_-eyrolles_(�ditions...
iOS 11 Swift Programming Cookbook Solutions and Examples for iOS Apps 1st Edi...
Programming ASP NET MVC 4 Developing Real World Web Applications with ASP NET...
Deploy automatic in the cloud
Hacking Kubernetes Threat Driven Analysis and Defense 1st Edition Andrew Martin
Rapport Projet Application Web De Domotique Arduino - Liotard Roulleau
Twitter API Up and Running 1st Edition Kevin Makice
CSS cookbook Description based on print version record Updated for Firefox 3 ...
The Ring programming language version 1.9 book - Part 3 of 210
Android VoIP/SIP Softphone
Projet de-recherche-Tuteuré
Guide nvivo 9
Ms es 70-291_1.0_fr
réaliser une plateforme d’automatisation et de génération des rapports de test
The Ring programming language version 1.9 book - Part 1 of 210
Apache Web Server Index
The Ring programming language version 1.3 book - Part 1 of 88
Mémoire Parallélisation d'algorithmes de graphes avec MapReduce sur un cluste...
C 6 0 Cookbook Solutions for C Developers 4th Edition Jay Hilyard
The Ring programming language version 1.10 book - Part 3 of 212
Christophe blaess shells-linux_et_unix_par_la_pratique_-eyrolles_(�ditions...
Publicité

Dernier (20)

DOCX
ENDODONTIE CONSERVATRICE.docx faculté de médecine dentaire
PPTX
Conception de documents et d'interfaces numériques.pptx
PPTX
SESSION4-SUPPORT-DE-COURS-FLEC-(Future leader en énergie au Cameroun)-CECOSDA...
PPTX
Devenir Inspecteur HSE _ Chp1_ L1....pptx
PPT
étude----- droit------ 2005---------.ppt
PDF
🎓 Le Secret des Profs Captivants - 💡 2. Hygiène vocale et santé professionnel...
PPTX
le-present-de-lindicatif-ou-le-subjonctif-present-exercice-grammatical-feuill...
PPTX
Copie de Présentation Personal Branding J2025.pptx_20250610_120558_0000.pptx
PPTX
Fondamentaux du LMD.pptx pour les etudiants
PDF
585-developpement-d-une-application-avec-python-fr-en-business.pdf
PPTX
Presentation_carte_arduino_uno_1_Entree_Sortie_numerique.pptx
PDF
Consignes générales sécurité et environnement.pdf
PPTX
le subjonctif présent, Conjugaison français
PPTX
Le rendez-vous de l'été.pptx Film français
PPTX
SESSION3-SUPPORT-DE-COURS-FLEC-(Future leader en énergie au Cameroun)-CECOSDA...
PPT
مبادئ و هدف الحركة الكشفية عرض تقديمي.ppt
PPTX
GESTION PHYTO_10-1_ SESAME PRPS BF JUIN 2020.pptx
PPTX
Séminaire protection des personnes vulnérables.pptx
PPTX
Hopital bonne sante.pptxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PPTX
SESSION2-SUPPORT-DE-COURS-FLEC-(Future leader en énergie au Cameroun)-CECOSDA...
ENDODONTIE CONSERVATRICE.docx faculté de médecine dentaire
Conception de documents et d'interfaces numériques.pptx
SESSION4-SUPPORT-DE-COURS-FLEC-(Future leader en énergie au Cameroun)-CECOSDA...
Devenir Inspecteur HSE _ Chp1_ L1....pptx
étude----- droit------ 2005---------.ppt
🎓 Le Secret des Profs Captivants - 💡 2. Hygiène vocale et santé professionnel...
le-present-de-lindicatif-ou-le-subjonctif-present-exercice-grammatical-feuill...
Copie de Présentation Personal Branding J2025.pptx_20250610_120558_0000.pptx
Fondamentaux du LMD.pptx pour les etudiants
585-developpement-d-une-application-avec-python-fr-en-business.pdf
Presentation_carte_arduino_uno_1_Entree_Sortie_numerique.pptx
Consignes générales sécurité et environnement.pdf
le subjonctif présent, Conjugaison français
Le rendez-vous de l'été.pptx Film français
SESSION3-SUPPORT-DE-COURS-FLEC-(Future leader en énergie au Cameroun)-CECOSDA...
مبادئ و هدف الحركة الكشفية عرض تقديمي.ppt
GESTION PHYTO_10-1_ SESAME PRPS BF JUIN 2020.pptx
Séminaire protection des personnes vulnérables.pptx
Hopital bonne sante.pptxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SESSION2-SUPPORT-DE-COURS-FLEC-(Future leader en énergie au Cameroun)-CECOSDA...
Publicité

Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders

  • 1. Even Faster Web Sites Performance Best Practices For Web Developers Original Steve Souders download https://ebookbell.com/product/even-faster-web-sites-performance- best-practices-for-web-developers-original-steve-souders-4642610 Explore and download more ebooks at ebookbell.com
  • 2. Here are some recommended products that we believe you will be interested in. You can click the link to download. Even Faster Web Sites Steve Souders https://ebookbell.com/product/even-faster-web-sites-steve- souders-48132392 Even Faster Web Sites Steve Souders https://ebookbell.com/product/even-faster-web-sites-steve- souders-48121340 Nginx Http Server Adopt Nginx For Your Web Applications To Make The Most Of Your Infrastructure And Serve Pages Faster Than Ever Clment Nedelcu https://ebookbell.com/product/nginx-http-server-adopt-nginx-for-your- web-applications-to-make-the-most-of-your-infrastructure-and-serve- pages-faster-than-ever-clment-nedelcu-1960504 Words At Work Powerful Business Writing Skills Deliver Increased Sales Improved Results And Even A Promotion Or Two Write Faster Series Book 1 Mcdaniel https://ebookbell.com/product/words-at-work-powerful-business-writing- skills-deliver-increased-sales-improved-results-and-even-a-promotion- or-two-write-faster-series-book-1-mcdaniel-55709518
  • 3. Halloween 03 Tales From Even Darker Places Foster Ray Caile https://ebookbell.com/product/halloween-03-tales-from-even-darker- places-foster-ray-caile-61758306 Italian Cooking In Your Instant Pot 60 Flavorful Homestyle Favorites Made Faster Than Ever Tawnie Graham https://ebookbell.com/product/italian-cooking-in-your-instant- pot-60-flavorful-homestyle-favorites-made-faster-than-ever-tawnie- graham-51139210 Nginx Http Server Fourth Edition Harness The Power Of Nginx To Make The Most Of Your Infrastructure And Serve Pages Faster Than Ever Before Fourth Martin Fjordvald Clement Nedelcu https://ebookbell.com/product/nginx-http-server-fourth-edition- harness-the-power-of-nginx-to-make-the-most-of-your-infrastructure- and-serve-pages-faster-than-ever-before-fourth-martin-fjordvald- clement-nedelcu-12070338 Just Sell The Damn Thing The Proven Contrarian Formula To Grow Your Business Faster Than Ever Doberman Dan https://ebookbell.com/product/just-sell-the-damn-thing-the-proven- contrarian-formula-to-grow-your-business-faster-than-ever-doberman- dan-33706728 Cooking Light Fresh Food Superfast Over 280 Allnew Recipes Faster Than Ever Editors Of Cooking Light Magazine https://ebookbell.com/product/cooking-light-fresh-food-superfast- over-280-allnew-recipes-faster-than-ever-editors-of-cooking-light- magazine-34949052
  • 8. Even Faster Web Sites Steve Souders Beijing • Cambridge • Farnham • Köln • Sebastopol • Taipei • Tokyo
  • 9. Even Faster Web Sites by Steve Souders Copyright © 2009 Steve Souders. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://my.safaribooksonline.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. Editor: Mary E. Treseler Production Editor: Sarah Schneider Copyeditor: Audrey Doyle Proofreader: Sarah Schneider Indexer: Lucie Haskins Cover Designer: Karen Montgomery Interior Designer: David Futato Illustrator: Robert Romano Printing History: June 2009: First Edition. O’Reilly and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc. Even Faster Web Sites, the image of a blackbuck antelope, and related trade dress are trademarks of O’Reilly Media, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O’Reilly Media, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. While every precaution has been taken in the preparation of this book, the publisher and author assume no responsibility for errors or omissions, or for damages resulting from the use of the information con- tained herein. ISBN: 978-0-596-52230-8 [M] 1243719104
  • 10. Table of Contents Credits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii 1. Understanding Ajax Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Trade-offs 1 Principles of Optimization 1 Ajax 4 Browser 4 Wow! 5 JavaScript 6 Summary 6 2. Creating Responsive Web Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 What Is Fast Enough? 9 Measuring Latency 10 When Latency Goes Bad 12 Threading 12 Ensuring Responsiveness 13 Web Workers 14 Gears 14 Timers 16 Effects of Memory Use on Response Time 17 Virtual Memory 18 Troubleshooting Memory Issues 18 Summary 19 3. Splitting the Initial Payload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Kitchen Sink 21 Savings from Splitting 22 Finding the Split 23 Undefined Symbols and Race Conditions 24 v
  • 11. Case Study: Google Calendar 25 4. Loading Scripts Without Blocking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Scripts Block 27 Making Scripts Play Nice 29 XHR Eval 29 XHR Injection 31 Script in Iframe 31 Script DOM Element 32 Script Defer 32 document.write Script Tag 33 Browser Busy Indicators 33 Ensuring (or Avoiding) Ordered Execution 35 Summarizing the Results 36 And the Winner Is 38 5. Coupling Asynchronous Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Code Example: menu.js 42 Race Conditions 44 Preserving Order Asynchronously 45 Technique 1: Hardcoded Callback 46 Technique 2: Window Onload 47 Technique 3: Timer 48 Technique 4: Script Onload 49 Technique 5: Degrading Script Tags 50 Multiple External Scripts 52 Managed XHR 52 DOM Element and Doc Write 56 General Solution 59 Single Script 59 Multiple Scripts 60 Asynchronicity in the Real World 63 Google Analytics and Dojo 63 YUI Loader Utility 65 6. Positioning Inline Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Inline Scripts Block 69 Move Inline Scripts to the Bottom 70 Initiate Execution Asynchronously 71 Use Script Defer 73 Preserving CSS and JavaScript Order 73 Danger: Stylesheet Followed by Inline Script 74 Inline Scripts Aren’t Blocked by Most Downloads 74 vi | Table of Contents
  • 12. Inline Scripts Are Blocked by Stylesheets 75 This Does Happen 77 7. Writing Efficient JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Managing Scope 79 Use Local Variables 81 Scope Chain Augmentation 83 Efficient Data Access 85 Flow Control 88 Fast Conditionals 89 Fast Loops 93 String Optimization 99 String Concatenation 99 Trimming Strings 100 Avoid Long-Running Scripts 102 Yielding Using Timers 103 Timer Patterns for Yielding 105 Summary 107 8. Scaling with Comet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 How Comet Works 109 Transport Techniques 111 Polling 111 Long Polling 112 Forever Frame 113 XHR Streaming 115 Future Transports 116 Cross-Domain 116 Effects of Implementation on Applications 118 Managing Connections 118 Measuring Performance 119 Protocols 119 Summary 120 9. Going Beyond Gzipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 Why Does This Matter? 121 What Causes This? 123 Quick Review 123 The Culprit 123 Examples of Popular Turtle Tappers 124 How to Help These Users? 124 Design to Minimize Uncompressed Size 125 Educate Users 129 Table of Contents | vii
  • 13. Direct Detection of Gzip Support 130 10. Optimizing Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Two Steps to Simplify Image Optimization 134 Image Formats 135 Background 135 Characteristics of the Different Formats 137 More About PNG 139 Automated Lossless Image Optimization 141 Crushing PNGs 141 Stripping JPEG Metadata 143 Converting GIF to PNG 144 Optimizing GIF Animations 144 Smush.it 144 Progressive JPEGs for Large Images 145 Alpha Transparency: Avoid AlphaImageLoader 146 Effects of Alpha Transparency 146 AlphaImageLoader 148 Problems with AlphaImageLoader 149 Progressively Enhanced PNG8 Alpha Transparency 151 Optimizing Sprites 152 Über-Sprite Versus Modular Sprite 153 Highly Optimized CSS Sprites 154 Other Image Optimizations 155 Avoid Scaling Images 155 Crush Generated Images 155 Favicons 157 Apple Touch Icon 158 Summary 158 11. Sharding Dominant Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Critical Path 161 Who’s Sharding? 163 Downgrading to HTTP/1.0 165 Rolling Out Sharding 168 IP Address or Hostname 168 How Many Domains 168 How to Split Resources 168 Newer Browsers 169 12. Flushing the Document Early . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Flush the Head 171 Output Buffering 173 viii | Table of Contents
  • 14. Chunked Encoding 175 Flushing and Gzip 176 Other Intermediaries 177 Domain Blocking During Flushing 178 Browsers: The Last Hurdle 178 Flushing Beyond PHP 179 The Flush Checklist 180 13. Using Iframes Sparingly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 The Most Expensive DOM Element 181 Iframes Block Onload 182 Parallel Downloads with Iframes 184 Script Before Iframe 184 Stylesheet Before Iframe 185 Stylesheet After Iframe 186 Connections per Hostname 187 Connection Sharing in Iframes 187 Connection Sharing Across Tabs and Windows 188 Summarizing the Cost of Iframes 190 14. Simplifying CSS Selectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 Types of Selectors 191 ID Selectors 192 Class Selectors 193 Type Selectors 193 Adjacent Sibling Selectors 193 Child Selectors 193 Descendant Selectors 193 Universal Selectors 194 Attribute Selectors 194 Pseudo-Classes and Pseudo-Elements 194 The Key to Efficient CSS Selectors 194 Rightmost First 195 Writing Efficient CSS Selectors 195 CSS Selector Performance 197 Complex Selectors Impact Performance (Sometimes) 197 CSS Selectors to Avoid 200 Reflow Time 201 Measuring CSS Selectors in the Real World 202 Appendix: Performance Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 Table of Contents | ix
  • 16. Credits Even Faster Web Sites contains six chapters contributed by the following authors. Dion Almaer is the cofounder of Ajaxian.com, the leading source of the Ajax com- munity. For his day job, Dion coleads a new group at Mozilla focusing on developer toolsfortheWeb,somethinghehasbeenpassionateaboutdoingforyears.Heisexcited for the opportunity, and he gets to work with Ben Galbraith, his partner in crime on Ajaxian and now at Mozilla. Dion has been writing web applications since Gopher, has been fortunate enough to speak around the world, has published many articles and a book, and, of course, covers life, the universe, and everything else on his blog at http: //almaer.com/blog. Douglas Crockford was born in the wilds of Minnesota, but left when he was only six months old because it was just too damn cold. He turned his back on a promising career in television when he discovered computers. He has worked in learning systems, small business systems, office automation, games, interactive music, multimedia, location-based entertainment, social systems, and programming languages. He is the inventor of Tilton, the ugliest programming language that was not specifically designed to be an ugly programming language. He is best known for having discovered that there are good parts in JavaScript. This was an important and unexpected discovery. He discovered the JSON (JavaScript Object Notation) data interchange format. He is cur- rently working on making the Web a secure and reliable software-delivery platform. He has his work cut out for him. Ben Galbraith is the codirector of developer tools at Mozilla and the cofounder of Ajaxian.com. Ben has long juggled interests in both business and tech, having written his first computer program at 6 years old, started his first business at 10, and entered the IT workforce at 12. He has delivered hundreds of technical presentations world- wide, produced several technical conferences, and coauthored more than a half-dozen books. He has enjoyed a variety of business and technical roles throughout his career, including CEO, CIO, CTO, and Chief Software Architect roles in medical, publishing, media, manufacturing, advertising, and software industries. He lives in Palo Alto, California with his wife and five children. xi
  • 17. Tony Gentilcore is a software engineer at Google. There, he has helped make the Google home and search results pages lightning fast. He finds that the days seem to fly by while writing web performance tools and techniques. Tony is also the creator of the popular Firefox extension, Fasterfox. Dylan Schiemann is CEO of SitePen and cofounder of the Dojo Toolkit, an open source JavaScript toolkit for rapidly building web sites and applications, and is an expert in the technologies and opportunities of the Open Web. Under his guidance, SitePen has grown from a small development firm to a leading provider of inventive tools, skilled software engineers, knowledgeable consulting services, and top-notch training and advice. Dylan’s commitment to R&D has enabled SitePen to be a major contributor to and creator of pioneering open source web development toolkits and frameworks such as Dojo, cometD, Direct Web Remoting (DWR), and Persevere. Prior to SitePen, Dylan developed web applications for companies such as Renkoo, Infor- matica, Security FrameWorks, and Vizional Technologies. He is a cofounder of Comet Daily, LLC, a board member at Dojo Foundation, and a member of the advisory board at Aptana. Dylan earned his master’s in physical chemistry from UCLA and his B.A. in mathematics from Whittier College. Stoyan Stefanov is a Yahoo! frontend developer, focusing on web application performance. He is also the architect of the performance extension YSlow 2.0 and cocreator of the Smush.it image optimization tool. Stoyan is a speaker, book author (Object-Oriented JavaScript from Packt Publishing), and blogger at http://phpied.com, http://jspatterns.com, and YUIblog. Nicole Sullivan is an evangelist, frontend performance consultant, and CSS Ninja. She startedtheObject-OrientedCSSopensourceproject,whichanswersthequestion,How do you scale CSS for millions of visitors or thousands of pages? She also consulted with the W3C for their beta redesign, and she is the cocreator of Smush.it, an image opti- mization service in the cloud. She is passionate about CSS, web standards, and scalable frontend architecture for large commercial websites. Nicole speaks about performance at conferences around the world, most recently at The Ajax Experience, ParisWeb, and Web Directions North. She blogs at http://stubbornella.org. Nicholas C. Zakas is the author of Professional JavaScript for Web Developers, Second Edition (Wrox) and coauthor of Professional Ajax, Second Edition (Wrox). Nicholas is principal frontend engineer for the Yahoo! home page and is also a contributor to the Yahoo! User Interface (YUI) library. He blogs regularly at his site, http://www .nczonline.net. xii | Credits
  • 18. Preface Vigilant: alertly watchful, especially to avoid danger Anyone browsing this book—or its predecessor, High Performance Web Sites—under- stands the dangers of a slow web site: frustrated users, negative brand perception, increased operating expenses, and loss of revenue. We have to constantly work to make our web sites faster. As we make progress, we also lose ground. We have to be alert for the impact of each bug fix, new feature, and system upgrade on our web site’s speed. We have to be watchful, or the performance improvements made today can easily be lost tomorrow. We have to be vigilant. Vigil: watch kept on a festival eve According to the Latin root of vigil, our watch ends with celebration. Web sites can indeed be faster—dramatically so—and we can celebrate the outcome of our care and attention. It’s true! Making web sites faster is attainable. Some of the world’s most popular web sites have reduced their load times by 60% using the techniques described in this book. Smaller web properties benefit as well. Ultimately, users benefit. Vigilante: a self-appointed doer of justice It’s up to us as developers to guard our users’ interests. At your site, evangelize per- formance. Implement these techniques. Share this book with a coworker. Fight for a faster user experience. If your company doesn’t have someone focused on performance, appoint yourself to that role. Performance vigilante—I like the sound of that. How This Book Is Organized This book is a follow-up to my first book, High Performance Web Sites (O’Reilly). In that book, I lay out 14 rules for better web performance: • Rule 1: Make Fewer HTTP Requests • Rule 2: Use a Content Delivery Network • Rule 3: Add an Expires Header • Rule 4: Gzip Components xiii
  • 19. • Rule 5: Put Stylesheets at the Top • Rule 6: Put Scripts at the Bottom • Rule 7: Avoid CSS Expressions • Rule 8: Make JavaScript and CSS External • Rule 9: Reduce DNS Lookups • Rule 10: Minify JavaScript • Rule 11: Avoid Redirects • Rule 12: Remove Duplicate Scripts • Rule 13: Configure ETags • Rule 14: Make Ajax Cacheable I call them “rules” because there is little ambiguity about their adoption. Consider these statistics for the top 10 U.S. web sites* for March 2007: • Two sites used CSS sprites. • 26% of resources had a future Expires header. • Five sites compressed their HTML, JavaScript, and CSS. • Four sites minified their JavaScript. The same statistics for April 2009 show that these rules are gaining traction: • Nine sites use CSS sprites. • 93% of resources have a future Expires header. • Ten sites compress their HTML, JavaScript, and CSS. • Nine sites minify their JavaScript. The rules from High Performance Web Sites still apply and are where most web com- panies should start. Progress is being made, but there’s still more work to be done on this initial set of rules. But the Web isn’t standing still, waiting for us to catch up. Although the 14 rules from High Performance Web Sites still apply, the growth in web page content and Web 2.0 applications introduces a new set of performance challenges. Even Faster Web Sites provides the best practices needed by developers to make these next-generation web sites faster. The chapters in this book are organized into three areas: JavaScript performance (Chapters 1–7), network performance (Chapters 8–12), and browser performance (Chapters 13 and 14). A roundup of the best tools for analyzing performance comes in the Appendix. * AOL, eBay, Facebook, Google Search, Live Search, MSN.com, MySpace, Wikipedia, Yahoo!, and YouTube, according to Alexa. xiv | Preface
  • 20. Six of the chapters were written by contributing authors: • Chapter 1, Understanding Ajax Performance, by Douglas Crockford • Chapter 2, Creating Responsive Web Applications, by Ben Galbraith and Dion Almaer • Chapter 7, Writing Efficient JavaScript, by Nicholas C. Zakas • Chapter 8, Scaling with Comet, by Dylan Schiemann • Chapter 9, Going Beyond Gzipping, by Tony Gentilcore • Chapter 10, Optimizing Images, by Stoyan Stefanov and Nicole Sullivan These authors are experts in each of these areas. I wanted you to hear from them directly, in their own voices. To help identify these chapters, the name(s) of the con- tributing author(s) are on the chapter’s opening page. JavaScript Performance In my work analyzing today’s web sites, I consistently see that JavaScript is the key to better-performing web applications, so I’ve started the book with these chapters. Douglas Crockford wrote Chapter 1, Understanding Ajax Performance. Doug describes how Ajax changes the way browsers and servers interact, and how web developers need to understand this new relationship to properly identify opportunities for improving performance. Chapter 2, Creating Responsive Web Applications, by Ben Galbraith and Dion Almaer, ties JavaScript performance back to what really matters: the user experience. Today’s web applications invoke complex functions at the click of a button and must be eval- uated on the basis of what they’re forcing the browser to do. The web applications that succeed will be written by developers who understand the effects of their code on response time. I wrote the next four chapters. They focus on the mechanics of JavaScript—the best way to package it and load it, and where to insert it in your pages. Chapter 3, Splitting the Initial Payload, describes the situation facing many web applications today: a huge JavaScriptdownloadatthebeginningofthepagethatblocksrenderingaswellasfurther downloads. The key is to break apart this monolithic JavaScript for more efficient loading. Chapters 4 and 5 go together. In today’s most popular browsers, external scripts block everything else in the page. Chapter 4, Loading Scripts Without Blocking, explains how to avoid these pitfalls when loading external scripts. Loading scripts asynchronously presents a challenge when inlined code depends on them. Luckily, there are several techniques for coupling inlined code with the asynchronous scripts on which they de- pend. These techniques are presented in Chapter 5, Coupling Asynchronous Scripts. Preface | xv
  • 21. Chapter 6, Positioning Inline Scripts, presents performance best practices that apply to inline scripts, especially the impact they have on blocking parallel downloads. I think of Chapter 7, Writing Efficient JavaScript, written by Nicholas C. Zakas, as the complement to Doug’s chapter (Chapter 1). Whereas Doug describes the Ajax land- scape, Nicholas zooms in on several specific techniques for speeding up JavaScript. Network Performance Web applications aren’t desktop applications—they have to be downloaded over the Internet each time they are used. The adoption of Ajax has resulted in a new style of data communication between servers and clients. Some of the biggest opportunities for growth in the web industry are in emerging markets where Internet connectivity is a challenge, to put it mildly. All of these factors highlight the need for improved network performance. In Chapter 8, Scaling with Comet, Dylan Schiemann describes an architecture that goes beyond Ajax to provide high-volume, low-latency communication for real-time appli- cations such as chat and document collaboration. Chapter 9, Going Beyond Gzipping, describes how turning on compression isn’t enough to guarantee optimal delivery of your web site’s content. Tony Gentilcore reveals a little-known phenomenon that severely hinders the network performance of 15% of the world’s Internet users. Stoyan Stefanov and Nicole Sullivan team up to contribute Chapter 10, Optimizing Images. This is a thorough treatment of the topic. This chapter reviews all popular image formats, presents numerous image optimization techniques, and describes the image compression tools of choice. The remaining chapters were written by me. Chapter 11, Sharding Dominant Do- mains, reminds us of the connection limits in the popular browsers of today, as well as the next generation of browsers. It includes techniques for successfully splitting resources across multiple domains. Chapter 12, Flushing the Document Early, walks through the benefits and many gotchas of using chunked encoding to start rendering the page even before the full HTML document has arrived. Browser Performance Iframes are an easy and frequently used technique for embedding third-party content in a web page. But they come with a cost. Chapter 13, Using Iframes Sparingly, explains the downsides of iframes and offers a few alternatives. Chapter 14, Simplifying CSS Selectors, presents the theories about how complex selec- tors can impact performance, and then does an objective analysis to pinpoint the situations that are of most concern. xvi | Preface
  • 22. The Appendix, Performance Tools, describes the tools that I recommend for analyzing web sites and discovering the most important performance improvements to work on. Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, file extensions, pathnames, and directories Constant width Indicates commands, options, switches, variables, attributes, keys, functions, types, classes, namespaces, methods, modules, properties, parameters, values, ob- jects, events, event handlers, XML tags, HTML tags, macros, the contents of files, and the output from commands Constant width bold Shows commands or other text that should be typed literally by the user Constant width italic Shows text that should be replaced with user-supplied values This icon signifies a tip, suggestion, or general note. This icon indicates a warning or caution. Comments and Questions Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 1005 Gravenstein Highway North Sebastopol, CA 95472 800-998-9938 (in the United States or Canada) 707-829-0515 (international or local) 707-829-0104 (fax) We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at: http://www.oreilly.com/catalog/9780596522308 Preface | xvii
  • 23. To comment or ask technical questions about this book, send email to: bookquestions@oreilly.com For more information about our books, conferences, Resource Centers, and the O’Reilly Network, see our web site at: http://www.oreilly.com Using Code Examples You may use the code in this book in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from this book does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of ex- ample code from this book into your product’s documentation does require permission. We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Even Faster Web Sites, by Steve Souders. Copyright 2009 Steve Souders, 978-0-596-52230-8.” If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at permissions@oreilly.com. Safari® Books Online When you see a Safari® Books Online icon on the cover of your favorite technology book, that means the book is available online through the O’Reilly Network Safari Bookshelf. Safari offers a solution that’s better than e-books. It’s a virtual library that lets you easily search thousands of top tech books, cut and paste code samples, download chapters, and find quick answers when you need the most accurate, current information. Try it for free at http://my.safaribooksonline.com. Acknowledgments I first want to thank the contributing authors: Dion Almaer, Doug Crockford, Ben Galbraith, Tony Gentilcore, Dylan Schiemann, Stoyan Stefanov, Nicole Sullivan, and Nicholas Zakas. They’ve made this a special book. Each of them is an expert in his or her own right. Most of them have written their own books. By sharing their expertise, they’ve helped create something unique. xviii | Preface
  • 24. I want to thank all the reviewers: Julien Lecomte, Matthew Russell, Bill Scott, and Tenni Theurer. I extend an especially strong thank you to Eric Lawrence and Andy Oram. Eric reviewed both this book as well as High Performance Web Sites. In both cases, he provided incredibly thorough and knowledgeable feedback. Andy was my editor on High Performance Web Sites. More than anyone else, he is responsible for improving how this book reads, making it flow smoothly from line to line, section to section, and chapter to chapter. A special thank you goes to my editor, Mary Treseler. Coordinating a book with mul- tiple authors is an opportunity that many editors will pass over. I’m glad that she took on this project and helped guide it from a bunch of ideas to what you’re holding in your hands now. I work with many people at Google who have a penchant for web performance. Tony Gentilcore is the creator of Fasterfox and the author of Chapter 9. He’s also my offi- cemate. Several times a day we’ll stop to discuss web performance. Steve Lamm, Lind- sey Simon, and Annie Sullivan are strong advocates for performance who I work with frequently. Other Googlers who have contributed to what I know about web perform- ance include Jacob Hoffman-Andrews, Kyle Scholz, Steve Krulewitz, Matt Gundersen, Gavin Doughtie, and Bryan McQuade. Many of the insights in this book come from my friends outside Google. They know that if they tell me about a good performance tip, it’s likely to end up in a book or blog post. These performance cohorts include Dion Almaer, Artur Bergman, Doug Crock- ford, Ben Galbraith, Eric Goldsmith, Jon Jenkins, Eric Lawrence, Mark Nottingham, Simon Perkins, John Resig, Alex Russell, Eric Schurman, Dylan Schiemann, Bill Scott, Jonas Sicking, Joseph Smarr, and Tenni Theurer. I’ve inevitably forgotten to mention someone in these lists. I apologize, and want to thank all of you for taking the time to send me email and talk to me at conferences. Hearingyourlessonslearnedandsuccessstorieskeepsmegoing.It’simportanttoknow there are so many of us who are working to make the Web a faster place. Thank you to my parents for being proud to have a son who’s an author. Most impor- tantly, thank you to my wife and three daughters. I promise to take a break now. Preface | xix
  • 26. CHAPTER 1 Understanding Ajax Performance Douglas Crockford Premature optimization is the root of all evil. —Donald Knuth Trade-offs The design and construction of a computer program can involve thousands of deci- sions, each representing a trade-off. In difficult decisions, each alternative has signifi- cant positive and negative consequences. In trading off, we hope to obtain a near optimal good while minimizing the bad. Perhaps the ultimate trade-off is: I want to go to heaven, but I don’t want to die. More practically, the Project Triangle: Fast. Good. Cheap. Pick Two. predicts that even under ideal circumstances, it is not possible to obtain fast, good, and cheap. There must be a trade-off. In computer programs, we see time versus memory trade-offs in the selection of algo- rithms. We also see expediency or time to market traded against code quality. Such trades can have a large impact on the effectiveness of incremental development. Every time we touch the code, we are trading off the potential of improving the code against the possibility of injecting a bug. When we look at the performance of programs, we must consider all of these trade-offs. Principles of Optimization When looking at optimization, we want to reduce the overall cost of the program. Typically, this cost is the perceived execution time of the program, although we could 1
  • 27. optimize on other factors. We then should focus on the parts of the program that contribute most significantly to its cost. For example, suppose that by profiling we discover the cost of a program’s four modules. Module A B C D Cost 54% 4% 30% 12% If we could somehow cut the cost of Module B in half, we would reduce the total cost by only 2%. We would get a better result by cutting the cost of Module A by 10%. There is little benefit from optimizing components that do not contribute significantly to the cost. The analysis of applications is closely related to the analysis of algorithms. When look- ing at execution time, the place where programs spend most of their time is in loops. The return on optimization of code that is executed only once is negligible. The benefits of optimizing inner loops can be significant. For example, if the cost of a loop is linear with respect to the number of iterations, then we can say it is O(n), and we can graph its performance as shown in Figure 1-1. Figure 1-1. Performance of a loop The execution time of each iteration is reflected in the slope of the line: the greater the cost, the steeper the slope. The fixed overhead of the loop determines the elevation of its starting point. There is usually little benefit in reducing the fixed overhead. Some- times there is a benefit in increasing the fixed overhead if the cost of each increment can be reduced. That can be a good trade-off. In addition to the plot of execution time, there are three lines—the Axes of Error—that our line must not intersect (see Figure 1-2). The first is the Inefficiency line. Crossing this line reduces the user’s ability to concentrate. This can also make people irritable. The second is the Frustration line. When this line is crossed, the user is aware that he 2 | Chapter 1: Understanding Ajax Performance
  • 28. is being forced to wait. This invites him to think about other things, such as the desir- ability of competing web applications. The third is the Failure line. This is when the user refreshes or closes the browser because the application appears to have crashed, or the browser itself produces a dialog suggesting that the application has failed and that the user should take action. Figure 1-2. The Axes of Error There are three ways to avoid intersecting the Axes of Error: reduce the cost of each iteration, reduce the number of iterations, or redesign the application. When loops become nested, your options are reduced. If the cost of the loop is O(n log n), O(n2), or worse, reducing the time per iteration is not effective (see Figure 1-3). The only effective options are to reduce n or to replace the algorithm. Fiddling with the cost per iteration will be effective only when n is very small. Figure 1-3. Performance of a nested loop Programs must be designed to be correct. If the program isn’t right, it doesn’t matter if it is fast. However, it is important to determine whether it has performance problems as early as possible in the development cycle. In testing web applications, test with slow Principles of Optimization | 3
  • 29. machines and slow networks that more closely mimic those of real users. Testing in developer configurations is likely to mask performance problems. Ajax Refactoring the code can reduce its apparent complexity, making optimization and other transformations more likely to yield benefits. For example, adopting the YSlow rules can have a huge impact on the delivery time of web pages (see http://developer .yahoo.com/yslow/). Even so, it is difficult for web applications to get under the Inefficiency line because of the size and complexity of web pages. Web pages are big, heavy, multipart things. Page replacement comes with a significant cost. For applications where the difference between successive pages is relatively small, use of Ajax techniques can produce a sig- nificant improvement. Instead of requesting a replacement page as a result of a user action, a packet of data issenttotheserver(usuallyencodedasJSONtext)andtheserverrespondswithanother packet (also typically JSON-encoded) containing data. A JavaScript program uses that data to update the browser’s display. The amount of data transferred is significantly reduced, and the time between the user action and the visible feedback is also significantly reduced. The amount of work that the server must do is reduced. The amount of work that the browser must do is reduced. The amount of work that the Ajax programmer must do, unfortunately, is likely to increase. That is one of the trade-offs. The architecture of an Ajax application is significantly different from most other sorts of applications because it is divided between two systems. Getting the division of labor right is essential if the Ajax approach is to have a positive impact on performance. The packets should be as small as possible. The application should be constructed as a conversationbetweenthebrowserandtheserver,inwhichthetwohalvescommunicate in a concise, expressive, shared language. Just-in-time data delivery allows the browser side of the application to keep n small, which tends to keep the loops fast. A common mistake in Ajax applications is to send all of the application’s data to the browser. This reintroduces the latency problems that Ajax is supposed to avoid. It also enlarges the volume of data that must be handled in the browser, increasing n and again compromising performance. Browser Ajax applications are challenging to write because the browser was not designed to be an application platform. The scripting language and the Document Object Model (DOM) were intended to support applications composed of simple forms. Surprisingly, the browser gets enough right that it is possible to use it to deliver sophisticated 4 | Chapter 1: Understanding Ajax Performance
  • 30. applications. Unfortunately, it didn’t get everything right, so the level of difficulty can be high. This can be mitigated with the use of Ajax libraries (e.g., http://developer.yahoo .com/yui/). An Ajax library uses the expressive power of JavaScript to raise the DOM toapracticallevel,aswellasrepairingmanyofthehazardsthatcanpreventapplications from running acceptably on the many brands of browsers. Unfortunately, the DOM API is very inefficient and mysterious. The greatest cost in running programs tends to be the DOM, not JavaScript. At the Velocity 2008 confer- ence, the Microsoft Internet Explorer 8 team shared this performance data on how time is spent in the Alexa 100 pages.* Activity Layout Rendering HTML Marshaling DOM Format JScript Other Cost 43.16% 27.25% 2.81% 7.34% 5.05% 8.66% 3.23% 2.5% The cost of running JavaScript is insignificant compared to the other things that the browser spends time on. The Microsoft team also gave an example of a more aggressive Ajax application, the opening of an email thread. Activity Layout Rendering HTML Marshaling DOM Format JScript Other Cost 9.41% 9.21% 1.57% 7.85% 12.47% 38.97% 14.43% 3.72% The cost of the script is still less than 15%. Now CSS processing is the greatest cost. Understanding the mysteries of the DOM and working to suppress its impact is clearly a better strategy than attempting to speed up the script. If you could heroically make the script run twice as fast, it would barely be noticed. Wow! There is a tendency among application designers to add wow features to Ajax applica- tions. These are intended to invoke a reaction such as, “Wow, I didn’t know browsers could do that.” When used badly, wow features can interfere with the productivity of users by distracting them or forcing them to wait for animated sequences to play out. Misused wow features can also cause unnecessary DOM manipulations, which can come with a surprisingly high cost. Wow features should be used only when they genuinely improve the experience of the user. They should not be used to show off or to compensate for deficiencies in func- tionality or usability. Design for things that the browser can do well. For example, viewing a database as an infinitely scrolling list requires that the browser hold on to and display a much larger set than it can manage efficiently. A better alternative is to have a very effective * http://en.oreilly.com/velocity2008/public/schedule/detail/3290 Wow! | 5
  • 31. paginating display with no scrolling at all. This provides better performance and can be easier to use. JavaScript Most JavaScript engines were optimized for quick time to market, not performance, so it is natural to assume that JavaScript is always the bottleneck. Typically, however, the bottleneck is not JavaScript, but the DOM, so fiddling with scripts will have little effectiveness. Fiddling should be avoided. Programs should be coded for correctness and clarity. Fiddling tends to work against clarity, which can increase the susceptibility of the program to attract bugs. Fortunately, competitive pressure is forcing the browser makers to improve the effi- ciency of their JavaScript engines. These improvements will enable new classes of applications in the browser. Avoid obscure idioms that might be faster unless you can prove that they will have a noticeable impact on your application. In most cases, they will have no noticeable impact except to degrade the quality of your code. Do not tune to the quirks of par- ticular browsers. The browsers are still in development and may ultimately favor better coding practices. If you feel you must fiddle, measure first. Our intuitions of the true costs of a program are usually wrong. Only by measuring can you have confidence that you are having a positive effect on performance. Summary Everything is a trade-off. When optimizing for performance, do not waste time trying to speed up code that does not consume a significant amount of the time. Measure first. Back out of any optimization that does not provide an enjoyable benefit. Browsers tend to spend little time running JavaScript. Most of their time is spent in the DOM. Ask your browser maker to provide better performance measurement tools. Code for quality. Clean, legible, well-organized code is easier to get right, easier to maintain, and easier to optimize. Avoid tricks except when they can be proven to substantially improve performance. Ajax techniques, when used well, can make applications faster. The key is in estab- lishing a balance between the browser and the server. Ajax provides an effective alter- native to page replacement, turning the browser into a powerful application platform, but your success is not guaranteed. The browser is a challenging platform and your intuitions about performance are not reliable. The chapters that follow will help you understand how to make even faster web sites. 6 | Chapter 1: Understanding Ajax Performance
  • 32. CHAPTER 2 Creating Responsive Web Applications Ben Galbraith and Dion Almaer With the rise of Ajax, web site performance is no longer just about the quick realization of a web site. An ever-increasing number of web sites, once loaded, will use JavaScript to dynamically change the page and load new content on the fly. Such sites have much in common with traditional desktop client programs, and optimizing the performance of these applications requires a different set of techniques from traditional web sites. From a high level, user interfaces for web applications and traditional desktop appli- cations share a common goal: respond to the user’s input as fast as possible. When it comes to responding to a user’s request to load a web site, the browser itself handles much of the responsiveness burden. It opens network connections to the requested site, parses the HTML, requests the associated resources, and so forth. Based on a careful analysis of this process, we can optimize our pages to render as fast as possible, but the browser is ultimately in control of loading and realizing the page. Whenitcomestorespondingtouserinputtothewebsiteitself(whenthatinputdoesn’t result in the browser loading a new page), we web developers are in control. We must ensure that the JavaScript that executes as a result of such input is responsive. To better understand just how much control we have over responsiveness, we’re going to take a minute to explain how browser user interfaces work. As shown in Figure 2-1, when a user interacts with a browser, the operating system receives input from various devices attached to the computer, such as the keyboard or mouse. It works out which application should receive these inputs, and it packages them up as individual events and places them in a queue for that application, known as an event queue. It’s up to the web browser, like any GUI application, to process the individual events placed in its queue. It does so by pulling them from the queue in first-in, first-out order and deciding what to do about the event. Generally, the browser will do one of two things based on these events: handle the event itself (such as display a menu, browse 7
  • 33. the Web, show a preference screen, etc.) or execute JavaScript code in the web page itself (e.g., JavaScript code in an onclick handler in the page), as shown in Figure 2-2. Figure 2-1. All user input is routed via the operating system into an event queue Figure 2-2. The browser uses a single thread to process events in the queue and execute user code The important takeaway here is that this process is essentially single-threaded. That is, the browser uses a single thread to pull an event from the queue and either do something 8 | Chapter 2: Creating Responsive Web Applications
  • 34. itself (“Web browsing” in Figure 2-2) or execute JavaScript. As such, it can do only one of these tasks at a time, and each of these tasks can prevent the other tasks from occurring. Any time spent by the browser executing a page’s JavaScript is time that it cannot spend responding to other user events. It is therefore vital that any JavaScript in a page execute as fast as possible. Otherwise, the web page and the browser itself may become sluggish or freeze up entirely. Note that this discussion of browser and operating system behavior with respect to input handling and events is a broadly applicable generalization; details vary. Regard- less of variances, all browsers execute all JavaScript code in a page on a single thread (excepting the use of Web Workers, discussed later in this chapter), making the de- veloper practices advocated in this chapter completely applicable. What Is Fast Enough? It’s fine to say that code needs to execute “as fast as possible,” but sometimes code needs to do things that simply take time. For instance, encryption algorithms, complex graphics rendering, and image manipulation are examples of computations that are time-consuming to perform, regardless of how much effort a developer puts forth to make them “as fast as possible.” However, as Doug mentioned in Chapter 1, developers seeking to create responsive, high-performance web sites can’t—and shouldn’t—go about achieving that goal by optimizing every single piece of code as they write it. The opposite is true: a developer should optimize only what isn’t fast enough. It is therefore vital to define exactly what is “fast enough” in this context. Fortunately, that’s already been done for us. Jakob Nielsen is a well-known and well-regarded expert in the field of web usability; the following quote* addresses the issue of “fast enough”: The response time guidelines for web-based applications are the same as for all other applications. These guidelines have been the same for 37 years now, so they are also not likely to change with whatever implementation technology comes next. 0.1 second: Limit for users feeling that they are directly manipulating objects in the UI. For example, this is the limit from the time the user selects a column in a table until that column should highlight or otherwise give feedback that it’s selected. Ideally, this would also be the response time for sorting the column—if so, users would feel that they are sorting the table. 1 second: Limit for users feeling that they are freely navigating the command space without having to unduly wait for the computer. A delay of 0.2–1.0 seconds does mean that users notice the delay and thus feel the computer is “working” on the command, as * http://www.useit.com/papers/responsetime.html What Is Fast Enough? | 9
  • 35. opposed to having the command be a direct effect of the users’ actions. Example: If sorting a table according to the selected column can’t be done in 0.1 seconds, it certainly has to be done in 1 second, or users will feel that the UI is sluggish and will lose the sense of “flow” in performing their task. For delays of more than 1 second, indicate to the user that the computer is working on the problem, for example by changing the shape of the cursor. 10 seconds: Limit for users keeping their attention on the task. Anything slower than 10 seconds needs a percent-done indicator as well as a clearly signposted way for the user to interrupt the operation. Assume that users will need to reorient themselves when they return to the UI after a delay of more than 10 seconds. Delays of longer than 10 seconds are only acceptable during natural breaks in the user’s work, for example when switching tasks. In other words, if your JavaScript code takes longer than 0.1 seconds to execute, your page won’t have that slick, snappy feel; if it takes longer than 1 second, the application feels sluggish; longer than 10 seconds, and the user will be extremely frustrated. These are the definitive guidelines to use for defining “fast enough.” Measuring Latency Now that you know the threshold for fast enough, the next step is to explore how you can measure the speed of JavaScript execution to determine whether it falls outside the ranges mentioned earlier (we’ll leave it to you to determine just how fast you wish your page to be; we aim to keep all interface latency smaller than 0.1 seconds). The easiest, most straightforward, and probably least precise way to measure latency is via human observation; simply use the application on your target platforms and ensure that performance is adequate. Since ensuring adequate human interface per- formance is only about pleasing humans, this is actually a fine way to perform such measurements (obviously, few humans will be able to quantify delays reliably in terms of precise whole or fractional second measurements; falling back to coarser categori- zations such as “snappy,” “sluggish,” “adequate,” and so on does the job). However, if you desire more precise measurements, there are two options you can choose: manual code instrumentation (logging) or automated code instrumentation (profiling). Manual code instrumentation is really straightforward. Let’s say you have an event handler registered on your page, as in: <div onclick="myJavaScriptFunction()"> ... </div> A simple way to add manual instrumentation would be to locate the definition of myJavaScriptFunction() and add timing to the function: function myJavaScriptFunction() { var start = new Date().getMilliseconds(); // some expensive code is here 10 | Chapter 2: Creating Responsive Web Applications
  • 36. var stop = new Date().getMilliseconds(); var executionTime = stop - start; alert("myJavaScriptFunction() executed in " + executionTime + " milliseconds"); } The preceding code will produce a pop-up dialog that displays the execution time; one millisecond represents 1/1,000 of a second, so 100 milliseconds represent the 0.1- second “snappiness” threshold mentioned earlier. Many browsers offer a built-in instance named console that provides a log() function (Firefox makes this available with the popular Firebug plug-in); we greatly prefer console.log() to alert(). There are tools to perform an automated measurement of code execution time, but such tools are typically used for a different purpose. Instead of being used to determine the precise execution duration of a function, such tools—called profilers—are usually used to determine the relative amount of time spent executing a set of functions; that is, they are used to find the bottleneck or slowest-running chunks of code. The popular Firebug extension for Firefox includes a JavaScript code profiler; it gen- erates output such as that shown in Figure 2-3. Figure 2-3. Firebug’s profiler The “Time” column represents the total amount of time the JavaScript interpreter spent inside a given function during the period of profiling. Often, a function invokes other Measuring Latency | 11
  • 37. functions; the “Own Time” column represents the amount of time spent inside a spe- cific function and not any other functions that it may have invoked. Whileyoumightthinktheseandtheothertemporal-relatedcolumnsrepresentaprecise measurement of function execution time, it turns out that profilers are subject to some- thing like the observer effect in physics: the act of observing the performance of code modifies the performance of the code. Profilers can take two basic strategies representing a basic trade-off: either they can intrude on the code being measured by adding special code to collect performance statistics (basically automating the creation of code as in the previous listing), or they can passively monitor the runtime by checking what piece of code is being executed at a particular moment in time. Of these two approaches, the latter does less to distort the performance of the code being profiled, but at the cost of lower-quality data. Firebug subjects results to a further distortion because its profiler executes inside Fire- fox’s own process, which creates the potential for it to rob the code it is measuring of performance. Nevertheless, the “Percent” column of Firebug’s output demonstrates the power of measuring relative execution time: you can perform a high-level task in your page’s interface (e.g., click the Send button) and then check Firebug’s profiler to see which functions spent the most time executing, and focus your optimization efforts on those. When Latency Goes Bad It turns out that if your JavaScript code ties up the browser thread for a particularly long time, most browsers will intervene and give the user the opportunity to interrupt your code. There is no standard behavior governing how browsers make the determination to give the user this opportunity. (For details on individual browser behavior, see http://www.nczonline.net/blog/2009/01/05/what-determines-that-a-script -is-long-running/.) The lesson is simple: don’t introduce potentially long-running, poorly performing code into your web page. Threading Once you’ve identified code that performs inadequately, of course the next step is to go about optimizing it. However, sometimes the task to perform is simply expensive and cannot be magically optimized to take less time. Are such scenarios fated to bring sluggish horror to a user interface? Will no solution emerge to keep our users happy? The traditional solution in such cases is to use threads to push such expensive code off the thread used to interact with the user. In our scenario, this would let the browser continue to process events from the event queue and keep the interface responsive while the long-running code merrily executes on a different thread (and the operating system 12 | Chapter 2: Creating Responsive Web Applications
  • 38. takes responsibility for making sure that both the browser user interface thread and the background thread equitably share the computer’s resources). However, JavaScript doesn’t support threads, so there’s no way for JavaScript code to create a background thread to execute expensive code. Further, this isn’t likely to change anytime soon. Brendan Eich, the creator of JavaScript and Mozilla’s chief technical officer, has made his position on this issue clear:† You must be [as tall as an NBA player] to hack on threaded systems, and that means most programmers should run away crying. But they don’t. Instead, as with most other sharp tools, the temptation is to show how big one is by picking up the nearest single- threaded code and jamming it into a multi-threaded embedding, or tempting race- condition fate otherwise. Occasionally the results are infamous, but too often, with only virtual fingers and limbs lost, no one learns. Threads violate abstractions six ways to Sunday. Mainly by creating race conditions, deadlock hazards, and pessimistic locking overhead. And still they don’t scale up to handle the megacore teraflop future. So my default answer to questions such as, “When will you add threads to JavaScript?” is: “over your dead body!” Given Brendan’s influence in the industry and on the future of JavaScript (which is considerable), and the broad degree to which this position is shared, it is safe to say that threads will not be coming to JavaScript anytime soon. However, there are alternatives. The basic problem with threads is that different threads can have access to and modify the same variables. This causes all sorts of problems when Thread A modifies variables that Thread B is actively modifying, and so on. You might think these sorts of issues could be kept straight by decent programmers, but it turns out that, as Brendan said, even the best of us make pretty horrible mistakes in this department. Ensuring Responsiveness What’s needed is a way to have the benefit of threads—tasks executing in parallel— without the hazards of the threads getting into each other’s business. Google imple- mented just such an API in its popular Gears browser plug-in: the WorkerPool API. It essentially allows the main browser JavaScript thread to create background “workers” that receive some simple “message” (i.e., standalone state, not references to shared variables) from the browser thread when they are kicked off and return a message upon completion. † http://weblogs.mozillazine.org/roadmap/archives/2007/02/threads_suck.html Ensuring Responsiveness | 13
  • 39. Experience with this API in Gears has led many browsers (e.g., Safari 4, Firefox 3.1) to implement support for “workers” natively based on a common API defined in the HTML 5 specification. This feature is known as “Web Workers.” Web Workers Let’s consider how to use the Web Worker API to decrypt a value. The following listing shows how to create and kick off a worker: // create and begin execution of the worker var worker = new Worker("js/decrypt.js"); // register an event handler to be executed when the worker // sends the main thread a message worker.onmessage = function(e) { alert("The decrypted value is " + e.data); } // send a message to the worker, in this case the value to decrypt worker.postMessage(getValueToDecrypt()); Now let’s take a look at the hypothetical contents of js/decrypt.js: // register a handler to receive messages from the main thread onmessage = function(e) { // get the data passed to us var valueToDecrypt = e.data; // TODO: implement decryption here // return the value to the main thread postMessage(decryptedValue); } Any potentially expensive (i.e., long-running) JavaScript operations that your page performs should be delegated to workers, as that will keep your application running lickety-split. Gears If you find yourself supporting a browser that doesn’t support the Web Worker API, there are a few alternatives. We mentioned Google’s Gears plug-in in the preceding section; you can use the Gears plug-in to bring something very much like Web Workers to Internet Explorer, to older versions of Firefox, and to older versions of Safari. The Gears worker API is similar but not identical to the Web Worker API. Here are the previous two code listings converted to the Gears API, starting with the code executed on the main thread to spawn a worker: 14 | Chapter 2: Creating Responsive Web Applications
  • 40. // create a worker pool, which spawns workers var workerPool = google.gears.factory.create('beta.workerpool'); // register the event handler that receives the message from the worker workerPool.onmessage = function(ignore1, ignore2, e) { alert("The decrypted value is + " e.body); } // create a worker var workerId = workerPool.createWorkerFromUrl("js/decrypt.js"); // send a message to the worker workerPool.sendMessage(getValueToDecrypt(), workerId); And here is the Gears version of js/decrypt.js: var workerPool = google.gears.workerPool; workerPool.onmessage = function(ignore1, ignore2, e) { // get the data passed to us var valueToDecrypt = e.body; // TODO: implement decryption here // return the value to the main thread workerPool.sendMessage(decryptedValue, e.sender); } More on Gears It is interesting to note some of the history of the Gears Worker Pool because it came from a very practical place. The Gears plug-in was built by a team at Google that was trying to push the browser to do more than it currently was able (this was before Google Chrome—but even with Chrome, Google wants as many users as possible to do great things with its web applications). Imagine if you wanted to build Gmail Offline; what would you need? First, you’d need a way to cache documents locally and to have an intercept so that when the browser tries to access http://mail.google.com/, it gets the page back instead of a message stating that you are offline. Second, it needs a way to store your email, both new and old. This could be done in many forms, but since SQLite is well known and already in most new browsers and bundled in many operating systems, why not use that? Here’s where the problem lies. We have been talking about the issues with a single-threaded browser. Now imagine operations such as writing new messages to the database or performing long queries. We can’t freeze the UI while the database does its work—the latency could be enor- mous! The Gears team needed a way to get around this. Since the Gears plug-in can do whatever it wants, it can easily work around the lack of threads in JavaScript. But since the need for concurrency is a general problem, why not give this ability to the outside world? Hence the “Worker Pool” API, which led to the HTML 5 standard “Web Workers.” Ensuring Responsiveness | 15
  • 41. The two APIs look subtly different, but this is because Web Workers is sort of like version 2.0 of the pioneering Gears API; Gears should support the standard API soon. There are already “shim” libraries that bridge the existing Gears API and the standard Web Worker API, and these shims can be used to work even without Gears or Web Workers (by using setTimeout(), described in this chapter). Timers Another approach, common before Gears and Web Workers, was simply to split up long-running operations into separate chunks and use JavaScript timers to control the execution. For example: var functionState = {}; function expensiveOperation() { var startTime = new Date().getMilliseconds(); while ((new Date().getMilliseconds() - startTime) < 100) { // TODO: implement expensive operation in such a way // that it performs work in iterative chunks that complete // in less than 100 ms and shove state in "functionState" // outside this function; good luck with that ;-) } if (!functionState.isFinished) { // re-enter expensiveOperation 10 ms after exiting; experiment // with larger values to strike the right balance between UI // responsiveness and performance setTimeout(expensiveOperation(), 10); } } Splitting up the operation in the manner just illustrated will result in a responsive in- terface, but as the comment in the listing indicates, it may not be straightforward (or even feasible) to structure the operation in that way. See “Yielding Using Timers” on page 103 for more details on using setTimeout() in this manner. There’s another fundamental issue with this approach. Most modern computers have multiple “cores,” which means that they have the ability to execute multiple threads in a truly concurrent fashion (whereas previous computers have only emulated concur- rency through fast task switching). Implementing task switching manually via Java- Script as we’ve done in the listing can’t take advantage of such architectures; you are therefore leaving processing power on the table by forcing one of the cores to do all of the processing. Thus, it is possible to perform long-running operations on the browser’s main thread and maintain a responsive interface, but it’s easier and more efficient to use workers. 16 | Chapter 2: Creating Responsive Web Applications
  • 42. XMLHttpRequest A discussion of threading wouldn’t be complete without touching briefly on the famed enabler of the Ajax revolution: XMLHttpRequest, or “XHR” for short. Using XHR, a web page may send a message and receive a response entirely from the JavaScript environ- ment, a feat that enables rich interactivity without loading new pages. XHR has two basic execution modes: synchronous and asynchronous. In the asyn- chronous mode, XHR is essentially a Web Worker but with a specialized API; indeed, coupled with other features of the in-progress HTML 5 specification, you can re-create the functionality of XHR with a worker. In the synchronous mode, XHR acts as though it performs all of its work on the browser’s main thread and will therefore introduce user interface latency that lasts as long as XHR takes to send its request and parse the response from the server. Therefore, never use XHR in synchronous mode, as it can lead to unpredictable user interface latency well outside of tolerable ranges. Effects of Memory Use on Response Time There’s another key aspect to creating responsive web pages: memory management. Like many modern high-level languages that abstract away low-level memory manage- ment, most JavaScript runtimes implement garbage collection (or “GC” for short). Garbage collection can be a magical thing, relieving developers from tedious details that feel more like accounting than programming. However, automatic memory management comes with a cost. All but the most sophisticated of GC implementations “stop the world” when they perform their col- lections; that is, they freeze the entire runtime (including what we’ve been calling the main browser JavaScript thread) while they walk the entire “heap” of created objects, searching for those that are no longer being used and are therefore eligible for recycling into unused memory. For most applications, GC is truly transparent; the runtime is frozen for short enough periods of time that it escapes the user’s attention entirely. However, as an application’s memory footprint increases in size, the time required to walk through the entire heap searching for objects that are no longer in use grows and can eventually reach levels that a user does notice. When this occurs, the application begins to be intermittently sluggish on somewhat regular intervals; as the problem gets worse, the entire browser may freeze on these intervals. Both cases lead to a frustrating user experience. Most modern platforms provide sophisticated tools that enable you to monitor the performance of the runtime’s GC process and to view the current set of objects on the heap in order to diagnose GC-related problems. Unfortunately, JavaScript runtimes don’t fall into that category. To make matters worse, no tools exist that can inform developers when collections occur or how much time they are spending performing Ensuring Responsiveness | 17
  • 43. their work; such tools would be very helpful to verify that observed latency is related to GC. This tool gap is a serious detriment toward the development of large-scale browser- hosted JavaScript applications. Meanwhile, developers must guess whether GC is responsible for UI delays. Virtual Memory There is another danger associated with memory: paging. Operating systems have two classes of memory they make available to applications: physical and virtual. Physical memory is mapped to extremely fast RAM chips in the underlying computer; virtual memory is mapped to a much slower mass storage device (e.g., hard drive) that makes up for its relative pokiness with much larger available storage space. If your web page’s memory requirements grow sufficiently large, you may force the operating system to start paging, an extremely slow process whereby other processes are forced to relinquish their real memory to make room for the browser’s increased appetite. The term paging is used because all modern operating systems organize mem- ory into individual pages, the term used to describe the smallest unit of memory that is mapped to either real or virtual memory. When paging occurs, pages are transferred from real to virtual memory (i.e., from RAM to a hard drive) or vice versa. The performance degradation caused by paging is a bit different from GC pauses; pag- ing results in a general, pervasive sluggishness whereas GC pauses tend to manifest themselves as discrete, individual pauses that occur in intervals—though the lengths of the pauses grow over time. Regardless of their differences, either one of these prob- lems represents significant threats to your goal of creating a responsive user interface. Troubleshooting Memory Issues As we mentioned earlier, we know of no good memory troubleshooting tools for browser-hosted JavaScript applications. The state of the art is to observe the memory footprint of the browser process (see the section “Measuring Memory Use” at http:// blog.pavlov.net/2008/03/11/firefox-3-memory-usage/ for details on how to measure process memory usage in Windows and OS X), and if it grows larger than is tolerable during the course of your application, check whether your code has any opportunities for memory usage optimizations. Once you’ve determined that you have a memory problem, you should look for op- portunities to clean up after yourself where you haven’t yet done so. You can do this in two ways: • Use the delete keyword to remove JavaScript objects that are no longer needed from memory. • Remove nodes that are no longer necessary from the web page DOM. 18 | Chapter 2: Creating Responsive Web Applications
  • 44. The following code listing demonstrates how to perform both of these tasks: var page = { address: "http://some/url" }; page.contents = getContents(page.address); ... // later, the contents are no longer necessary delete page.contents; ... var nodeToDelete = document.getElementById("redundant"); // remove the node from the DOM (which can only be done via // call to removeChild() from parent node) and // simultaneously delete the node from memory delete nodeToDelete.parent.removeChild(nodeToDelete); Obviously, there is significant room for improvement in the area of memory usage optimization for web pages. At Mozilla, we are currently developing tools to address this problem. In fact, by the time you read this, you should be able to find one or more such tools by visiting http://labs.mozilla.com. Summary Ajax ushered in a new era of long-running, JavaScript-centric web pages. Such web pages are really browser-hosted applications and are subject to the same user interface guidelines of any other application. It is vital that such applications keep the user interface responsive by minimizing operations performed on the main application thread. Web Workers are a powerful new tool that can be used to offload complex operations that threaten UI responsiveness. The Gears plug-in and JavaScript timers can be used when Web Workers are unavailable. Poorly managed memory can lead to UI performance problems. While there’s a short- age of good tools to troubleshoot memory problems, developers can generally observe browser memory usage and take steps to minimize their application’s memory footprint when problems arise. The good news is that memory troubleshooting tools are in development. Summary | 19
  • 46. CHAPTER 3 Splitting the Initial Payload The growing adoption of Ajax and DHTML (Dynamic HTML) means today’s web pages have more JavaScript and CSS than ever before. Web applications are becoming more like desktop applications, and just like desktop applications, a large percentage of the application code isn’t used at startup. Advanced desktop applications have a plug-in architecture that allows for modules to be loaded dynamically, a practice that many Web 2.0 applications could benefit from. In this chapter I show some popular Web 2.0 applications that load too much code upfront, and I discuss approaches for making pages load more dynamically. Kitchen Sink Facebook has 14 external scripts totaling 786 KB uncompressed.* Figuring out how much of that JavaScript is necessary for the initial page to render is difficult to do, even for a core Facebook frontend engineer. Some of those 14 external scripts are critical to rendering the initial page, but others were included because they support Ajax and DHTML functionality, such as the drop-down menus and the Comment and Like fea- tures shown in Figure 3-1. It’s critical to render a web page as quickly as possible. Doing so engages the user and creates a responsive experience for her. Imagine if the Facebook JavaScript could be split into two parts: what’s needed to render the initial page, and everything else. Rather than bog down the user’s first impression with “everything else,” the initial JavaScript download should include only what’s necessary for the initial rendering. The remaining JavaScript payload can be loaded later. * Fourteen scripts are downloaded when logged-in users visit this page. If the user is not logged in, fewer scripts are used. 21
  • 47. Figure 3-1. Facebook Ajax and DHTML features This raises several questions: • How much does this save? • How do you find where to split the code? • What about race conditions? • How do you download “everything else” later? The first three questions are tackled in this chapter. How to load “everything else” is the topic of Chapter 4. Savings from Splitting It turns out that Facebook executes only 9% of the downloaded JavaScript functions by the time the onload event is called. This is computed by using Firebug’s JavaScript profiler to count all the functions executed up to the onload event.† The counting stops at the onload event because functionality needed after this point can, and should, be downloaded after the initial page has rendered. I call this a post-onload download. (See Chapter 4 for various lazy-loading techniques.) Table 3-1 shows the percentage of functions downloaded that are not executed before the onload event for 10 top U.S. web sites. On average, 75% of the functions † Firebug is the preeminent web development tool, available at http://getfirebug.com/. 22 | Chapter 3: Splitting the Initial Payload
  • 48. downloaded are not executed during the initial rendering of the page. Thus, if down- loading of these unexecuted functions was deferred, the size of the initial JavaScript download would be dramatically reduced. Admittedly, the 75% estimate might be exaggerated; some of the unexecuted functions might be required for error handling or other special conditions. The estimate is still useful to illustrate the point that much of the JavaScript downloaded initially could be deferred. The average total amount of JavaScript is 252 KB uncompressed. This per- centage is in terms of function count, not size. If we assume a constant function size, 75% represents an average 189 KB that doesn’t have to be downloaded until after the onload event, making the initial page render more quickly. Table 3-1. Percentage of JavaScript functions executed before onload Web site % of functions not executed JavaScript size uncompressed http://www.aol.com/ 71% 115 KB http://www.ebay.com/ 56% 183 KB http://www.facebook.com/ 91% 786 KB http://www.google.com/search?q=flowers 56% 15 KB http://search.live.com/results.aspx?q=flowers 75% 17 KB http://www.msn.com/ 69% 131 KB http://www.myspace.com/ 87% 297 KB http://en.wikipedia.org/wiki/Flowers 79% 114 KB http://www.yahoo.com/ 88% 321 KB http://www.youtube.com/ 84% 240 KB Finding the Split Firebug’s JavaScript profiler shows the names of all the functions that were executed by the time of the onload event. This list can be used to manually split the JavaScript code into one file loaded as part of the initial page rendering and another file to be downloaded later. However, because some of the unused functions may still be nec- essary for error-handling and other conditional code paths, splitting the code into an initialdownloadthatiscompletewithoutundefinedsymbolsisachallenge.JavaScript’s higher-order features, including function scoping and eval, make the challenge even more complicated. Doloto is a system developed by Microsoft Research for automatically splitting Java- Script into clusters. The first cluster contains the functions needed for initializing the web page. The remaining clusters are loaded on demand the first time the missing code needs to execute, or they are lazy-loaded after the initial flurry of JavaScript activity is over. When applied to Gmail, Live Maps, Redfin, MySpace, and Netflix, Doloto re- Finding the Split | 23
  • 49. duced the initial JavaScript download size by up to 50% and reduced the application load time by 20% to 40%. Doloto’s decisions about where to split the code are based on a training phase and can result in the JavaScript being split into multiple downloads. For many web applications, it is preferable to define a single split at the onload event, after which the remaining JavaScript is immediately downloaded using the nonblocking techniques described in Chapter 4. Waiting to start the additional downloads on demand after the user has pulled down a menu or clicked on a page element forces the user to wait for the addi- tional JavaScript to arrive. This wait can be avoided if all the additional JavaScript is downloaded after the initial page rendering. Until Doloto or other systems are publicly available, developers need to split their code manually. The following section discusses some of the issues to keep in mind when doing this. Undefined Symbols and Race Conditions The challenge in splitting your JavaScript code is to avoid undefined symbols. This problem arises if the JavaScript being executed references a symbol that has, mistak- enly, been relegated to a later download. In the Facebook example, for instance, I suggest that the JavaScript for drop-down menus should be loaded later. But if the drop-down menu is displayed before the required JavaScript is downloaded, there’s a window in which the user can click on the drop-down menu and the required JavaScript won’t be available. My suggestion would then have created a race condition where the JavaScript is racing to download while the user is racing to click the menu. In most cases, the JavaScript will win the race, but there is a definite possibility that the user may click first and experience an undefined symbol error when the (yet to be down- loaded) drop-down menu function is called. In a situation where the delayed code is associated with a UI element, the problem can be avoided by changing the element’s appearance. In this case, the menu could contain a “Loading…” spinner, alerting the user that the functionality is not yet available. Another option is to attach handlers to UI elements in the lazy-loaded code. In this example, the menu would be rendered initially as static text. Clicking on it would not execute any JavaScript. The lazy-loaded code would both contain the menu function- ality and would attach that behavior to the menu using attachEvent in Internet Explorer and addEventListener in all other browsers.‡ In situations where the delayed code is not associated with a UI element, the solution to this problem is to use stub functions. A stub function is a function with the same name as the original function but with an empty function body or temporary code in place of the original. The previous section described Doloto’s ability to download additional JavaScript modules on demand. Doloto implements this on-demand feature ‡ See http://www.quirksmode.org/js/events_advanced.html for more information. 24 | Chapter 3: Splitting the Initial Payload
  • 50. by inserting stub functions in the initial download that, when invoked, dynamically download additional JavaScript code. When the additional JavaScript code is down- loaded, the original function definitions overwrite the stub functions. A simpler approach is to include an empty stub function for each function that is ref- erenced but relegated to the later download. If necessary, the stub function should return a stub value, such as an empty string. If the user tries to invoke a DHTML feature before the full function implementation is downloaded, nothing happens. A slightly more advanced solution has each stub function record the user’s requests and invokes those actions when the lazy-loaded JavaScript arrives. Case Study: Google Calendar A good example of splitting the initial payload is Google Calendar. Figure 3-2 shows the HTTP requests that are made when Google Calendar is requested. I call these charts HTTP waterfall charts. Each horizontal bar represents one request. The resource type is shown on the left. The horizontal axis represents time, so the placement of the bars shows at what point during page load each resource was requested and received. Figure 3-2. Google Calendar HTTP waterfall chart Google Calendar requests five scripts totaling 330 KB uncompressed. The payload is split into an initial script of 152 KB that is requested early (the third bar from the top). The blocking behavior of this script is mitigated by the fact that it contains less than half of the total JavaScript. The rest of the JavaScript payload is requested last, after the page has been allowed to render. By splitting their JavaScript, the Google Calendar team creates a page that renders more quickly than it would have if all of the JavaScript were loaded in one file. Splitting a web application’s JavaScript is not a simple task. It requires determining the functions needed for initial rendering, finding all required code dependencies, stubbing out other functions, and lazy-loading the remaining JavaScript. Further automation for these tasks is needed. Microsoft’s Doloto project describes such a system, but as of this writ- ing, it’s not available publicly. Until tools such as this are made available, developers will have to roll up their sleeves and do the heavy lifting themselves. Case Study: Google Calendar | 25
  • 51. This chapter has focused on splitting JavaScript, but splitting CSS stylesheets is also beneficial. The savings are less than those gained by splitting JavaScript because the total size of stylesheets is typically less than JavaScript, and downloading CSS does not have the blocking characteristics that downloading JavaScript has.§ This is another opportunity for further research and tool development. § Firefox 2 is the one exception. 26 | Chapter 3: Splitting the Initial Payload
  • 52. CHAPTER 4 Loading Scripts Without Blocking SCRIPT tags have a negative impact on page performance because of their blocking behavior. While scripts are being downloaded and executed, most browsers won’t download anything else. There are times when it’s necessary to have this blocking, but it’s important to identify situations when JavaScript can be loaded independent of the rest of the page. When these opportunities arise, we want to load the JavaScript in such a way that it does not block other downloads. Luckily, there are several techniques for doing this that make pages load faster. This chapter explains these techniques, compares how they affect the browser and performance, and describes the circumstances that make one approach preferred over another. Scripts Block JavaScript is included in a web page as an inline script or an external script. An inline script includes all the JavaScript in the HTML document itself using the SCRIPT tag: <script> function displayMessage(msg) { alert(msg); } </script> External scripts pull in the JavaScript from a separate file using the SCRIPT SRC attribute: <script src='A.js'></script> The SRC attribute specifies the URL of the external file that needs to be loaded. The browser reads the script file from the cache, if available, or makes an HTTP request to fetch the script. Normally, most browsers download components in parallel, but that’s not the case for external scripts. When the browser starts downloading an external script, it won’t start any additional downloads until the script has been completely downloaded, parsed, and executed. (Any downloads that were already in progress are not blocked.) 27
  • 53. Figure 4-1 shows the HTTP requests for the Scripts Block Downloads example.* Scripts Block Downloads http://stevesouders.com/cuzillion/?ex=10008&title=Scripts+Block+Downloads This page has two scripts at the top, A.js and B.js, followed by an image, a stylesheet, and an iframe. The scripts are each programmed to take one second to download and one second to execute. The white gaps in the HTTP profile indicate where the scripts are executed. This shows that while scripts are being downloaded and executed, all other downloads are blocked. Only after the scripts have finished are the image, style- sheet, and iframe merrily downloaded in parallel. Figure 4-1. Scripts block parallel downloads The reason browsers block while downloading and executing a script is that the script may make changes to the page or JavaScript namespace that affect whatever follows. The typical example cited is when A.js uses document.write to alter the page. Another example is when A.js is a prerequisite for B.js. The developer is guaranteed that scripts are executed in the order in which they appear in the HTML document so that A.js is downloaded and executed before B.js. Without this guarantee, race conditions could result in JavaScript errors if B.js is downloaded and executed before A.js. Although it’s clear that scripts must be executed sequentially, there’s no reason they have to be downloaded sequentially. That’s where Internet Explorer 8 comes in. The behavior shown in Figure 4-1 is true for most browsers, including Firefox 3.0 and earlier and Internet Explorer 7 and earlier. However, Internet Explorer 8’s download profile, shown in Figure 4-2, is different. Internet Explorer 8 is the first browser that supports downloading scripts in parallel. Figure 4-2. Internet Explorer 8 downloads scripts without blocking * This and other examples are generated from Cuzillion, a tool I built specifically for this chapter. See the Appendix for more information about Cuzillion. 28 | Chapter 4: Loading Scripts Without Blocking
  • 54. The ability of Internet Explorer 8 to download scripts in parallel makes pages load faster, but as shown in Figure 4-2, it doesn’t entirely solve the blocking problem. It is true that A.js and B.js are downloaded in parallel, but the image and iframe are still blocked until the scripts are downloaded and executed. Safari 4 and Chrome 2 are similar—they download scripts in parallel, but block other resources that follow.† What we really want is to have scripts downloaded in parallel with all the other com- ponents in the page. And we want this in all browsers. The techniques discussed in the next section explain how to do just that. Making Scripts Play Nice There are several techniques for downloading external scripts without having your page suffer from their blocking behavior. One technique I don’t suggest doing is inlining all of your JavaScript. In a few situations (home pages, small amounts of JavaScript), inlining your JavaScript is acceptable, but generally it’s better to serve your JavaScript in external files because of the page size and caching benefits derived. (For more information about these trade-offs, see High Performance Web Sites, “Rule 8: Make JavaScript and CSS External.”) The techniques listed here provide the benefits of external scripts without the slow- downs imposed from blocking: • XHR Eval • XHR Injection • Script in Iframe • Script DOM Element • Script Defer • document.write Script Tag The following sections describe each of these techniques in more detail, followed by a comparison of how they affect the browser and which technique is best under different circumstances. XHR Eval In this technique, an XMLHttpRequest (XHR) retrieves the JavaScript from the server. When the response is complete, the content is executed using the eval command as shown in this example page. † As of this writing, Firefox does not yet support parallel script downloads, but that is expected soon. Making Scripts Play Nice | 29
  • 55. Another Random Document on Scribd Without Any Related Topics
  • 56. Eylau. Combat de Ziegelhoff, livré le 7 février au soir. Combat dans l'intérieur de la ville d'Eylau. carte no 40), et devant lequel on arrive au sortir des bois dont la route de Landsberg à Eylau est couverte. Les généraux Bagowout et Barklay de Tolly étaient en position sur ce plateau, prêts à renouveler le combat de la veille. Le général Benningsen, sentant bien qu'il était serré de trop près pour ne pas être amené à une bataille, tenait beaucoup à occuper ce plateau, sur lequel on pouvait recevoir avec avantage l'armée française débouchant de la région boisée. Il tenait de plus à protéger l'arrivée de sa grosse artillerie, à laquelle il avait ordonné de faire un détour. Par tous ces motifs sa résistance sur ce point devait être opiniâtre. La cavalerie de Murat, secondée par l'infanterie du maréchal Soult, déboucha des bois avec sa hardiesse accoutumée, et s'avança sur le plateau de Ziegelhoff. La brigade Levasseur, composée des 46e et 28e régiments de ligne, la suivit résolument, pendant que la brigade Viviès, filant à droite, essayait à travers des lacs gelés de tourner la position. La brigade Levasseur, que le feu d'une nombreuse artillerie excitait à brusquer l'attaque, hâta le pas. Une première ligne d'infanterie ennemie fut d'abord repoussée à la baïonnette. Mais la cavalerie russe, chargeant à propos sur la gauche de la brigade, renversa le 28e , avant qu'il eût le temps de se former en carré. Elle sabra beaucoup de nos fantassins, et enleva une aigle. Le combat bientôt rétabli, se continua de part et d'autre avec acharnement. Cependant la brigade Viviès ayant débordé la position des Russes, ceux- ci la quittèrent pour se retirer dans la ville même d'Eylau. Le maréchal Soult y pénétra en même temps qu'eux. Napoléon ne voulait pas qu'on leur laissât la ville d'Eylau, pour le cas incertain, mais probable, d'une grande bataille. On entra donc baïonnette baissée dans Eylau. Les Russes s'y défendirent opiniâtrement de rue en rue. On tourna la ville, et on trouva une de leurs colonnes établie dans un cimetière, devenu fameux depuis par de terribles souvenirs, et qui était situé en dehors à droite. La
  • 57. Les Russes s'arrêtent le 7 au soir au delà d'Eylau, et paraissent disposés à livrer bataille. État de l'armée française la veille de la bataille d'Eylau. brigade Viviès emporta ce cimetière après un combat des plus rudes. Les Russes se replièrent au delà d'Eylau. De toutes les rencontres d'arrière-garde, celle-ci avait été la plus sanglante, et elle avait coûté au corps du maréchal Soult des pertes considérables. On se jeta un peu en désordre dans la ville d'Eylau, les soldats se dispersant pour vivre, et surprenant dans les maisons beaucoup de Russes qui n'avaient pas eu le temps de s'enfuir. La première opinion que conçut Murat, et qu'il transmit à Napoléon, c'est que les Russes, ayant perdu le point d'appui d'Eylau, iraient en chercher un plus éloigné. Cependant quelques officiers égarés dans cette mêlée, avaient aperçu les Russes établis un peu au delà d'Eylau, et allumant leurs feux de bivouac pour y passer la nuit. Cette observation, confirmée par de nouveaux rapports, ne permit aucun doute sur l'importance de la journée du lendemain 8 février; et en effet, elle en a acquis une qui lui assure l'immortalité dans les siècles. Il devenait évident que les Russes, s'arrêtant cette fois après le combat du soir, et n'employant pas la nuit à marcher, étaient résolus à engager le lendemain une action générale. L'armée française était harassée de fatigue, fort réduite en nombre par la rapidité des marches, travaillée par la faim, et transie de froid. Mais il fallait livrer bataille, et ce n'était pas en semblable occasion, que soldats, officiers, généraux, avaient coutume de sentir leurs souffrances. Napoléon se hâta de dépêcher le soir même plusieurs officiers aux maréchaux Davout et Ney pour les ramener, l'un à sa droite, l'autre à sa gauche. Le maréchal Davout avait continué de suivre l'Alle jusqu'à Bartenstein, et il ne se trouvait plus qu'à trois ou quatre lieues. Il répondit qu'il arriverait dès la pointe du jour vers la droite d'Eylau (droite de l'armée française), prêt à donner dans le flanc des Russes.
  • 58. Effectif des corps composant l'armée française à la bataille d'Eylau. Le maréchal Ney, qu'on avait dirigé sur la gauche, de façon à tenir les Prussiens à distance, et à pouvoir fondre sur Kœnigsberg dans le cas où les Russes se jetteraient derrière la Prégel, le maréchal Ney était en marche sur Kreutzbourg. On fit courir après lui, sans être aussi assuré de l'amener à temps sur le champ de bataille, qu'on l'était d'y voir paraître le maréchal Davout. Privée du corps de Ney, l'armée française s'élevait tout au plus à cinquante et quelques mille hommes, bien que les Russes l'aient portée à 80 mille dans leurs relations, et un historien français, ordinairement digne de foi, à 68[19]. Le corps du maréchal Davout, dont l'effectif présentait 26 mille hommes à Awerstaedt, sensiblement diminué par les combats livrés depuis, par les maladies, par la dernière marche de la Vistule à Eylau, par les détachements laissés sur la Narew, était fort de 15 mille hommes environ. Le corps du maréchal Soult, le plus nombreux de toute l'armée, très-réduit également par la dyssenterie, la marche, les combats d'arrière-garde, ne pouvait pas être évalué à plus de 16 ou 17 mille hommes. Celui du maréchal Augereau, affaibli d'une quantité de traînards et de maraudeurs qui s'étaient dispersés pour vivre, n'en comptait que 6 à 7 mille au bivouac d'Eylau, dans la soirée du 7 février. La garde, mieux traitée, plus retenue par la discipline, n'avait laissé personne en arrière. Toutefois elle ne s'élevait qu'à 6 mille hommes. Enfin la cavalerie de Murat, composée d'une division de cuirassiers et de trois divisions de dragons, ne présentait guère que 10 mille cavaliers dans le rang. C'était donc une force totale de 53 à 54 mille combattants, capables de tout, il est vrai, quoique accablés de fatigue, et épuisés par la faim. Si le maréchal Ney arrivait à temps, il devenait possible d'opposer 63 mille hommes à l'ennemi, tous présents au feu. Il ne fallait pas espérer de voir arriver le corps de Bernadotte, demeuré à une distance de trente lieues. Napoléon, qui pendant cette nuit dormit à peine trois ou quatre heures sur une chaise, dans la maison du maître de poste, plaça le
  • 59. Raisons qui décident le général Benningsen à livrer bataille. Force de l'armée russe. corps du maréchal Soult à Eylau même, partie dans l'intérieur, partie à droite et à gauche de la ville, le corps d'Augereau et la garde impériale un peu en arrière, toute la cavalerie sur les ailes, attendant qu'il fît jour pour arrêter ses dispositions. Le général Benningsen s'était enfin déterminé à livrer bataille. Il se trouvait en plaine, ou à peu près, terrain excellent pour ses fantassins, peu manœuvriers mais solides, et pour sa cavalerie qui était nombreuse. Sa grosse artillerie, à laquelle il avait fait faire un détour, pour qu'elle ne gênât pas ses mouvements, venait de le rejoindre. C'était un précieux renfort. De plus il était tellement poursuivi, qu'il se voyait forcé d'interrompre sa marche pour tenir tête aux Français. Il faut, à une armée qui bat en retraite, un peu d'avance, afin qu'elle puisse dormir et manger. Il faut aussi qu'elle n'ait pas l'ennemi trop près d'elle, car essuyer une attaque en route, le dos tourné, est la plus dangereuse manière de recevoir une bataille. Il est donc un moment où ce qu'il y a de plus sage est de choisir son terrain et de s'y arrêter pour combattre. C'est la résolution que prit le général Benningsen le 7 au soir. Il fit halte au delà d'Eylau, résolu à soutenir une lutte acharnée. Son armée, qui s'élevait à 78 ou 80 mille hommes, et à 90 mille avec les Prussiens, lors de la reprise des hostilités, avait fait des pertes assez notables dans les derniers combats, mais fort peu dans les marches, car une armée qui se retire sans être en déroute, est ralliée par l'ennemi qui la poursuit, tandis que l'armée poursuivante, n'ayant pas les mêmes motifs de se serrer, laisse toujours une partie de son effectif en arrière. En défalquant les pertes essuyées à Mohrungen, à Bergfried, à Waltersdorf, à Hoff, à Heilsberg, à Eylau même[20], on peut dire que l'armée du général Benningsen était réduite à 80 mille hommes environ, dont 72 mille Russes et 8 mille Prussiens. Ainsi en attendant l'arrivée du général Lestocq et du maréchal Ney, 72 mille Russes allaient combattre 54 mille Français. Les Russes avaient de plus une artillerie formidable, évaluée à 4 ou 500 bouches à feu. La nôtre montait tout au plus à 200, la garde comprise. Il est vrai qu'elle était
  • 60. Champ de bataille d'Eylau. Ordre de bataille adopté par les Russes. supérieure à toutes les artilleries de l'Europe, même à celle des Autrichiens. Le général Benningsen se décida donc à attaquer dès la pointe du jour. Le caractère de ses soldats était énergique, comme celui des soldats français, mais conduit par d'autres mobiles. Il n'y avait chez les Russes ni cette confiance dans le succès, ni cet amour de la gloire, qui se voyait chez les Français, mais un certain fanatisme d'obéissance, qui les portait à braver aveuglément la mort. Quant à la dose d'intelligence chez les uns et les autres, il n'est pas nécessaire d'en faire remarquer la différence. Depuis qu'on avait débouché sur Eylau, le pays se montrait uni et découvert. La petite ville d'Eylau, située sur une légère éminence, et surmontée d'une flèche gothique, était le seul point saillant du terrain. À droite de l'église, le sol, s'abaissant quelque peu, présentait un cimetière. En face, il se relevait sensiblement, et sur ce relèvement marqué de quelques mamelons, on apercevait les Russes en masse profonde. Plusieurs lacs, pourvus d'eau au printemps, desséchés en été, gelés en hiver, actuellement effacés par la neige, ne se distinguaient en aucune manière du reste de la plaine. À peine quelques granges réunies en hameaux, et des lignes de barrière servant à parquer le bétail, formaient-elles un point d'appui ou un obstacle, sur ce morne champ de bataille. Un ciel gris, fondant par intervalles en une neige épaisse, ajoutait sa tristesse à celle des lieux, tristesse qui saisit les yeux et les cœurs, dès que la naissance du jour, très-tardive en cette saison, eut rendu les objets visibles. Les Russes étaient rangés sur deux lignes, fort rapprochées l'une de l'autre, leur front couvert par trois cents bouches à feu, qui avaient été disposées sur les parties saillantes du terrain. En arrière, deux colonnes serrées, appuyant comme deux arcs-boutants cette double ligne de bataille, semblaient destinées à la soutenir, et à l'empêcher de plier sous le choc des Français. Une forte réserve d'artillerie était placée à quelque distance. La cavalerie se trouvait partie en arrière, partie sur les ailes. Les Cosaques, ordinairement
  • 61. Disposition opposée par Napoléon à celle des Russes. dispersés, tenaient cette fois au corps même de l'armée. Il était évident qu'à l'énergie, à la dextérité des Français, les Russes avaient voulu, sur ce terrain découvert, opposer une masse compacte, défendue sur son front par une nombreuse artillerie, fortement étayée par derrière, une véritable muraille enfin, lançant une pluie de feux. Napoléon, à cheval dès la pointe du jour, s'était établi de sa personne dans le cimetière à la droite d'Eylau. Là, protégé à peine par quelques arbres, il voyait parfaitement la position des Russes, lesquels, déjà en bataille, avaient ouvert le feu par une canonnade, qui devenait à chaque instant plus vive. On pouvait prévoir que le canon serait l'arme de cette journée terrible. Grâce à la position d'Eylau, qui s'allongeait en face des Russes, Napoléon pouvait donner moins de profondeur à sa ligne de bataille, moins de prise par conséquent aux coups de l'artillerie. Deux des divisions du maréchal Soult furent placées à Eylau, la division Legrand en avant et un peu à gauche, la division Leval partie à gauche de la ville, sur une éminence que surmontait un moulin, partie à droite au cimetière même. La troisième division du maréchal Soult, la division Saint-Hilaire, fut établie plus à droite encore, à une assez grande distance du cimetière, au village de Rothenen, qui formait le prolongement de la position d'Eylau. Dans l'intervalle qui séparait le village de Rothenen de la ville d'Eylau, intervalle laissé ouvert pour y faire déboucher le reste de l'armée, se tenait un peu en arrière le corps d'Augereau, rangé sur deux lignes, et formé des divisions Desjardins et Heudelet. Augereau, tourmenté de la fièvre, les yeux rouges et enflés, mais oubliant ses souffrances au bruit du canon, était monté à cheval pour se mettre à la tête de ses troupes. Plus en arrière de ce même débouché, venaient l'infanterie et la cavalerie de la garde impériale, les divisions de dragons et de cuirassiers, prêtes les unes et les autres à se présenter à l'ennemi par la même issue, et en attendant un peu abritées du canon par l'enfoncement du terrain. Enfin à l'extrême droite de ce champ de bataille, au delà et en avant de Rothenen, au
  • 62. La bataille d'Eylau commence par un violent combat d'artillerie. hameau de Serpallen, devait entrer en action le corps du maréchal Davout, de manière à donner dans le flanc des Russes. Napoléon étant donc sur un ordre mince, et sa ligne ayant l'avantage d'être couverte à gauche par les bâtiments d'Eylau, à droite par ceux de Rothenen, le combat d'artillerie par lequel il voulait démolir l'espèce de muraille que lui opposaient les Russes était beaucoup moins redoutable pour lui que pour eux. Il avait fait sortir des corps et mettre en bataille toutes les bouches à feu de l'armée, il y avait joint les quarante pièces de la garde, et il allait ainsi riposter à la formidable artillerie des Russes par une artillerie très-inférieure en nombre, mais très-supérieure en habileté. Les Russes avaient commencé le feu. Les Français leur avaient répondu presque aussitôt par une violente canonnade, exécutée à demi-portée de canon. La terre tremblait sous cette détonation épouvantable. Les artilleurs français, non- seulement plus adroits, mais tirant sur une masse vivante, qui leur servait de but, y exerçaient d'horribles ravages. Nos boulets emportaient des files entières. Les boulets des Russes, au contraire, lancés avec moins de justesse, et frappant sur des bâtiments, ne nous causaient pas un dommage égal à celui que l'ennemi éprouvait. Bientôt le feu prit à la ville d'Eylau, et au village de Rothenen. Les lueurs de l'incendie vinrent joindre leur horreur à l'horreur du carnage. Quoiqu'il tombât beaucoup moins de Français que de Russes, il en tombait beaucoup encore, surtout dans les rangs de la garde impériale, immobile dans le cimetière. Les projectiles, passant par-dessus la tête de Napoléon, et quelquefois bien près de lui, perçaient les murs de l'église ou brisaient les branches des arbres au pied desquels il s'était placé pour diriger la bataille. Cette canonnade durait depuis long-temps, et les deux armées la supportaient avec une tranquillité héroïque, ne faisant aucun mouvement, et se bornant à serrer les rangs à mesure que le canon
  • 63. Arrivée du maréchal Davout à Serpallen. y produisait des vides. Les Russes parurent les premiers éprouver une sorte d'impatience[21]. Désirant accélérer le résultat par la prise d'Eylau, ils s'ébranlèrent, pour enlever la position du moulin, située à la gauche de la ville. Une partie de leur droite se forma en colonne, et vint nous attaquer. La division Leval, composée des brigades Ferey et Viviès, la repoussa vaillamment, et par sa contenance ne permit pas aux Russes d'espérer un succès s'ils renouvelaient leurs efforts. Quant à Napoléon, il ne tentait rien de décisif, ne voulant pas compromettre, en le portant en avant, le corps du maréchal Soult, qui faisait bien assez de tenir Eylau sous une affreuse canonnade, ne voulant pas non plus hasarder ni la division Saint-Hilaire, ni le corps d'Augereau, contre le centre de l'ennemi, car c'eût été les exposer à se briser contre un rocher brûlant. Il attendait pour agir que le maréchal Davout, dont le corps arrivait sur la droite, se fit sentir dans le flanc des Russes. Ce lieutenant, exact autant qu'intrépide, était parvenu en effet au village de Serpallen. La division Friant marchait en tête. Elle déboucha la première, rencontra les Cosaques, qu'elle eut bientôt ramenés, et occupa le village de Serpallen par quelques compagnies d'infanterie légère. (Voir la carte no 40.) À peine était-elle établie dans le village et dans les terrains à droite, que l'une des masses de cavalerie qui étaient placées sur les ailes de l'armée russe, se détacha pour venir à elle. Le général Friant, usant avec intelligence et sang-froid des avantages que lui offrait le hasard des lieux, rangea les trois régiments dont se composait alors sa division, derrière les longues et solides barrières en bois employées à parquer les troupeaux. Abrité derrière ce retranchement naturel, il fusilla à bout portant les escadrons russes, et les força de se retirer. Ils se replièrent, mais ils revinrent bientôt, accompagnés d'une colonne de neuf à dix mille hommes d'infanterie. C'était l'une des deux colonnes serrées qui servaient d'arcs-boutants à la ligne de bataille des Russes, qui se portait maintenant à la gauche de cette
  • 64. Le corps du maréchal Davout ayant produit sur la gauche des ligne pour reprendre Serpallen. Le général Friant n'avait pas plus de cinq mille hommes à lui opposer. Toujours abrité derrière les barrières en bois dont il s'était couvert, et maître de se déployer sans craindre d'être chargé par la cavalerie, il accueillit les Russes par un feu si nourri et si bien dirigé, qu'il leur fit essuyer une perte considérable. Leurs escadrons ayant voulu le tourner, il forma le 33e en carré sur sa droite, et les arrêta par la contenance inébranlable de ses fantassins. Ne pouvant se servir de sa cavalerie, qui consistait en quelques chasseurs à cheval, il y suppléa par une nuée de tirailleurs, qui, profitant avec adresse des moindres accidents du terrain, allèrent fusiller les Russes sur leurs flancs, et les obligèrent à se retirer vers les hauteurs en arrière de Serpallen, entre Serpallen et Klein-Sausgarten. En se retirant sur ces hauteurs, les Russes se couvrirent par une nombreuse artillerie, dont le feu plongeant était malheureusement très-meurtrier. La division Morand, à son tour, était arrivée sur le champ de bataille. Le maréchal Davout s'emparant de la première brigade, celle du général Ricard, vint la placer au delà et à gauche de Serpallen, puis il disposa la seconde, composée du 51e et du 61e , à droite du village, de manière à soutenir ou la brigade Ricard, ou la division Friant. Celle-ci s'était portée à droite de Serpallen, vers Klein-Sausgarten. Dans ce même moment la division Gudin forçait le pas pour entrer en ligne. Ainsi les Russes, par le mouvement de notre droite, avaient été contraints de replier leur gauche, de Serpallen sur Klein-Sausgarten. L'effet attendu dans le flanc de l'armée ennemie était donc produit. Napoléon, de la position qu'il occupait, avait vu distinctement les réserves russes se diriger vers le corps du maréchal Davout. L'heure d'agir était venue, car si on n'intervenait pas, les Russes pouvaient se jeter en masse sur le maréchal Davout, et l'écraser. Napoléon donna sur-le-champ ses ordres. Il prescrivit à la division Saint-Hilaire, qui était à Rothenen, de se porter en avant, pour donner la main, vers Serpallen, à la division Morand. Il commanda aux deux divisions Desjardins et Heudelet du corps
  • 65. Russes l'effet attendu, Napoléon fait attaquer leur centre par la division Saint- Hilaire et le corps d'Augereau. Destruction presque totale d'Augereau, de déboucher par l'intervalle qui séparait Rothenen d'Eylau, de se lier à la division Saint-Hilaire, et toutes ensemble de former une ligne oblique du cimetière d'Eylau à Serpallen. Le résultat de ce mouvement devait être de culbuter les Russes, en renversant leur gauche sur leur centre, et d'abattre ainsi, en commençant par son extrémité, la longue muraille qu'on avait devant soi. Il était dix heures du matin. Le général Saint-Hilaire s'ébranla, quitta Rothenen, et se déploya obliquement dans la plaine, sous un terrible feu d'artillerie, sa droite à Serpallen, sa gauche vers le cimetière. Augereau s'ébranla presque en même temps, non sans un triste pressentiment du sort réservé à son corps d'armée, qu'il voyait exposé à se briser contre le centre des Russes, solidement appuyé à plusieurs mamelons. Tandis que le général Corbineau lui transmettait les ordres de l'Empereur, un boulet perça le flanc de ce brave officier, l'aîné d'une famille héroïque. Le maréchal Augereau se mit immédiatement en marche. Les deux divisions Desjardins et Heudelet débouchèrent entre Rothenen et le cimetière, en colonnes serrées, puis le défilé franchi, se formèrent en bataille, la première brigade de chaque division déployée, la seconde en carré. Tandis qu'elles s'avançaient, une rafale de vent et de neige vint frapper tout à coup la face des soldats et leur dérober la vue du champ de bataille. Les deux divisions, au milieu de cette espèce de nuage, se trompèrent de direction, donnèrent un peu à gauche, et laissèrent à leur droite un large espace entre elles et la division Saint-Hilaire. Les Russes, peu incommodés de la neige qu'ils recevaient à dos, et voyant s'avancer les deux divisions d'Augereau sur les mamelons auxquels ils appuyaient leur centre, démasquèrent à l'improviste une batterie de 72 bouches à feu qu'ils tenaient en réserve. La mitraille vomie par cette redoutable batterie était si épaisse, qu'en un quart d'heure la moitié du corps d'Augereau fut abattue. Le général Desjardins, commandant la première division, fut tué; le
  • 66. du corps d'Augereau. général Heudelet, commandant la seconde, reçut une blessure presque mortelle. Bientôt l'état-major des deux divisions fut mis hors de combat. Tandis qu'elles essuyaient ce feu épouvantable, obligées de se reformer en marchant, tant leurs rangs étaient éclaircis, la cavalerie russe, se précipitant dans l'espace qui les séparait de la division Morand, fondit sur elles en masse. Ces braves divisions résistèrent toutefois, mais elles furent obligées de rétrograder vers le cimetière d'Eylau, cédant le terrain sans se rompre, sous les assauts répétés de nombreux escadrons. Tout à coup la neige, ayant cessé de tomber, permit d'apercevoir ce douloureux spectacle. Sur six ou sept mille combattants, quatre mille environ, morts ou blessés, jonchaient la terre. Augereau, atteint lui-même d'une blessure, plus touché au reste du désastre de son corps d'armée que du péril, fut porté dans le cimetière d'Eylau aux pieds de Napoléon, auquel il se plaignit, non sans amertume, de n'avoir pas été secouru à temps. Une morne tristesse régnait sur les visages, dans l'état-major impérial. Napoléon, calme et ferme, imposant aux autres l'impassibilité qu'il s'imposait à lui-même, adressa quelques paroles de consolation à Augereau, puis il le renvoya sur les derrières, et prit ses mesures pour réparer le dommage. Lançant d'abord les chasseurs de sa garde, et quelques escadrons de dragons qui étaient à sa portée, pour ramener la cavalerie ennemie, il fit appeler Murat, et lui ordonna de tenter un effort décisif sur la ligne d'infanterie qui formait le centre de l'armée russe, et qui profitant du désastre d'Augereau, commençait à se porter en avant. Au premier ordre, Murat était accouru au galop.—Eh bien, lui dit Napoléon, nous laisseras-tu dévorer par ces gens-là?—Alors il prescrivit à cet héroïque chef de sa cavalerie de réunir les chasseurs, les dragons, les cuirassiers, et de se jeter sur les Russes avec quatre-vingts escadrons, pour essayer tout ce que pouvait l'élan d'une pareille masse d'hommes à cheval, chargeant avec fureur une infanterie réputée inébranlable. La cavalerie de la garde fut portée en avant, prête à joindre son choc à celui de la cavalerie de l'armée. Le moment était critique, car si l'infanterie russe n'était pas arrêtée, elle
  • 67. Charge de toute la réserve de cavalerie sur l'infanterie russe. Murat culbute l'infanterie russe, et hache le centre de leur ligne. allait aborder le cimetière, centre de la position, et Napoléon n'avait pour le défendre que les six bataillons à pied de la garde impériale. Murat part au galop, réunit ses escadrons, puis les fait passer entre le cimetière et Rothenen, à travers ce même débouché par lequel le corps d'Augereau avait déjà marché à une destruction presque certaine. Les dragons du général Grouchy chargent les premiers, pour déblayer le terrain, et en écarter la cavalerie ennemie. Ce brave officier, renversé sous son cheval, se relève, se met à la tête de sa seconde brigade, et réussit à disperser les groupes de cavaliers qui précédaient l'infanterie russe. Mais pour renverser celle-ci, il ne faut pas moins que les gros escadrons vêtus de fer du général d'Hautpoul. Cet officier, qui se distinguait par une habileté consommée dans l'art de manier une cavalerie nombreuse, se présente avec vingt-quatre escadrons de cuirassiers, que suit toute la masse des dragons. Ces cuirassiers, rangés sur plusieurs lignes, s'ébranlent, et se précipitent sur les baïonnettes russes. Les premières lignes, arrêtées par le feu, ne pénètrent pas, et se repliant à droite et à gauche, viennent se reformer derrière celles qui les suivent, pour charger de nouveau. Enfin l'une d'elles, lancée avec plus de violence, renverse sur un point l'infanterie ennemie, et y ouvre une brèche, à travers laquelle cuirassiers et dragons pénètrent à l'envi les uns des autres. Comme un fleuve qui a commencé à percer une digue, l'emporte bientôt tout entière, la masse de nos escadrons ayant une fois entamé l'infanterie des Russes, achève en peu d'instants de renverser leur première ligne. Nos cavaliers se dispersent alors pour sabrer. Une affreuse mêlée s'engage entre eux et les fantassins russes. Ils vont, viennent, et frappent de tous côtés ces fantassins opiniâtres. Tandis que la première ligne d'infanterie est ainsi culbutée, et hachée, la seconde se replie à un bois, qui se voyait au fond du champ de bataille. Il restait là une dernière réserve d'artillerie. Les Russes la mettent en batterie, et tirent confusément sur leurs soldats et sur les nôtres, s'inquiétant peu de
  • 68. Le combat étant rétabli au centre, Napoléon attend le résultat de l'action engagée sur les ailes. mitrailler amis et ennemis, pourvu qu'ils se débarrassent de nos redoutables cavaliers. Le général d'Hautpoul est frappé à mort par un biscaïen. Pendant que notre cavalerie est ainsi aux prises avec la seconde ligne de l'infanterie russe, quelques parties de la première se relèvent çà et là pour tirer encore. À cette vue, les grenadiers à cheval de la garde, conduits par le général Lepic, l'un des héros de l'armée, s'élancent à leur tour, pour seconder les efforts de Murat. Ils partent au galop, chargent les groupes d'infanterie qu'ils aperçoivent debout, et, parcourant le terrain en tous sens, complètent la destruction du centre de l'armée russe, dont les débris achèvent de s'enfuir vers les bouquets de bois qui lui ont servi d'asile. Durant cette scène de confusion, un tronçon détaché de cette vaste ligne d'infanterie, s'était avancé jusqu'au cimetière même. Trois ou quatre mille grenadiers russes, marchant droit devant eux, avec ce courage aveugle d'une troupe plus brave qu'intelligente, viennent se heurter contre l'église d'Eylau, et menacent le cimetière occupé par l'état-major impérial. La garde à pied, immobile jusque- là, avait essuyé la canonnade sans rendre un coup de fusil. C'est avec joie qu'elle voit naître une occasion de combattre. Un bataillon est commandé: deux se disputent l'honneur de marcher. Le premier en ordre, conduit par le général Dorsenne, obtient l'avantage de se mesurer avec les grenadiers russes, les aborde sans tirer un coup de fusil, les joint à la baïonnette, les refoule les uns sur les autres, tandis que Murat, apercevant cet engagement, lance sur eux deux régiments de chasseurs sous le général Bruyère. Les malheureux grenadiers russes, serrés entre les baïonnettes des grenadiers de la garde, et les sabres de nos chasseurs, sont presque tous pris ou tués, sous les yeux de Napoléon, et à quelques pas de lui. Cette action de cavalerie, la plus extraordinaire peut-être de nos grandes guerres, avait eu pour résultat de culbuter le centre des Russes, et de le repousser à une assez grande distance. Il aurait fallu avoir sous la main une réserve d'infanterie, afin d'achever la défaite d'une troupe qui, après
  • 69. Vaillante conduite de la division Saint- Hilaire et du corps du maréchal Davout. s'être couchée à terre, se relevait pour faire feu. Mais Napoléon n'osait pas disposer du corps du maréchal Soult, réduit à une moitié de son effectif, et nécessaire à la garde d'Eylau. Le corps d'Augereau était presque détruit. Les six bataillons de la garde à pied restaient seuls comme réserve, et au milieu des chances si diverses de cette journée, fort éloignée encore de sa fin, c'était une ressource qu'il fallait conserver précieusement. À gauche le maréchal Ney, marchant depuis plusieurs jours côte à côte avec les Prussiens, pouvait les devancer, ou en être devancé sur le champ de bataille, et huit ou dix mille hommes, survenant à l'improviste, devaient apporter à l'une des deux armées un renfort peut-être décisif. À droite, le maréchal Davout se trouvait engagé avec la gauche des Russes dans un combat acharné, dont le résultat était encore inconnu. Napoléon, immobile dans ce cimetière où l'on avait accumulé les cadavres d'un grand nombre de ses officiers, plus grave que de coutume, mais commandant à son visage comme à son âme, ayant sa garde derrière lui, et devant lui les chasseurs, les dragons, les cuirassiers reformés, prêts à se dévouer de nouveau, Napoléon attendait l'événement, avant de prendre une détermination définitive. Jamais, ni lui, ni ses soldats n'avaient assisté à une action aussi disputée. Mais le temps des défaites n'était pas venu, et la fortune, rigoureuse un moment pour cet homme extraordinaire, le traitait encore en favori. À cette heure, le général Saint-Hilaire, avec sa division, le maréchal Davout avec son corps, justifiaient la confiance que Napoléon avait mise en eux. La division Saint-Hilaire, accueillie comme le corps d'Augereau, et au même instant, par un horrible feu de mitraille et de mousqueterie, avait eu cruellement à souffrir. Aveuglée aussi par la neige, elle n'avait point aperçu une masse de cavalerie accourant sur elle au galop, et un bataillon du 10e léger, assailli avant d'avoir pu se former, avait été renversé sous les pieds des chevaux. La division Morand, extrême gauche de Davout, découverte par
  • 70. Subite apparition du général prussien Lestocq sur le champ de bataille. Friant et Gudin arrêtent les Prussiens. l'accident arrivé au bataillon du 10e léger, s'était vue ramenée en arrière, pendant deux ou trois cents pas. Mais bientôt Davout et Morand l'avaient reportée en avant. Dans cet intervalle, le général Friant soutenait à Klein-Sausgarten une lutte héroïque, et, secondé par la division Gudin, il occupait définitivement cette position avancée sur le flanc des Russes. Il venait même de pousser des détachements jusqu'au village de Kuschitten, situé sur leurs derrières. C'était le moment où, la journée étant presque achevée, et l'armée russe presque à moitié détruite, la bataille semblait devoir se terminer en notre faveur. Mais l'événement que redoutait Napoléon s'était réalisé. Le général Lestocq, poursuivi à outrance par le maréchal Ney, paraissait sur ce champ de carnage, avec 7 ou 8 mille Prussiens, jaloux de se venger du dédain des Russes. Le général Lestocq, devançant à peine d'une heure ou deux le corps du maréchal Ney, avait tout juste le temps de porter un coup, avant d'être atteint lui-même. Il débouche sur le champ de bataille à Schmoditten, passe derrière la double ligne des Russes, maintenant brisée par le feu de nos artilleurs, par le sabre de nos cavaliers, et se présente à Kuschitten, en face de la division Friant, qui, dépassant Klein-Sausgarten, avait déjà refoulé la gauche de l'ennemi sur son centre. Le village de Kuschitten était occupé par quatre compagnies du 108e , et par le 51e , qui avait été détaché de la division Morand, pour aller au soutien de la division Friant. Les Prussiens, ralliant les Russes autour d'eux, fondent impétueusement sur le 51e et sur les quatre compagnies du 108e ne parviennent pas à les rompre, mais les ramènent fort en arrière de Kuschitten. Après ce premier avantage, les Prussiens se portent au delà de Kuschitten afin de ressaisir les positions du matin. Ils marchent déployés sur deux lignes. Les réserves russes ralliées, forment sur leurs ailes deux colonnes serrées. Une nombreuse artillerie les précède. Ils s'avancent ainsi en traversant les derrières du champ de bataille,
  • 71. Horrible état de l'armée russe à la fin du jour. Le général Benningsen délibère s'il doit tenter un dernier effort. La subite arrivée du maréchal pour regagner le terrain perdu, et ramener le maréchal Davout sur Klein-Sausgarten, et de Klein-Sausgarten sur Serpallen. Mais les généraux Friant et Gudin, ayant le maréchal Davout à leur tête, accourent. La division Friant tout entière, les 12e , 21e , 25e régiments appartenant à la division Gudin se placent en avant, couverts par toute l'artillerie du troisième corps. Vainement les Russes et les Prussiens veulent-ils renverser cet obstacle formidable, ils n'y peuvent réussir. Les Français, appuyés à des bois, à des marécages, à des monticules, ici déployés en ligne, là dispersés en tirailleurs, opposent une opiniâtreté invincible à ce dernier effort des coalisés. Le maréchal Davout, parcourant les rangs jusqu'à la fin du jour, contient ses soldats en leur disant: Les lâches iront mourir en Sibérie; les braves mourront ici en gens d'honneur.—L'attaque des Prussiens et des Russes ralliés s'arrête, le terrain perdu sur leur flanc gauche n'est pas reconquis. Le corps du maréchal Davout reste ferme dans cette position de Klein-Sausgarten, d'où il menace les derrières de l'ennemi. Les deux armées étaient épuisées. Ce jour si sombre devenait à chaque instant plus sombre encore, et allait se terminer en une affreuse nuit. Le carnage était horrible. Près de 30 mille Russes, atteints par les projectiles ou le sabre des Français, jonchaient la terre, les uns morts, les autres blessés plus ou moins gravement. Beaucoup de leurs soldats commençaient à s'en aller à la débandade[22]. Le général Benningsen, entouré de ses lieutenants, délibérait s'il fallait reprendre l'offensive, et tenter un nouvel effort. Mais, d'une armée de 80 mille hommes, il ne lui en restait pas 40 mille en état de combattre, les Prussiens compris. S'il avait succombé dans cet engagement désespéré, il n'aurait pas eu de quoi couvrir la retraite. Néanmoins il hésitait encore, lorsqu'on vint lui annoncer un dernier et grave incident. Le maréchal Ney, qui avait suivi de près les Prussiens, arrivant le soir sur notre gauche comme le
  • 72. Ney décide la retraite des Russes. Position occupée par l'armée française le soir de la bataille d'Eylau. maréchal Davout était arrivé le matin sur notre droite, débouchait enfin vers Althof. Ainsi les combinaisons de Napoléon, retardées par le temps, n'en avaient pas moins amené sur les deux flancs de l'armée russe les forces qui devaient décider la victoire. L'ordre de retraite ne pouvait plus dès lors être différé, car le maréchal Davout, s'étant maintenu à Klein-Sausgarten, n'avait pas beaucoup à faire pour rencontrer le maréchal Ney, qui s'était avancé jusqu'à Schmoditten, et la jonction de ces deux maréchaux aurait exposé les Russes à être enveloppés. L'ordre de se retirer fut donné à l'instant même par le général Benningsen. Toutefois pour assurer la retraite il voulut contenir le maréchal Ney, et essayer de lui enlever le village de Schmoditten. Les Russes marchèrent sur ce village, à la faveur de la nuit, et en grand silence, pour surprendre les troupes du maréchal Ney, arrivées tard sur ce champ de bataille où l'on avait de la peine à se reconnaître. Mais celles-ci étaient sur leurs gardes. Le général Marchand, avec le 6e léger et le 39e de ligne, laissant approcher les Russes, puis les accueillant par un feu à bout portant, les arrêta net. Il courut ensuite sur eux à la baïonnette, et les fit renoncer à toute attaque sérieuse. Dès ce moment ils se mirent définitivement en retraite. Napoléon discernant à la direction des feux du maréchal Davout et du maréchal Ney, le véritable état des choses, se savait maître du champ de bataille, mais il n'était pas assuré cependant de ne pas avoir une seconde bataille à livrer, la nuit ou le lendemain. Il occupait cette plaine légèrement relevée, qui s'étendait au delà d'Eylau, ayant devant lui et au centre sa cavalerie et sa garde, à gauche en avant d'Eylau les deux divisions Legrand et Leval du corps du maréchal Soult, à droite la division Saint- Hilaire qui se liait avec le corps du maréchal Davout porté au delà de Klein-Sausgarten, l'armée française décrivant ainsi une ligne oblique sur le terrain que les Russes avaient possédé le matin. Fort au delà, sur la gauche, le maréchal Ney isolé,
  • 73. Disposition morale de l'armée. se trouvait sur les derrières de la position que l'ennemi abandonnait en toute hâte. Napoléon, certain d'être victorieux, mais triste au fond du cœur, était demeuré au milieu de ses troupes, ordonnant qu'on allumât des feux, et qu'on ne quittât pas les rangs, même pour aller chercher des vivres. On distribuait aux soldats un peu de pain et d'eau-de-vie, et, quoiqu'il n'y en eût pas assez pour tous, on ne les entendait pas se plaindre. Moins joyeux qu'à Austerlitz ou à Iéna, ils étaient pleins de confiance, fiers d'eux-mêmes, prêts à recommencer cette lutte terrible, si les Russes en avaient le courage et la force. Quiconque, en ce moment, leur eût donné le pain et l'eau-de-vie dont ils manquaient, les eût retrouvés aussi gais que de coutume. Deux artilleurs du corps du maréchal Davout ayant été absents de leur compagnie pendant cette journée, et étant arrivés trop tard pour assister à la bataille, leurs camarades s'assemblèrent le soir au bivouac, les jugèrent, et n'ayant pas goûté leurs raisons, leur infligèrent sur ce terrain glacé et sanglant, le châtiment burlesque que les soldats appellent la savate[23]. Il n'y avait en grande abondance que des munitions. Le service de l'artillerie, exécuté avec une activité rare, avait déjà remplacé les munitions consommées. Le service des ambulances se faisait avec non moins de zèle. On avait ramassé un grand nombre de blessés, et on administrait aux autres quelques secours sur place, en attendant qu'on pût les transporter à leur tour. Napoléon, accablé de fatigue, debout cependant, présidait aux soins donnés à ses soldats. Sur les derrières de l'armée tout n'offrait pas une contenance aussi ferme. Beaucoup de traînards qui manquaient à l'effectif le matin, par suite de la rapidité des marches, avaient entendu le retentissement de cette épouvantable bataille, avaient aperçu quelques houras de Cosaques, et s'étaient repliés, répandant sur les routes des nouvelles fâcheuses. Les braves accouraient se ranger
  • 74. Journée qui suit la bataille d'Eylau. Pertes des Russes et des Français à la bataille d'Eylau. auprès de leurs camarades, les autres s'en allaient dans les diverses directions qu'avait parcourues l'armée. Le lendemain le jour commençant à luire, on découvrit cet affreux champ de bataille, et Napoléon lui-même fut ému, au point de le laisser apercevoir dans le bulletin qu'il publia. Sur cette plaine glacée, des milliers de morts et de mourants cruellement mutilés, des milliers de chevaux abattus, une innombrable quantité de canons démontés, de voitures brisées, de projectiles épars, des hameaux en flammes, tout cela se détachant sur un fond de neige[24], présentait un spectacle saisissant et terrible. «Ce spectacle, s'écriait Napoléon, est fait pour inspirer aux princes l'amour de la paix, et l'horreur de la guerre!»—Singulière réflexion dans sa bouche, et sincère au moment où il la laissait échapper. Une particularité frappa tous les yeux. Soit penchant à revenir aux choses du passé, soit aussi économie, on avait voulu rendre l'habit blanc aux troupes. On en avait fait l'essai sur quelques régiments, mais la vue du sang sur les habits blancs décida la question. Napoléon rempli de dégoût et d'horreur déclara qu'il ne voulait que des habits bleus, quoi qu'il pût en coûter. L'aspect de ce champ de bataille abandonné par l'ennemi rendit à l'armée le sentiment de sa victoire. Les Russes s'étaient retirés, laissant sur le terrain 7 mille morts, et plus de 5 mille blessés, que le vainqueur généreux se hâta de relever après les siens. Outre les 12 mille morts ou mourants abandonnés à Eylau, ils emmenaient avec eux environ 15 mille blessés, plus ou moins gravement atteints. Ils avaient eu par conséquent 26 ou 27 mille hommes hors de combat. Nous tenions 3 à 4 mille prisonniers, 24 pièces de canon, 16 drapeaux. Leur perte totale était donc de 30 mille hommes. Les Français avaient eu environ 10 mille hommes hors de combat, dont 3 mille morts et 7 mille blessés[25], perte bien inférieure à celle de l'armée russe, et qui s'explique par la position
  • 75. Napoléon pousse les Russes jusqu'à Kœnigsberg. de nos troupes rangées en ordre mince, par l'habileté de nos artilleurs et de nos soldats. Ainsi dans cette journée fatale, près de 40 mille hommes des deux côtés avaient été atteints par le feu et le fer. C'est la population d'une grande ville détruite en un jour! Triste conséquence des passions des peuples! passions terribles, qu'il faut s'appliquer à bien diriger, mais non pas chercher à éteindre! Napoléon, dès le 9 au matin, avait porté ses dragons et ses cuirassiers en avant, afin de courir après les Russes, de les jeter sur Kœnigsberg, et de les refouler pour tout l'hiver au delà de la Prégel. Le maréchal Ney, qui n'avait pas eu beaucoup à faire dans la journée d'Eylau, fut chargé de soutenir Murat. Les maréchaux Davout et Soult devaient suivre à peu de distance. Napoléon resta de sa personne à Eylau pour panser les plaies de sa brave armée, pour la nourrir, et mettre tout en ordre sur ses derrières. Cela importait plus qu'une poursuite, que ses lieutenants étaient très-capables d'exécuter eux-mêmes. En marchant on acquit plus complétement encore la conviction du désastre essuyé par les Russes. À mesure qu'on avançait, on trouvait les villages et les bourgs de la Prusse orientale remplis de blessés; on apprenait le désordre, la confusion, le triste état enfin de l'armée fugitive. Néanmoins les Russes, en comparant cette bataille à celle d'Austerlitz, étaient fiers de la différence. Ils convenaient de leur défaite, mais ils se dédommageaient de cet aveu, en ajoutant que la victoire avait coûté cher aux Français. On ne s'arrêta que sur les bords de la Frisching, petite rivière qui coule de la ligne des lacs à la mer, et Murat poussa ses escadrons jusqu'à Kœnigsberg. Les Russes réfugiés en toute hâte, les uns au delà de la Prégel, les autres à Kœnigsberg même, faisaient mine de vouloir s'y défendre, et avaient braqué sur les murs une nombreuse artillerie. Les habitants épouvantés se demandaient s'ils allaient éprouver le sort de Lubeck. Heureusement pour eux Napoléon voulait mettre un terme à ses opérations offensives. Il avait envoyé
  • 76. les cavaliers de Murat jusqu'aux portes de Kœnigsberg, mais il ne se proposait pas d'y conduire son armée elle-même. Il n'aurait pas fallu moins que cette armée tout entière, pour tenter avec espoir de succès une attaque de vive force, sur une grande ville, pourvue de quelques ouvrages, et défendue par tout ce qui restait de troupes russes et prussiennes. Une attaque même heureuse sur cette riche cité, ne valait pas les chances qu'on aurait courues, si la tentative eût échoué. Napoléon ayant poussé ses corps jusqu'aux bords de la Frisching, tint à les y laisser quelques jours, pour bien constater sa victoire, et puis songea à se retirer pour reprendre ses cantonnements. Sans doute il n'avait pas obtenu l'immense résultat dont il s'était d'abord flatté, et qui ne lui aurait certainement point échappé, si une dépêche interceptée n'avait révélé ses desseins aux Russes; mais il les avait menés battant pendant cinquante lieues, leur avait détruit neuf mille hommes dans une suite de combats d'arrière-garde, et les trouvant à Eylau formés en une masse compacte, couverts d'artillerie, résolus jusqu'au désespoir, forts avec les Prussiens de 80 mille soldats, sur une plaine où aucune manœuvre n'était possible, il les avait attaqués avec 54 mille, les avait détruits à coups de canon, et avait paré à tous les accidents de la journée avec un imperturbable sang-froid, pendant que ses lieutenants s'efforçaient de le rejoindre. Les Russes ce jour-là avaient eu tous leurs avantages, la solidité, l'immobilité au feu; lui n'avait pas eu tous les siens, sur un terrain où il était impossible de manœuvrer; mais il avait opposé à leur ténacité un invincible courage, une force morale au-dessus des horreurs du plus affreux carnage. L'âme de ses soldats s'était montrée dans cette journée aussi forte que la sienne! Assurément il pouvait être fier de cette épreuve. D'ailleurs pour 12 ou 13 mille hommes qu'il avait perdus pendant ces huit jours, il en avait détruit 36 mille à l'ennemi. Mais il devait sentir en ce moment ce que c'était que la puissance du climat, du sol, des distances, car, possédant plus de 300 mille hommes en Allemagne, il n'avait pas pu en réunir plus de 54 mille sur le lieu de l'action décisive. Il devait après une telle victoire faire de graves réflexions, compter davantage avec les éléments et la fortune, et moins entreprendre à l'avenir sur l'invincible nature des
  • 77. Napoléon quitte les environs de Kœnigsberg, et les bords de la Prégel, pour reprendre ses cantonnements de la Vistule. choses. Ces réflexions il les fit, et elles lui inspirèrent, comme on va en juger bientôt, la conduite la mieux calculée, la plus admirablement prévoyante. Plût au ciel qu'elles fussent restées pour toujours gravées dans sa mémoire! Quoique victorieux et garanti pour plusieurs mois de toute tentative contre ses cantonnements, il avait cependant une chose à craindre, c'étaient les récits mensongers des Russes, l'effet de ces récits sur l'Autriche, sur la France, sur l'Italie, sur l'Espagne, sur l'Europe en un mot, qui, voyant depuis trois mois sa marche deux fois arrêtée, tantôt par les boues, tantôt par les frimas, serait portée à le croire moins irrésistible, moins fatalement heureux, tiendrait pour douteuse la victoire pourtant la plus incontestable, la plus cruellement efficace, et pourrait enfin être tentée de méconnaître sa fortune. Il résolut de montrer ici le caractère qu'il avait déployé pendant la journée même d'Eylau, et, certain de sa force, d'attendre que l'Europe, mieux éclairée, la sentît comme lui. Après avoir passé quelques jours sur la Frisching, l'ennemi ne sortant pas de ses lignes, il prit le parti de rétrograder pour rentrer dans ses cantonnements. La température était toujours froide, mais sans descendre à plus de 2 ou 3 degrés au-dessous de la glace. Il en profita pour évacuer ses blessés en traîneau. Plus de six mille subirent, sans en souffrir sensiblement, ce singulier voyage de quarante à cinquante lieues, jusqu'à la Vistule. Un soin extrême apporté à les rechercher tous dans les villages environnants, permit d'en constater le véritable nombre. Il était conforme à celui que nous avons mentionné plus haut. Quand tout fut évacué, blessés, malades, prisonniers, artillerie prise à l'ennemi, Napoléon commença, le 17 février, son mouvement rétrograde, le maréchal Ney avec le sixième corps, Murat avec la cavalerie faisant l'arrière- garde, les autres corps conservant leur position accoutumée dans l'ordre de marche, le maréchal Davout à droite, le maréchal Soult au
  • 78. Motifs qui décident Napoléon à changer la position de ses cantonnements. centre, le maréchal Augereau à gauche, enfin le maréchal Bernadotte, qui avait rejoint, formant l'extrême gauche, le long du Frische-Haff. Napoléon ayant remonté l'Alle jusque près des lacs d'où elle sort, et d'où sort aussi la Passarge, changea de direction, et, au lieu de prendre la route de Varsovie, prit celle de Thorn, Marienbourg et Elbing, voulant désormais s'appuyer à la basse Vistule. Les derniers événements avaient modifié ses idées quant au choix de sa base d'opération. Voici les motifs de ce changement. La position entre les branches de l'Ukra, de la Narew, du Bug, qu'il avait d'abord adoptée, était une conséquence de l'occupation de Varsovie. Elle avait l'avantage de couvrir cette capitale, et, si l'ennemi se portait le long du littoral, de permettre plus aisément de le déborder, de le tourner, de l'acculer à la mer, ce que Napoléon venait d'essayer, et ce qu'il aurait certainement exécuté, sans l'enlèvement de ses dépêches. Mais, cette manœuvre une fois dévoilée, il n'était pas probable que les Russes avertis s'exposassent à un danger qu'ils venaient d'éviter par une sorte de miracle. La position choisie en avant de Varsovie ne présentait donc plus le même avantage, et elle offrait un inconvénient grave, celui d'obliger l'armée à s'étendre démesurément, pour couvrir à la fois Varsovie et le siége de Dantzig, siége qui devenait l'opération urgente, à laquelle il fallait consacrer les loisirs de l'hiver. En se plaçant, en effet, à Varsovie, on était obligé de laisser le corps de Bernadotte à grande distance, avec peu de chances de le rallier au gros de l'armée; et si on marchait en avant, on était forcé en outre de laisser le cinquième corps, celui de Lannes, à la garde de Varsovie. On agissait par conséquent avec deux corps de moins. L'éloignement du corps de Bernadotte serait devenu à l'avenir d'autant plus regrettable, qu'on allait être contraint de lui adjoindre de nouvelles forces, pour seconder et couvrir le siége de Dantzig.
  • 79. Nouvelle position prise par Napoléon. Napoléon prit donc la résolution de s'éloigner de Varsovie, de confier la garde de cette capitale au cinquième corps, aux Polonais, aux Bavarois (la soumission des places de la Silésie rendait ces derniers disponibles), et de s'établir avec la plus grande partie de ses troupes, en avant de la basse Vistule, derrière la Passarge, ayant Thorn à sa droite, Elbing à sa gauche, Dantzig sur ses derrières, son centre à Osterode, ses avant-postes entre la Passarge et l'Alle. (Voir les cartes nos 37 et 38.) Dans cette position il couvrait lui-même le siége de Dantzig, sans avoir besoin de détacher pour cet objet aucune partie de ses forces. Si, en effet les Russes, voulant secourir Dantzig, venaient chercher une bataille, il pouvait leur opposer tous ses corps réunis, celui de Bernadotte compris, et même une partie des troupes de Lefebvre, que rien ne l'empêchait d'attirer à lui dans un cas pressant, ainsi qu'il l'avait fait en 1796, lorsqu'il leva le siége de Mantoue pour courir aux Autrichiens. Il ne lui manquait un jour de bataille que le cinquième corps, qui, de quelque manière qu'on opérât, était indispensable sur la Narew, afin de défendre Varsovie. Cette nouvelle position, d'ailleurs, donnait lieu à des combinaisons savantes, fécondes en grands résultats, ignorées de l'ennemi, tandis que celles qui auraient eu Varsovie pour base, lui étaient toutes connues. Cantonné derrière la Passarge, Napoléon se trouvait à quinze lieues seulement de Kœnigsberg. Supposez que les Russes, attirés par l'isolement apparent dans lequel on laissait Varsovie, s'avançassent sur cette capitale, on courait derrière eux à Kœnigsberg, on s'emparait de cette ville, et puis se rabattant par un mouvement à droite sur leurs derrières, on les jetait sur la Narew et la Vistule, dans les marécages de l'intérieur, avec autant de certitude de les détruire, que dans le cas du mouvement vers la mer. Si, au contraire, ils attaquaient de front les cantonnements sur la Passarge, on avait, comme nous venons de le dire, outre la force naturelle de ces cantonnements, la masse entière de l'armée à leur opposer. La position était donc excellente pour le siége de Dantzig, excellente pour les opérations futures, car elle faisait naître des combinaisons nouvelles, dont le secret n'était pas dévoilé.
  • 80. Caractère de la guerre que Napoléon faisait en ce moment. Répartition de l'armée entre les divers cantonnements. C'est assurément un spectacle imposant et instructif, que celui de ce général impétueux, qui n'était propre, au dire de ses détracteurs, qu'à la guerre offensive, porté d'un seul bond du Rhin à la Vistule, s'arrêtant tout à coup devant les difficultés des lieux et des saisons, s'enfermant dans un espace étroit, y faisant la guerre froide, lente, méthodique, y disputant pied à pied de petites rivières, après avoir franchi les plus gros fleuves sans s'arrêter, se réduisant enfin à couvrir un siége, et placé à une aussi vaste distance de son empire, en présence de l'Europe qu'étonnait cette nouvelle manière de procéder, que le doute commençait à gagner, conservant une fermeté inébranlable, n'étant pas même séduit par le désir de frapper un coup d'éclat, et sachant ajourner ce coup au moment où la nature des choses le rendrait sûr et possible: c'est, disons-nous, un spectacle digne d'intérêt, de surprise, d'admiration, c'est une précieuse occasion d'étude et de réflexions, pour quiconque est sensible aux combinaisons des grands hommes, et se plaît à les méditer! Napoléon vint donc se placer entre la Passarge et la basse Vistule (voir la carte no 38), le corps du maréchal Bernadotte à gauche sur la Passarge, entre Braunsberg et Spanden; le corps du maréchal Soult au centre, entre Liebstadt et Mohrungen; le corps du maréchal Davout à droite, entre Allenstein et Hohenstein, au point où l'Alle et la Passarge sont le plus rapprochées; le corps du maréchal Ney en avant-garde, entre la Passarge et l'Alle, à Guttstadt; le quartier général et la garde à Osterode, dans une position centrale, où Napoléon pouvait réunir toutes ses forces en quelques heures. Il attira le général Oudinot à Osterode, avec les grenadiers et voltigeurs, formant une réserve d'infanterie de 6 à 7 mille hommes. Il répandit la cavalerie sur ses derrières, entre Osterode et la Vistule, depuis Thorn jusqu'à Elbing, pays qui abondait en toute sorte de fourrages.
  • 81. Dissolution du corps d'Augereau. Dans l'énumération des corps cantonnés derrière la Passarge, nous n'avons pas désigné celui d'Augereau. Napoléon en avait prononcé la dissolution. Augereau venait de quitter l'armée, déconcerté de ce qui lui était arrivé dans la journée d'Eylau, imputant mal à propos son échec à la jalousie de ses camarades, qui, selon lui, n'avaient pas voulu le soutenir, se disant fatigué, malade, usé! L'Empereur le renvoya en France, avec des témoignages de satisfaction, qui étaient de nature à le consoler. Mais craignant que dans le septième corps, à moitié détruit, il ne restât quelque chose du découragement manifesté par le chef, il en prononça la dissolution, après y avoir prodigué les récompenses. Il en répartit les régiments entre les maréchaux Davout, Soult et Ney. Des 12 mille hommes dont se composait le septième corps, il y en avait eu 7 mille présents à Eylau, et sur ces 7 mille, deux tiers mis hors de combat. Les survivants, joints à ceux qui étaient demeurés en arrière, devaient fournir 7 à 8 mille hommes de renfort aux divers corps de l'armée. Napoléon plaça le cinquième corps sur l'Omulew, à quelque distance de Varsovie. Lannes étant toujours malade, il avait mandé, avec regret d'en priver l'Italie, mais avec une grande satisfaction de le posséder en Pologne, le premier de ses généraux, Masséna, qui n'avait pas pu s'entendre avec Joseph à Naples. Il lui donna le commandement du cinquième corps. Les siéges de la Silésie avançant, grâce à l'énergie et à la fertilité d'esprit du général Vandamme, Schweidnitz ayant été pris, Neisse et Glatz restant seuls à prendre, Napoléon en profita pour amener sur la Vistule la division bavaroise Deroy, forte de 6 à 7 mille hommes d'assez bonnes troupes, laquelle fut cantonnée à Pultusk, entre la position du cinquième corps sur l'Omulew et Varsovie. Les bataillons polonais de Kalisch et de Posen avaient été envoyés à Dantzig. Napoléon rassembla ceux de Varsovie, organisés par le prince Poniatowski, à Neidenbourg, de manière à maintenir la communication entre le quartier général et les troupes campées sur l'Omulew. Ils étaient là sous les ordres du général Zayonscheck. Il demanda en outre que
  • 82. Distribution générale des forces de l'armée. l'on organisât un corps de cavalerie de mille à deux mille Polonais, afin de courir après les Cosaques. Ces diverses troupes polonaises destinées à lier la position de la grande armée sur la Passarge, avec celle de Masséna sur la Narew, n'étaient pas capables assurément d'arrêter une armée russe qui aurait pris l'offensive, mais elles suffisaient pour empêcher les Cosaques de pénétrer entre Osterode et Varsovie, et pour exercer dans ce vaste espace une active surveillance. Concentré ainsi derrière la Passarge, et en avant de la basse Vistule, couvrant dans une position inattaquable le siége de Dantzig, qui allait enfin commencer, pouvant par une menace sur Kœnigsberg, arrêter tout mouvement offensif sur Varsovie, Napoléon était dans une situation à ne rien craindre. Rejoint par les retardataires laissés en arrière, et par le corps de Bernadotte, renforcé par les grenadiers et voltigeurs d'Oudinot, il pouvait en quarante-huit heures réunir 80 mille hommes sur l'un des points de la Passarge. Cette situation était fort imposante, surtout si on la compare à celle des Russes, qui n'auraient pas pu mettre 50 mille hommes en ligne. Mais c'est une remarque digne d'être répétée, quoique déjà faite par nous, qu'une armée de plus de 300 mille hommes, répandue depuis le Rhin jusqu'à la Vistule, administrée avec une habileté qu'aucun capitaine n'a jamais égalée, fût dans l'impossibilité de fournir plus de 80 mille combattant sur le même champ de bataille. Il y avait 80 à 90 mille hommes capables d'agir offensivement entre la Vistule et la Passarge, 24 mille sur la Narew, d'Ostrolenka à Varsovie, en y comprenant les Polonais et les Bavarois, 22 mille sous Lefebvre devant Dantzig et Colberg, 28 mille sous Mortier, en Italiens, Hollandais et Français, répandus depuis Brême et Hambourg jusqu'à Stralsund et Stettin, 15 mille en Silésie tant Bavarois que Wurtembergeois, 30 mille dans les places, depuis Posen jusqu'à Erfurt et Mayence, 7 ou 8 mille employés aux parcs, 15 mille blessés de toutes les époques, 60 et quelques mille malades et maraudeurs, enfin 30 à 40 mille recrues en marche, ce qui faisait à peu près 330 mille hommes à la grande armée, dont 270 mille Français, et environ 60 mille auxiliaires, Italiens, Hollandais, Allemands et Polonais.
  • 83. Mars 1807. Grand nombre de maraudeurs à la suite de l'armée. Ce qui paraîtra singulier, c'est ce nombre énorme de 60 mille malades ou maraudeurs, nombre, il est vrai, très-approximatif[26], difficile à fixer, mais digne de l'attention des hommes d'État, qui étudient les secrets ressorts de la puissance des nations. Il n'y avait pas dans ces soixante mille absents qualifiés de malades, la moitié qui fût aux hôpitaux. Les autres étaient en maraude. Nous avons déjà dit que beaucoup de soldats manquaient dans les rangs à la bataille d'Eylau, par suite de la rapidité des marches, et que les impressions produites par cette terrible bataille se répandant au loin, les lâches et la valetaille avaient fui à toutes jambes, en criant que les Français étaient battus. Depuis il s'était joint à eux beaucoup d'hommes, qui, sous prétexte de maladies ou de blessures légères, demandaient à se rendre aux hôpitaux, mais se gardaient bien d'y aller, parce qu'on y était retenu, surveillé, soigné même jusqu'à l'ennui. Ils avaient passé la Vistule, vivaient dans les villages, à droite et à gauche de la grande route, de manière à échapper à la surveillance générale qui contenait dans l'ordre toutes les parties de l'armée. Ils vivaient ainsi aux dépens du pays, qu'ils ne ménageaient pas, les uns vrais lâches, dont une armée, même héroïque, a toujours une certaine quantité dans ses rangs, les autres fort braves au contraire, mais pillards par nature, aimant la liberté et le désordre, et prêts à revenir au corps dès qu'ils apprenaient la reprise des opérations. Napoléon, averti de cet état de choses, par la différence entre le nombre d'hommes réputés aux hôpitaux, et le nombre de ceux que les dépenses de M. Daru prouvaient y être véritablement, porta sur cet abus une sérieuse attention. Il employa pour le réprimer la police des autorités polonaises, puis la gendarmerie d'élite attachée à sa garde, comme la seule troupe qui fût assez respectée pour se faire obéir. Jamais néanmoins on ne put complétement détruire sur la ligne d'opération cette lèpre attachée aux grandes armées. Et pourtant l'armée dont il s'agissait ici, était celle du camp de Boulogne, la plus solide, la plus disciplinée, la plus brave qui fut jamais! Dans la campagne d'Austerlitz, les maraudeurs s'étaient à peine fait voir. Mais la rapidité des mouvements, la distance, le climat, la saison, le carnage enfin,
  • 84. Quelques démonstrations des Russes contre nos cantonnements. relâchant les liens de la discipline, cette vermine, triste effet de la misère dans un grand corps, commençait à pulluler. Napoléon y pourvut cette fois par une immense prévoyance, et par les victoires qu'il remporta bientôt. Mais des défaites peuvent en quelques jours faire dégénérer un pareil mal en dissolution des armées. Ainsi dans les succès même de cette belle et terrible campagne de 1807, apparaissaient plusieurs des symptômes d'une campagne à jamais fatale et mémorable, celle de 1812. Le retour dans les cantonnements fut signalé par quelques mouvements de la part des Russes. Leurs rangs étaient singulièrement éclaircis. Il ne leur restait pas cinquante mille hommes capables d'agir. Cependant le général Benningsen, tout enorgueilli de n'avoir pas perdu à Eylau jusqu'au dernier homme, et, suivant son usage, se disant vainqueur, voulut donner à ses vanteries une apparence de vérité. Il quitta donc Kœnigsberg, dès qu'il apprit que l'armée française se retirait sur la Passarge. Il vint montrer de fortes colonnes le long de cette rivière, surtout dans son cours supérieur, vers Guttstadt, en face de la position du maréchal Ney. Il s'adressait mal, car cet intrépide maréchal, privé de l'honneur de combattre à Eylau, et impatient de s'en dédommager, reçut vigoureusement les corps qui se présentèrent à lui, et leur fit essuyer une perte notable. Dans le même moment, le corps du maréchal Bernadotte, cherchant à s'établir sur la basse Passarge, et obligé pour cela d'occuper Braunsberg, s'empara de cette ville, où il fît prisonniers deux mille Prussiens. Ce fut la division Dupont qui eut le mérite de cette brillante expédition. Les Russes ayant néanmoins continué de s'agiter, et paraissant vouloir se porter sur la haute Passarge, Napoléon, dans les premiers jours de mars, prit le parti de faire sur la basse Passarge une démonstration offensive, de façon à inquiéter le général Benningsen pour la sûreté de Kœnigsberg. C'est à regret que Napoléon se décidait à un tel mouvement, car c'était révéler aux Russes le danger qu'ils couraient en s'élevant sur notre droite pour menacer Varsovie. Sachant bien qu'une manœuvre démasquée est
  • 85. Importance attachée aux approvisionnem ents dans la position où se trouvait Napoléon. une ressource perdue, Napoléon aurait voulu ne pas agir du tout, ou agir d'une manière décisive, en marchant sur Kœnigsberg avec toutes ses forces. Mais, d'une part, il fallait obliger l'ennemi à se tenir tranquille, afin de l'être soi-même dans ses quartiers d'hiver; de l'autre, on n'avait ni en vivres ni en munitions de quoi tenter une opération de quelque durée. Napoléon se résigna donc à une simple démonstration sur la basse Passarge, exécutée le 3 mars par les corps des maréchaux Soult et Bernadotte, qui passèrent cette rivière pendant que le maréchal Ney à Guttstadt poussait rudement le corps ennemi dirigé sur la haute Passarge. Les Russes perdirent dans ces mouvements simultanés environ 2 mille hommes, et, en voyant leur ligne de retraite sur Kœnigsberg compromise, se hâtèrent de se retirer et de rendre la tranquillité à nos cantonnements. Tels furent les derniers actes de cette campagne d'hiver. Le froid long-temps retardé commençait à se faire sentir; le thermomètre était descendu à 8 et 10 degrés au-dessous de la glace. On allait avoir en mars le temps auquel on aurait dû s'attendre en décembre et en janvier. Napoléon, qui ne s'était décidé que malgré lui à ordonner les dernières opérations, écrivit au maréchal Soult: «C'est bien un des inconvénients que j'avais sentis des mouvements actuels, que d'éclairer les Russes sur leur position. Mais ils me pressaient trop sur ma droite. Résolu à laisser passer le mauvais temps, et à organiser les subsistances, je ne suis point autrement fâché de cette leçon donnée à l'ennemi. Avec l'esprit de présomption dont je le vois animé, je crois qu'il ne faut que de la patience, pour lui voir faire de grandes fautes.» (Osterode, 6 mars.) Si Napoléon avait eu alors assez de vivres et de moyens de transport pour traîner après lui de quoi nourrir l'armée pendant quelques jours, il eût immédiatement terminé la guerre, ayant affaire à un ennemi assez malavisé pour venir se jeter sur la droite de ses quartiers. Aussi toute la question
  • 86. Efforts pour se procurer des vivres et des moyens de transport. consistait-elle à ses yeux dans un approvisionnement, qui lui permît de refaire ses soldats épuisés par les privations, et de les réunir quelques jours, sans être exposé à les voir mourir de faim, ou à laisser une moitié d'entre eux en arrière, comme il lui était arrivé à Eylau. Les villes du littoral, notamment celle d'Elbing, pouvaient lui fournir des vivres pour les premiers moments de son établissement, mais de telles ressources ne lui suffisaient pas. Il voulait donc en amener de grandes quantités, qui descendraient de Varsovie par la Vistule, ou viendraient de Bromberg par le canal de Nackel, et puis seraient par terre transportées de la Vistule aux divers cantonnements de l'armée sur la Passarge. Il donna les ordres les plus précis à cet égard, pour amasser d'abord à Bromberg et à Varsovie les approvisionnements nécessaires, pour créer ensuite les moyens de transport qui devaient servir à terminer le trajet de la Vistule aux bords de la Passarge. Son intention était de commencer par fournir chaque jour la ration entière à ses soldats, et puis de former à Osterode, centre de ses quartiers, un magasin général, qui renfermât quelques millions de rations, en pain, riz, vin, eau-de-vie. Il voulut utiliser à cet effet le zèle des Polonais, qui jusqu'ici lui avaient rendu peu de services militaires, et dont il désirait tirer au moins quelques services administratifs. Comme il avait M. de Talleyrand à Varsovie, il le chargea de s'entendre avec le gouvernement provisoire, qui dirigeait les affaires de la Pologne. Il lui écrivit donc la lettre suivante, en lui envoyant ses pleins pouvoirs pour conclure des marchés à quelque prix que ce fût. Osterode, 12 mars, 10 heures du soir. «Je reçois votre lettre du 10 mars à 3 heures après midi. J'ai 300 mille rations de biscuit à Varsovie. Il faut huit jours pour venir de Varsovie à Osterode; faites des miracles, mais qu'on m'en expédie par jour 50 mille rations. Tâchez aussi de me faire expédier par jour 2 mille pintes d'eau-de-vie. Aujourd'hui le sort de l'Europe et les plus grands calculs dépendent des
  • 87. subsistances. Battre les Russes, si j'ai du pain, est un enfantillage. J'ai des millions, je ne me refuse pas d'en donner. Tout ce que vous ferez sera bien fait, mais il faut qu'au reçu de cette lettre on m'expédie, par terre et par Mlawa et Zakroczin, 50 mille rations de biscuit et 2 mille pintes. C'est l'affaire de 80 voitures par jour en les payant au poids de l'or. Si le patriotisme des Polonais ne peut pas faire cet effort, ils ne sont pas bons à grand'chose. L'importance de ce dont je vous charge là est plus considérable que toutes les négociations du monde. Faites appeler l'ordonnateur, le gouverneur, le général Lemarois, les hommes les plus influents du gouvernement. Donnez de l'argent; j'approuve tout ce que vous ferez. Du biscuit et de l'eau-de-vie, c'est tout ce qu'il nous faut. Ces 300 mille rations de biscuit et ces 18 ou 20 mille pintes d'eau-de-vie qui peuvent nous arriver dans quelques jours, voilà ce qui déjouera les combinaisons de toutes les puissances.» M. de Talleyrand assembla les membres du gouvernement polonais, pour tâcher d'en obtenir les vivres et les charrois dont on avait besoin. Les denrées ne manquaient pas en Pologne, car avec de l'argent comptant fourni aux juifs, on était sûr d'en trouver. Mais les moyens de transport étaient fort difficiles à organiser. On voulut d'abord s'en procurer dans le pays même, en payant des prix considérables; puis on finit par acheter des charrettes et des chevaux, et on parvint ainsi à établir des relais aboutissant des bords de la Vistule à ceux de la Passarge. Les vivres circulaient en bateaux sur la Vistule; débarqués ensuite à Varsovie, à Plock, à Thorn, à Marienwerder, ils étaient transportés à Osterode, centre des cantonnements, ou sur les caissons des régiments, ou sur les voitures du pays, ou sur celles qu'on avait soi-même achetées et pourvues de chevaux. On rechercha en les payant des bœufs dans toute la Silésie, et on les fit venir sur pied à Varsovie. On tâcha de recueillir des vins et des spiritueux sur le littoral du nord, où le commerce les apporte en quantité considérable, et en qualité supérieure. On en avait à Berlin, à Stettin, à Elbing; on les achemina par eau jusqu'à Thorn. Napoléon eût attaché beaucoup de prix à se
  • 88. Situation des troupes dans les cantonnements. Arrivée des renforts organisés en régiments provisoires. procurer deux ou trois cent mille bouteilles de vin, pour réjouir le cœur de ses soldats. Il avait près de lui une précieuse ressource en ce genre, mais elle était renfermée dans la place de Dantzig, où se trouvaient plusieurs millions de bouteilles d'excellents vins, c'est-à- dire de quoi en fournir à l'armée pendant quelques mois. Ce n'était pas un médiocre stimulant pour prendre cette forteresse. Ces soins si actifs, consacrés à l'approvisionnement de l'armée, ne pouvaient pas produire un effet immédiat; mais, dans l'intervalle, on vivait sur la Nogath, sur Elbing, sur les districts mêmes qu'on occupait, et l'industrie de nos soldats suppléant à ce qui manquait, on était parvenu à se procurer le nécessaire. Beaucoup de vivres cachés avaient été découverts, et avaient permis d'attendre les arrivages réguliers de la Vistule. On était logé dans les villages, et on ne bivouaquait plus, ce qui était un grand soulagement pour des troupes qui venaient de bivouaquer pendant cinq mois de suite, depuis octobre jusqu'à février. Aux avant-postes, on vivait dans des baraques, dont ce pays de forêts fournissait en abondance les matériaux et le chauffage. Quelques vins, quelques eaux-de-vie, trouvés à Elbing, et distribués avec ordre, rendaient à nos soldats un peu de gaieté. Les premiers jours passés, ils avaient fini par être mieux que sur la Narew, car le pays était meilleur, et ils espéraient bien, au retour de la belle saison, se dédommager des peines présentes, et terminer en un jour de bataille la terrible lutte dans laquelle ils étaient engagés. Les régiments provisoires, qui amenaient les recrues, commençaient à paraître sur la Vistule. Plusieurs d'entre eux, déjà rendus sur le théâtre de la guerre, avaient été passés en revue, dissous, et répartis entre les régiments auxquels ils appartenaient. Les soldats voyaient ainsi leurs rangs se remplir, entendaient parler de renforts nombreux qui se préparaient sur les derrières de l'armée, et se confiaient davantage dans la vigilance suprême qui pourvoyait à tous leurs besoins. La
  • 89. Soins pour remonter la cavalerie. Travaux de défense sur la Passarge et la Vistule. cavalerie continuait d'être l'objet des soins les plus attentifs. Napoléon avait formé des détachements à pied de tous les cavaliers démontés, et il les avait envoyés en Silésie, pour aller y chercher les chevaux dont cette province abondait. Des travaux immenses s'exécutaient sur la Passarge et la Vistule, afin d'assurer la position de l'armée. Tous les ponts sur la Passarge avaient été détruits, deux exceptés, l'un pour l'usage du corps du maréchal Bernadotte à Braunsberg, l'autre pour l'usage du corps du maréchal Soult à Spanden. De vastes têtes de pont étaient ajoutées à chacun des deux, afin de pouvoir déboucher au delà, Napoléon répétant sans cesse à ses lieutenants, qu'une ligne n'était facile à défendre que lorsqu'on était en mesure de la franchir à son tour pour prendre l'offensive contre celui qui l'attaquait[27]. Deux ponts sur la Vistule, l'un à Marienbourg, l'autre à Marienwerder, assuraient la communication avec les troupes du maréchal Lefebvre, chargées du siége de Dantzig. On pouvait donc aller à elles, ou les amener à soi, et présenter partout à l'ennemi une masse compacte. Le maréchal Lefebvre se rapprochait de Dantzig, en attendant la grosse artillerie tirée des places de la Silésie, pour commencer ce grand siége, qui devait être l'occupation et la gloire de l'hiver. Les ouvrages de Sierock, de Praga, de Modlin, destinés à consolider la position de Varsovie, se poursuivaient également. C'est du petit bourg d'Osterode que Napoléon ordonnait toutes ces choses. Ses soldats ayant du pain, des pommes de terre, de la viande, de l'eau-de-vie, du chaume pour s'abriter, du bois pour se chauffer, ne souffraient pas. Mais les officiers qui ne parvenaient à se procurer que la nourriture et le logement du soldat, même avec leur solde exactement payée, étaient exposés à beaucoup de privations. Napoléon avait voulu leur donner l'exemple de la résignation, en restant au milieu d'eux. Les officiers de chaque corps, envoyés à Osterode, pouvaient dire qu'ils ne l'avaient pas trouvé mieux établi que le dernier d'entre eux. Aussi, répondant à son frère Joseph, qui
  • 90. Welcome to our website – the perfect destination for book lovers and knowledge seekers. We believe that every book holds a new world, offering opportunities for learning, discovery, and personal growth. That’s why we are dedicated to bringing you a diverse collection of books, ranging from classic literature and specialized publications to self-development guides and children's books. More than just a book-buying platform, we strive to be a bridge connecting you with timeless cultural and intellectual values. With an elegant, user-friendly interface and a smart search system, you can quickly find the books that best suit your interests. Additionally, our special promotions and home delivery services help you save time and fully enjoy the joy of reading. Join us on a journey of knowledge exploration, passion nurturing, and personal growth every day! ebookbell.com