This document discusses RequestReduce, a tool that automatically optimizes websites for performance by reducing the number of HTTP requests. It does this through CSS and JavaScript merging, minification, automatic sprite generation, caching headers, and synchronization across multiple servers with minimal customization needed. The document provides details on how RequestReduce works, its features, limitations, and ways to optimize and troubleshoot sites optimized with RequestReduce.
4. Why is this important?
• PLT has a direct impact on traffic and
conversions
• Yahoo found that 400ms equaled a 5 – 9%
drop in full page traffic
• Google takes speed into account in search
rankings
5. What is RequestReduce
• Applies common client side performance best
practices so that you don’t have to
– CSS and Javascript Merge and Minification
– CSS Import expansion
– Automatic Sprite Generation
– Sprite PNG Optimization
– Cache Header Generation
– Supports multi server content synchronization
– Supports CDN hosts
9. Features Unique to RequestReduce
• Reduces on the fly instead of at build time
– Can reduce Dynamic css and javascript
• Unobtrusive: Does not require you to change
your code, configuration or file structure.
• Works with all asp.net technologies
(MVC/Web Forms/Razor)
• Pulls resources via HTTP – can reduce
distributed and third party resources.
• Synchronizes content across multiple servers
10. Why not just make this part of the
build process?
• Does not work or difficult to integrate with
dynamic or external css and javascript
• Unusually requires new static resource to be
manually “plugged in”
• Easy to forget or overlook integrating new
content
• RequestReduce is designed to be “dropped” in to
any running app with minimal customization or
consideration of that App’s design
11. RequestReduce: How does it work?
• Filter’s the response looking for <HEAD/> and <SCRIPT/> tags
– Derives from Stream and is attached to the Response stream of any
text/html resource
– Extracts URLs from Link hrefs and script src
– Ignore CSS and Script inside conditional comments
– Ignore script URLs included in black list (google and MS jquery CDN
included by default)
– Creates a key from concatenated urls that can be merged together
– Queries a dictionary for the existence of that key
13. Sprite Generation
• All CSS is scanned for classes containing a
background image.
• Each class is treated as an autonomous unit. No
inheritance awareness.
• Cannot currently sprite:
– Repeating images
– Images positioned with non pixel units or a
percentage unit > 0.
– Images with no explicit horizontal dimension (padding
+ width)
14. Sprite Image Processing
• Both Lossy and Lossless compression is applied.
• Silverlight Code Gallery before any spriting is
applied has a spritable payload size of 18k.
• After initial sprite generation: 27k
• Why? It’s a 32bit PNG
• Need to quantize down to 8 bit.
• Standard C based quantizers had inadequate
quality
15. Developing nQuant
• Images quantized using pngquant.exe were often coming
out with distorted colors
• Tried to find Free OSS quantizers. Either license was not
friendly or the they were code samples that were not alpha
aware and had horrid quality.
• Found a C based algorithm converted to C# that was
extremely high quality but not alpha aware.
• Tokk me about a month to come up with the formulas that
supported the alpha layers and the result is nQuant
(available on codeplex).
• Silverlight spright optimized to 10.6k after quantization.
• Use optipng for final lossless compression to get to 9k.
16. Sprite Sizing Limits
• RequestReduce continues to add images to a
sprite until the image size exceeds 50k.
• OR until there are over 5000 unique colors in
the sprite – Mitigates poor quantization
output.
• Threshold can be safely increased with JPGs.
• Lots of room for future experimantation here
17. Migration issues with sprites
• Depending on original CSS structure, can
sprite most images with no editing or
dramatically distort the rendering.
• Like every thing else, this feature can be
turned off.
• I have assisted Galleries, Forums, Profile and
Search to convert the CSS to be
RequestReduce friendly.
18. CSS Sprite change example
• Old CSS:
img.alert,
img.answer,
img.answered,
img.ask
{ background: url('http://i1.social.s-msft.com/contentservice/c2afadb0-5d34-489a-bf31-
9f5c011d3cd4/icon_strip_windows.png') no-repeat !important;
Width: 20px;}
img.ask { background-position: -100px 0;}
img.answer { background-position: -120px 0;}
img.alert { background-position: -140px 0;}
• Merge image with position into one class.
19. Serving the Reduced Resources
• All reduced content is cached and managed by
RequestReduce
• The following caching headers are applied:
– Cache-control: public (ensures resources will be
cached on proxies and CDNs)
– Expires: 360 days from serving (over a year would
violate http RFC)
– Etag: “<32byte hash of file contents>” ensures
Etag is automatically invalidated upon content
change.
20. Reduced Content caching
• RequestReduce Supports two caching modes:
– Simple file system cache
• This can be any UNC path including a remote share or
centralized image server
• This mode is ideal for individual dev environments due
to its simplicity.
• On app startup, the file names of the file cache are read
and keyed in memory so that content does not have to
be reprocessed.
– SQL Server caching…
21. Caching across multiple servers
• The Sql Server based cache is ideal for multi
server test and production environments.
• All reduced content is initially saved to a sql
table
22. Content Changing and Flushing
• Content is automatically flushed and queued for
reprocessing when CSS or Javascript Urls change.
• Changes that do not result in a url change will require a
flush in order to be seen. To flush content from a file
based settingm you can wither delete the
RequestReduce directory or issue a flush explicitly via
http://<app>/RequestReduceContent/flush
• Sql Servers can also call the flush url but it may take up
to 5 minutes for all servers to sync.
• Deleting the data directory in a webserver running
against a sql based cache, will NOT clear the cache.
23. Troubleshooting
• Normal dev work may want to have
RequestReduce turned off.
• Appending any url with rrfilter=disabled
effectively shuts down the response filter for
the current request. This is a good technique
to determine if RequestReduce is responsible
for page defects
24. Optimizing
• Request can often perform better based on
dev practices:
– Maker sure background images are sprite friendly
– Use background images for commonly used
foreground images
– Group cachable javascript together and preferably
at the bottom of the page if you can
25. So many more possibilities
• Foreground image spriting
• Optimize non sprites
• Externalize inline styles and scripts
• Asynchronously load CSS
• Support defered javascript execution
• Exploit perf optimizations specific to the browser
of the incoming request
• Make the processing build friendly and expand
extension points
26. Resources
• Project home page: http://www.RequestReduce.com
• Source Code:
https://github.com/mwrock/RequestReduce I take
pull requests
• Detailed and organized Wiki documentation:
https://github.com/mwrock/RequestReduce/wiki
• Bug reporting and feature requests:
https://github.com/mwrock/RequestReduce/issue