从web现状谈及性能优化
性能优化指南
The Internet is growing exponentially, and so is the Web platform we create. Often though we fail to reflect on the greater picture of connectivity and contexts the audience of our work might find themselves in. Even a short glance at the state of the World Wide Web shows that we haven’t been building with empathy, situation variability awareness, let alone performance in mind.
如今网络发展迅猛,这对我们构建的互联网平台要求也更高。而我们却疲于反思用户与我们之间的联系。这就说明,我们在开发时,并没有站在用户的角度上换位思考,更别谈性能优化。
So, what is the state of the Web today?
那么,互联网现状如何?
Only 46% of 7.4 billion people on this planet have access to the Internet. The average network speed caps at unimpressive 7Mb/s. More importantly, 93% of Internet users are going online through mobile devices — it becomes inexcusable to not cater to handhelds. Often data is more expensive than we’d assume — it could take anywhere from an hour to 13 hours to purchase 500MB packet (Germany versus Brazil; for more intriguing stats on connectivity head to Ben Schwarz’s Beyond the Bubble: The Real World Performance).
据统计,全球只有3亿多人能接触到互联网,但网速平均只有7mb/s,关键的是,其中3亿是通过移动端浏览。势必,我们开发时必须考虑这部分人群的需求。而且,数据也比我们想象中的要贵,有数据指出,我们可以在1-13个小时内就花掉500MB流量(参考德国和巴西----想要更多关于用户与互联网之间联系的有趣统计,可以看:https://building.calibreapp.c...)。
Our websites aren’t in a perfect shape either — the average site is the size of original Doom game (approx. 3 MB) (please note that for statistical accuracy medians should be used, read Ilya Grigorik’s excellent The “Average Page” is a myth. Median site size is currently at 1.4MB). Images can easily account for 1.7 MB of bandwidth and JavaScript averages at 400KB. This isn’t a problem specific to the Web platform only. Native applications aren’t better; remember that time you had to download 200 MB to get unspecified bug fixes?
而且,我们搭建的网站也并不完善——平均一个网站(计算首屏加载)的大小和国外经典桌面游戏Doom game1的大小差不多(大约3MB)(注意这里计算出的平均值,参考Ilya Grigorik’s excellent The “Average Page” is a myth,目前一般网站首屏加载大约要1.4MB),其中加载图片需要1.7MB,javascript需要400KB。不仅在pc端有这个问题,手机原生应用也好不到哪去,还记得你必须花200MB流量来更新app修复未知缺陷吗?
As technologists often we find ourselves in the position of privilege. With up-to-date, high-end laptops, phones and fast cable Internet connection, it becomes all to easy to forget this isn’t the case for everyone (actually, it’s true for very few).
If we’re building the web platform from the standpoint of privilege and lack of empathy, it results in exclusionary, subpar experiences.
How can we do better by designing and developing with performance in mind?
作为技术人员,我们拥有绝对的优势。用最新、高配置的电脑和手机,网速也超快,这让我们很容易认为普罗大众也是这样(事实上,是很少很少)。
构建网络平台时,如果我们安于开发特权、缺乏用户同理心,将会导致极糟的用户体验。
那么,在设计和开发时,怎样才能做到性能优化呢?
优化所有资源
Optimising all assets
One of the most powerful, but under-utilised ways to significantly improve performance starts with understanding how the browser analyses and serves assets. It turns out that browsers are pretty great at discovering resources while parsing and determining their priority on the fly. Here’s where the critical request comes in.
A request is critical if it contains assets that are necessary to render the content within the users’ viewport.
For most sites, it’d be HTML, necessary CSS, a logo, a web font and maybe an image. It turns out that in many cases, dozens of other, irrelevant at the time assets are requested instead (JavaScript, tracking codes, ads, etc.). Luckily, we’re able to control this behaviour by carefully picking crucial resources and adjusting their priority.
要想显著地提升性能,最有效但也容易被忽视的方法就是了解浏览器如何解析资源。已被证明,浏览器善于查找资源并且解析后快速确定资源加载的优先级顺序。那么什么资源优先级高呢?这里有关于critical request的来源:
判断一个请求是关键性请求,就看它是否包含用于渲染用户可见内容的资源
对于大多数网站来说,关键性请求是请求html文件、必要的css、logo、字体文件和图片,在加载完这些文件后,再选择加载其它非决定性的文件(JavaScript、统计代码、广告...)。因此,我们可通过区分关键资源并调整加载的优先级来实现性能优化。
With <link rel='preload'> we’re able to manually force assets’ priority to High ensuring that desired content will be rendered on time. This technique can yield significant improvements in Time to Interactive metric, making optimal user experience possible.
方法一:为link标签设置rel='preload'属性,手动设置该资源优先加载,来确保所期望的内容及时呈现。这种技术可以显着改善“交互时间”,使最佳用户体验成为可能。
Critical requests still seem like a black box for many, and the lack of shareable materials doesn’t help to change that. Fortunately, Ben Schwarz published an incredibly comprehensive and approachable article on the subject — The Critical Request. Additionally, check Addy’s Preload, Prefetch and Priorities in Chrome.
关键性请求对于大多数人来说似乎还是个盲区,可共享资源的缺乏也没有改变这一点。幸好,本·施瓦茨(Ben Schwarz)发表了一篇关于关键性请求的文章,文章非常全面且易懂。另外,Addy也有一篇文章《在Chrome中的预加载,预取和优先级》。
General performance checklist
- Cache aggressively
- Enable compression
- Prioritise critical assets
- Use content delivery networks
普遍的性能优化方式
- 积极地使用缓存
- 使用压缩
- 优先加载关键性请求
- 使用内容传送网络CDN
优化图片
Optimising images
Images often account for most of a web page’s transferred payload, which is why imagery optimisation can yield the biggest performance improvements. There are many existing strategies and tools to aid us in removing extra bytes, but the first question to ask is: “Is this image essential to convey the message and effect I’m after?”. If it’s possible to eliminate it, not only we’re saving bandwidth, but also requests.
图片通常占网页传输的大部分有效载荷,因此图片优化可以带来最大的性能提升。有许多现有的策略和工具可以帮助我们删除额外的字节,但我们要考虑的第一个问题是:“这张图片对于传达我的信息和效果是否至关重要”。做好了图片优化,可以为用户节省很多带宽。
In some cases, similar results can be achieved with different technologies. CSS has a range of properties for art direction, such as shadows, gradients, animations or shapes allowing us to swap assets for appropriately styled DOM elements.
在某些情况下,不一定非得用图片,可以通过不同的代码方式实现相同的效果。CSS具有一系列属性设置艺术样式,例如阴影,渐变,动画或形状,这些属性可以把资源转换为适当风格的DOM元素。
选择正确的格式
Choosing the right format
If it’s not possible to remove an asset, it’s important to determine what format will be appropriate. The initial choice falls between vector and raster graphics:
如果不可能删除资源,确定哪种合适的格式很重要。首选矢量图或栅格图:
Vector: resolution independent, usually significantly smaller in size. Perfect for logos, iconography and simple assets comprising of basic shapes (lines, polygons, circles and points).
Raster: offers much more detailed results. Ideal for photographs.
矢量:分辨率独立,通常尺寸很小。适用于logo,icon和一些由基本形状(线,多边形,圆和点)组成的图片。
栅格:提供更细节的处理。更适用于图片。
After making this decision, there are a fair bit of formats to choose from: JPEG, GIF, PNG–8, PNG–24, or newest formats such as WEBP or JPEG-XR. With such an abundance of options, how do we ensure we’re picking the right one? Here’s a basic way of finding the best format to go with:
- JPEG: imagery with many colours (e.g. photos)
- PNG–8: imagery with a few colours
- PNG–24: imagery with partial transparency
- GIF: animated imagery
决定好之后,我们可以选择几种格式:JPEG, GIF, PNG–8, PNG–24,或最新格式,如WEBP或JPEG-XR。有了这么多的选择,我们如何确保我们选择了合适的格式?这是找到最佳格式的基本方法: - JPEG:具有多种颜色的图像(例如照片)
- PNG-8:具有几种颜色的图像
- PNG-24:具有部分透明度的图像
- GIF: 动图
Photoshop can optimise each of these on export through various settings such as decreasing quality, reducing noise or number of colours. Ensure that designers are aware of performance practices and can prepare the right type of asset with the right optimisation presets. If you’d like to know more how to develop images, head to Lara Hogan’s invaluable Designing for Performance.
Photoshop可以通过各种设置,例如降低画质,降低噪点或减少颜色数量来优化图片。确保设计师了解性能实践,并可以使用正确的优化方式来提供恰当格式的资源。如果您想了解如何优化图片,请前往Lara Hogan’s invaluable Designing for Performance。
尝试新格式
Experimenting with new formats
There are a few newer players in the spectrum of image formats, namely WebP, JPEG 2000 and JPEG-XR. All of them are developed by browser vendors: WebP by Google, JPEG 2000 by Apple and JPEG-XR by Microsoft.
图像格式有几个较新的玩家,即WebP,JPEG 2000和JPEG-XR。所有这些都是由浏览器供应商开发的:Google的WebP,Apple的JPEG 2000和Microsoft的JPEG-XR。
WebP is easily the most popular contender, supporting both lossless and lossy compression, which makes it incredibly versatile. Lossless WebP is 26% smaller than PNGs and 25–34% smaller than JPGs. With 74% browser support it can safely be used with fallback, introducing up to 1/3 savings in transferred bytes. JPGs and PNGs can be converted to WebP in Photoshop and other image processing apps as well as through command line interfaces (brew install webp).
WebP是最受欢迎的竞争者,支持无损和失真压缩,这使得它非常通用。无损WebP比PNG小26%,比JPG小25-34%。有了74%的浏览器支持,它可以安全地用于回退,最多可节省1/3的传输字节。JPG和PNG图片可以在Photoshop或其他图像处理应用程序以及命令行界面(brew install webp)中转换为WebP。
If you’d like to explore (minor) visual differences between these formats I recommend this nifty demo on Github.
如果你想探索这些格式之间的视觉差异,我建议看看这个在Github上的demo。
用工具和算法进行图片优化
Optimising with tools and algorithms
Even using incredibly efficient image formats doesn’t warrant skipping post-processing optimisation. This step is crucial.
即使使用高效的图像格式也不值得跳过后处理优化。这一步很重要。
If you’ve chosen SVGs, which are usually relatively small in size, they too have to be compressed. SVGO is a command line tool that can swiftly optimise SVGs through stripping unnecessary metadata. Alternatively, use SVGOMG by Jake Archibald if you prefer a web interface or are limited by your operating system. Because SVG is an XML-based format, it can also be subject to GZIP compression on the server side.
如果你选择了通常尺寸相对较小的SVG,那么也需要被压缩。SVGO是一个命令行工具,可以通过剥离不必要的元数据来快速优化SVG。或者,如果你喜欢Web界面或受操作系统的限制,请使用Jake Archibald的SVGOMG。因为SVG是基于XML的格式,它也可以在服务器端进行GZIP压缩。
ImageOptim is an excellent choice for most of the other image types. Comprising of pngcrush, pngquant, MozJPEG, Google Zopfli and more, it bundles a bunch of great tools in a comprehensive, Open Source package. Available as a Mac OS app, command line interface and Sketch plugin, ImageOptim can be easily implemented into an existing workflow. For those on Linux or Windows, most of the CLIs ImageOptim relies on can be used on your platform.
ImageOptim是大多数其他图像类型的绝佳选择。包括pngcrush,pngquant,MozJPEG,Google Zopfli等,它在一个开源包中捆绑了一堆很棒的工具。作为Mac OS应用程序,命令行界面和Sketch插件,ImageOptim可以轻松地应用到现有的工作流程中。对于那些在Linux或Windows上,大多数ImageOptim的CLI也可以使用。
If you’re inclined to try emerging encoders, earlier this year, Google released Guetzli — an Open Source algorithm stemming from their learnings with WebP and Zopfli. Guetzli is supposed to produce up to 35% smaller JPEGs than any other available method of compression. The only downside: slow processing times (a minute of CPU per megapixel).
如果你想尝试新兴的编码器,Google今年早些时候发布了Guetzli - 源自WebP和Zopfli的开源算法。 Guetzli应该比任何其他可用的压缩方法产生比35%更小的JPEG。唯一的缺点:处理时间慢(CPU每百万像素一分钟)。
When choosing tools make sure they produce desired results and fit into teams’ workflow. Ideally, automate the process of optimisation, so no imagery slips through the cracks unoptimised.
选择工具时,请确保它们适合项目和团队的工作流程。理想情况下,构建自动化优化,这样可以基本覆盖所有需优化的图片。
自适应图像
Responsible and responsive imagery
A decade ago we might have gotten away with one resolution to serve all, but the landscape of ever-changing, responsive web is very different today. That’s why we have to take extra care in implementing visual resources we’ve so carefully optimised and ensuring they cater for the variety of viewports and devices. Fortunately, thanks to Responsive Images Community Group we’re perfectly equipped to do so with picture element and srcset attribute (both have 85%+ support).
十年前,我们可能已经抛弃了一次性解决所有问题的观念,如今的不断发展的响应式网络更需如此。这就是为什么我们在渲染我们精心优化过的视觉资源时必须特别小心,并确保它们适应各种视口和设备。幸运的是,感谢Responsive Images社区小组,我们完全可以使用图片元素和srcset属性(都有85%+支持)。
srcset属性
The srcset attribute
Srcset works best in the resolution switching scenario—when we want to display imagery based on users’ screen density and size. Based on a set of predefined rules in srcset and sizes attributes the browser will pick the best image to serve accordingly to the viewport. This technique can bring great bandwidth and request savings, especially for the mobile audience.
Srcset在分辨率切换方案中效果最佳 - 当我们要根据用户的屏幕分辨率和大小显示图像时。基于srcset和size属性中的一组预定义规则,浏览器将选择最佳图像,以便相应地提供给视口。这种技术可以带来很大的带宽,需谨慎使用,特别是针对移动用户。
图片元素
The picture element
Picture element and the media attribute are designed to make art direction easy. By providing different sources for varying conditions (tested via media-queries), we’re able always able to keep the most important elements of imagery in the spotlight, no matter the resolution.
图片元素和媒体属性旨在使艺术化变得简单。通过为不同场景提供不同资源(通过媒体查询测试),无论场景怎么变化,我们始终可以展现正确的图像。
Make sure to read Jason Grigsby’s Responsive Images 101 guide for a thorough explanation of both approaches.
务必阅读Jason Grigsby的Responsive Images 101指南,以便彻底理解这两种方法。
图片放到CDN
Delivery with image CDNs
The last step of our journey to performant visuals is delivery. All assets can benefit from using a content delivery network, but there are specific tools targeting imagery, such as Cloudinary or imgx. The benefit of using those services goes further than reducing traffic on your servers and significantly decreasing response latency.
图片优化的最后一步是传输。所有资源可以放到CDN上,现有一些特定的工具可以定位到图像,例如“Cloudinary”或“imgx”。使用这些服务的好处远远超过想办法减少服务器上的流量,并显着降低了响应延迟,提升加载速度。
CDNs can take out a lot of complexity from serving responsive, optimised assets on image-heavy sites. The offerings differ (and so does the pricing) but most handle resizing, cropping and determining which format is best to serve to your customers based on devices and browsers. Even more than that — they compress, detect pixel density, watermark, recognise faces and allow post-processing. With these powerful features and ability to append parameters to URLs serving user-centric imagery becomes a breeze.
CDN在图像重磅的网站上响应和优化资源会加重复杂度。资源不同(花费也是如此),但是大多数处理器可以根据设备和浏览器调整合适的大小,裁剪并确定最合适的格式。而且 - 它们可以进行压缩,检测像素密度,水印,识别面部并允许后处理。借助这些强大的功能和将参数附加到以用户为中心的图像的URL的功能变得轻而易举。
Image performance checklist
- Choose the right format
- Use vector wherever possible
- Reduce the quality if change is unnoticeable
- Experiment with new formats
- Optimise with tools and algorithms
- Learn about srcset and picture
- Use an image CDN
图像性能清单
- 选择正确的格式
- 尽可能使用矢量
- 如果变化不明显,则降低画质
- 尝试新格式
- 用工具和算法进行图片优化
- 了解srcset和图片元素
- 图片放到CDN
优化网页字体
Optimising web fonts
The ability to use custom fonts is an incredibly powerful design tool. But with power comes a lot of responsibility. With whooping 68% of websites leveraging web fonts this type of asset is one of the biggest performance offenders (easily averaging 100KB, depending on the number of variants and typefaces).
使用自定义字体的是一个非常强大进步。但权力越多责任越大。有68%的网站利用网络字体,这种类型的资产是最大的性能违规者之一(容易平均100KB,取决于变体和字体的数量)。
Even when weight isn’t the most major issue, Flash of Invisible Text (FOIT) is. FOIT occurs when web fonts are still loading or failed to be fetched, which results in an empty page and thus, inaccessible content. It might be worth it to carefully examine whether we need web fonts in the first place. If so, there are a few strategies to help us mitigate the negative effect on performance.
即使重量不是最大的问题,Flash的隐形文本(FOIT)也是。当网页字体在加载中或未能被抓取时,会发生FOIT,这会导致空白页面,从而导致无法访问的内容。首先要仔细检查我们是否需要网页字体。如果是这样,有一些策略可以帮助我们减轻对性能方面的负面影响。
选择正确的格式
Choosing the right format
There are four web font formats: EOT, TTF, WOFF and more recent WOFF2. TTF and WOFF are most widely adopted, boasting over 90% browser support. Depending on the support you’re targeting it’s most likely safe to serve WOFF2 and fall back to WOFF for older browsers. The advantage of using WOFF2 is a set of custom preprocessing and compression algorithms (like Brotli) resulting in approx. 30% file-size reduction and improved parsing capabilities.
有四种网络字体格式:EOT,TTF,WOFF和近期的WOFF2。 TTF和WOFF被广泛采用,拥有超过90%的浏览器支持。根据你的项目,尽可能稳定地支持WOFF2,并在旧版浏览器上使用WOFF。使用WOFF2的优点是其有一套定制的预处理和压缩算法(如Brotli),能缩小大约30%的文件大小和提升解析功能。
When defining the sources of web fonts in @font-face
use the format()
hint to specify which format should be utilised.
在@font-face
中定义网页字体的来源时,请使用format()
来指定应使用哪种格式。
If you’re using Google Fonts or Typekit to serve your fonts, both of these tools have implemented a few strategies to mitigate their performance footprint. Typekit now serves all kits asynchronously, preventing FOIT as well as allows for extended cache period of 10 days for their JavaScript kit code (instead of default 10 minutes). Google Fonts automatically serves the smallest file, based on the capabilities of the users’ device.
如果你使用Google Fonts或Typekit来作为字体,这两种字体都实施了一些策略来减轻其性能消耗。 Typekit现在可以异步地为所有工具包提供服务,保护FOIT以及允许其JavaScript代码延长10天的缓存时间(而不是默认10分钟)。 Google Fonts可以根据用户设备的性能自动提供最小的文件。
斟酌字体选择
Audit font selection
No matter whether self-hosting or not, the number of typefaces, font weights and styles will significantly affect your performance budgets.
无论是否自主托管,字体数量、大小和样式都将显著影响你的性能预算。
Ideally, we can get away with one typeface featuring normal and bold stylistic variants. If you’re not sure how to make font selection choices refer to Lara Hogan’s Weighing Aesthetics and Performance.
理想情况下,我们可以避免使用正常或加粗格式上变体的字体。如果不确定如何选择字体,请参考Lara Hogan的衡量美与性能。
使用Unicode格式的字集
Use Unicode-range subsetting
Unicode-range subsetting allows splitting large fonts into smaller sets. It’s a relatively advanced strategy but might bring significant savings especially when targeting Asian languages (did you know Chinese fonts average at 20,000 glyphs?). The first step is to limit the font to the necessary language set, such as Latin, Greek or Cyrillic. If a web font is required only for logotype usage, it’s worth it to use Unicode-range descriptor to pick specific characters.
Unicode格式的字集允许将大字体分割成较小的集合。这是一个相对先进的方案,特别是针对亚洲语言的时候,可能会带来显著的空间节省(你知道中文字体的平均数为20,000字形吗?)。第一步是将字体限制为必要的语言集,例如拉丁语,希腊语或西里尔语。如果使用一个网络字体只是为了进行标识,则推荐使用Unicode格式的描述符来指定字符。
The Filament Group released an Open Source command-line utility, glyph hanger that can generate a list of necessary glyphs based on files or URLs. Alternatively, the web-based Font Squirrel Web Font Generator offers advanced subsetting and optimisation options. If using Google Fonts or Typekit choosing a language subset is built into the typeface picker interface, making basic subsetting easier.
Filament团队发布了一个开源命令行工具,可以根据文件或URL生成必需字形列表。或者,基于Web的Font Squirrel和Font Generator提供的高级字集和优化选项。如果在字体选择器界面中内置了Google Fonts或Typekit,则使用基本字集更容易。
建立一个字体加载策略
Establish a font loading strategy
Fonts are render-blocking — because the browser has to build both the DOM and CSSOM first; web fonts won’t be downloaded before they’re used in a CSS selector that matches an existing node. This behaviour significantly delays text rendering, often causing the Flash of Invisible Text (FOIT) mentioned before. FOIT is even more pronounced on slower networks and mobile devices.
由于浏览器必须首先构建DOM和CSSOM,之后再渲染字体;在解析到应用了web fonts的CSS选择器之前,不会下载web fonts。这种行为有明显的延迟文本现象,特别是前面提到的Flash隐藏文本(FOIT)。在较慢的网络和移动设备上,FOIT延迟更加明显。
Implementing a font loading strategy prevents users from not being able to access your content. Often, opting for Flash of Unstyled Text (FOUT) is the easiest and most effective solution.
实施字体加载策略可防止用户无法访问您的内容。通常,选择Flash的Unstyled Text(FOUT)是最简单和最有效的解决方案。
font-display is a new CSS property providing a non-JavaScript reliant solution. Unfortunately, it has partial support (Chrome and Opera only) and is currently under development in Firefox and WebKit. Still, it can and should be used in combination with other font loading mechanisms.
font-display是提供非JavaScript依赖解决方案的新CSS属性。不幸,它仅有部分浏览器支持(Chrome和Opera),目前正在Firefox和WebKit中开发。尽管如此,它应该与其他字体加载机制结合使用。
font-display property in action
Luckily, Typekit’s Web Font Loader and Bram Stein’s Font Face Observer can help manage font loading behaviour. Additionally, Zach Leatherman, an expert on web font performance, published A Comprehensive Guide to Font Loading Strategies which will aid in choosing the right approach for your project.
幸运的是,Typekit的Web Font Loader和Bram Stein的Font Face Observer可以帮助管理字体加载行为。此外,网页字体性能专家Zach Leatherman发布了“字体加载策略综合指南”,这将有助于为你的项目对web fonts的选择。
Web font performance checklist
- Chose the right format
- Audit the font selection
- Use Unicode-range subsetting
- Establish a font loading strategy
Web字体性能清单
- 选择正确的格式
- 斟酌字体选择
- 使用Unicode格式的字集
- 建立一个字体加载策略
- 使用font-display属性
优化JavaScript
Optimising JavaScript
At the moment, the average size of JavaScript bundle is 446 KB, which already makes it second biggest type of an asset size-wise (following images).
目前,JavaScript软件包的平均大小为446 KB,占用资源的比例已经达到第二(仅次于图片)。
What we might not realise is that there’s a much more sinister performance bottleneck hidden behind our beloved JavaScript.
我们可能没有意识到,我们所爱的JavaScript隐藏着更加险恶的性能瓶颈。
监控JavaScript的传输
Monitor how much JavaScript is delivered
Optimising delivery is only one step in combating web page bloat. After JavaScript is downloaded, it has to be parsed, compiled and run by the browser. A quick look at a few popular sites and it becomes obvious that gzipped JS becomes at least three times bigger after unpacking. Effectively, we are sending giant blobs of code down the wire.
优化传输只是减轻网页膨胀的一步。JavaScript下载后,必须由浏览器进行解析,编译和运行。当你快速浏览一些流行的网站,明显gzip压缩的JS在解压之后至少要增加三倍。实际上,我们正在发送一大堆代码。
Parse times for 1MB of JavaScript on different devices. Image courtesy of Addy Osmani and his JavaScript Start-up Performance article.
在不同的设备上多次解析1MB的JavaScript。图片由Addy Osmani和他的JavaScript Start-up Performance文章提供。
Analysing parse and compile times becomes crucial to understanding when apps are ready to be interacted with. These timings vary significantly based the hardware capabilities of users’ device. Parse and compile can easily be 2–5x times higher on lower end mobiles. Addy’s research confirms that on an average phone an app will take 16 seconds to reach an interactive state, compared to 8 seconds on a desktop. It’s crucial to analyse these metrics, and fortunately, we can do so through Chrome DevTools.
apps在解析和编译后是否可用,分析其中的耗时至关重要。所耗时间因用户设备的硬件功能而异。在低端手机解析和编译比高端手机上慢2-5倍。Addy的研究证实,在一般手机上,一个应用程序将需要16秒才能正常使用,而在桌面上为8秒。分析这些指标至关重要,幸运的是,我们可以通过Chrome DevTools来实现。
Investigating parse and compile in Chrome Dev Tools
在Chrome开发工具中调查解析和编译
Make sure to read Addy Osmani’s detailed write-up on JavaScript Start-up Performance.
请务必阅读Addy Osmani对JavaScript性能优化的详细说明。
去除不必要的依赖
Get rid of unnecessary dependencies
The way modern package managers work can easily obscure the number and the size of dependencies. webpack-bundle-analyzer and Bundle Buddy are great, visual tools helping identify code duplication, biggest performance offenders and outdated, unnecessary dependencies.
现代软件包管理器的工作方式可以轻而易举地掩盖依赖包的数量和大小。webpack-bundle-analyzer和Bundle Buddy是很好的可视化工具,帮助识别重复代码,最大的性能阻碍和过时的、不必要的依赖。
Webpack bundle analyzer in action.
使用中的Webpack bundle analyzer
We can make imported package cost even more visible with Import Cost extension in VS Code and Atom.
通过导入VS Code和Atom中的扩展,我们可以使包引入成本更加明显。
Import Code VS Code extension.
导入代码VS导入代码扩展。
实现代码拆分
Implement code splitting
Whenever possible, we should only serve the necessary assets to create the desired user experience. Sending a full bundle.js file to the user, including code handling interactions they might never see is less than optimal (imagine downloading JavaScript handling an entire app when visiting a landing page). Similarly, we shouldn’t be universally serving code targeting specific browsers or user agents.
只要有可能,我们只需提供必要的资源来实现所需的用户体验。向用户发送一个完整的bundle.js文件,包括他们可能永远看不到的代码,处理交互效果是不太理想的(假设在访问首页时下载JavaScript处理整个应用程序)。同样,我们不应该普遍投放针对特定浏览器或用户代理的代码。
Webpack, one of the most popular module bundlers, comes with code splitting support. Most straightforward code splitting can be implemented per page (home.js for a landing page, contact.js for a contact page, etc.), but Webpack offers few advanced strategies like dynamic imports or lazy loading that might be worth looking into as well.
Webpack是最受欢迎的模块打包工具之一,支持代码拆分。最明显的是可以每页实现代码拆分(用于首页的home.js,联系人页面的contact.js等),并且Webpack提供了几个的高级策略,例如动态导入和延迟加载,值得一看。
框架选择的考虑
Consider framework alternatives
JavaScript front-end frameworks are constantly on the rise. According to the State of JavaScript 2016 survey React is the most popular option. Carefully auditing architecture choices though might show that you’d be better off with a much more lightweight alternative such as Preact (note that Preact isn’t trying to be a full React reimplementation, just a highly performant, less featured virtual DOM library). Similarly, we can swap bigger libraries for smaller altrnatives — moment.js for date-fns (or in particular case of moment.js remove unused locales).
JavaScript前端框架不断增加。根据2016年对JavaScript的调查,React是最受欢迎的选择。仔细考虑架构选择,虽然你可能会使用更为轻量级的替代方案(例如Preact)(请注意,Preact不会是一个完整的React重新实现,只是一个高性能,功能较差的虚拟DOM库)。类似地,我们可以用较小的库来替代 - 例如用于date-fns的moment.js(或者是删除moment.js未使用的部分)。
Before starting a new project, it’s worthwhile to determine what kind of features are necessary and pick the most performant framework for your needs and goals. Sometimes that might mean opting for writing more vanilla JavaScript instead.
在开始一个新项目之前,确定什么样的功能是必要的,并为你的需求和目标选择最具性能的框架。不过可能意味着选择写更多的JavaScript代码。
JavaScript performance checklist
- Monitor how much JavaScript is delivered
- Get rid of unnecessary dependencies
- Implement code splitting
- Consider framework alternatives
JavaScript性能清单
- 监控JavaScript的传输
- 避免不必要的依赖
- 代码拆分
- 框架选择的考虑
跟踪性能优化之路
Tracking performance and the road forward
We’ve talked about several strategies that in most cases will yield positive changes to the user experience of products we’re building. Performance can be a tricky beast though, and it’s necessary to track the long-term results of our tweaks.
我们已经讨论过几种策略,在大多数情况下会对我们正在建立的产品的用户体验产生积极的变化。性能可能是一个棘手的问题,而且有必要跟踪我们调整的长期结果。
以用户为中心的性能指标
User-centric performance metrics
Great performance metrics aim to be as close to portraying user experience as possible. Long established onLoad, onContentLoaded or SpeedIndex tell us very little about how soon sites can be interacted with. When focusing only on the delivery of assets, it’s not easy to quantify perceived performance. Fortunately, there are a few timings that paint quite a comprehensive picture of how soon content is both visible and interactive.
优秀的性能指标旨在尽可能接近用户体验。长期建立onLoad,onContentLoaded或SpeedIndex告诉我们很少关于网站可以互动多久的信息。当仅关注资源传输时,是不容易确定性能的。幸运的是,有一些时间点的图片可以全面地描述内容的显示和交互过程。
Those metrics are First Paint, First Meaningful Paint, Visually Complete and Time to Interactive.
这些指标是第一次绘制,第一次有意义的绘制,视觉完整和互动时间。
- First Paint: the browser changed from a white screen to the first visual change.
- First Meaningful Paint: text, images and major items are viewable.
- Visually Complete: all content in the viewport is visible.
- Time to Interactive: all content in the viewport is visible and ready to interact with (no major main thread JavaScript activity).
- 第一次绘制:浏览器从白色屏幕到第一次视觉变化。
- 第一次有意义的绘制:文字,图像和主要模块可见。
- 视觉完整:视窗中的所有内容都可见。
- 互动时间:视窗中的所有内容都是可见的,可以随时进行交互(没有主要的JavaScript线程活动)。
These timings directly correspond to what the users see therefore make excellent candidates for tracking. If possible, record all, otherwise pick one or two to have a better understanding of perceived performance. It’s worth keeping an eye on other metrics as well, especially the number of bytes (optimised and unpacked) we’re sending.
这些时间点直接对应于用户看到的优秀性能跟踪。如果可能,记录全部,否则选择一两个来更好地了解感知的表现。值得注意的是其他指标,特别是我们发送的字节数(优化和解压)。
设置性能预算
Setting performance budgets
All of these figures might quickly become confusing and cumbersome to understand. Without actionable goals and targets, it’s easy to lose track of what we’re trying to achieve. A good few years ago Tim Kadlec wrote about the concept of performance budgets.
所有这些数字可能会很快会使理解变得混乱和麻烦。没有可操作的目标和场景,很容易偏离我们正在实现的内容。几年前,Tim Kadlec写了关于性能预算的概念。
Unfortunately, there’s no magical formula for setting them. Often performance budgets boil down to competitive analysis and product goals, which are unique to each business.
不幸的是,没有设置它们的神奇公式。性能预算通常归结为竞争分析和产品目标,这是每个业务都不同的。
When setting budgets, it’s important to aim for a noticeable difference, which usually equals to at least 20% improvement. Experiment and iterate on your budgets, leveraging Lara Hogan’s Approach New Designs with a Performance Budget as a reference.
设定预算时,重要的是要达到明显的效果,通常至少改善20%。实践和迭代您的预算,利用Lara Hogan新设计的方法,作为性能预算参考。
Try out Performance Budget Calculator or Browser Calories Chrome extension to aid in creating budgets.
试用性能预算计算器或浏览器卡路里Chrome扩展程序来帮助建立预算。
持续监测
Continuous monitoring
Monitoring performance shouldn’t be manual. There are quite a few powerful tools offering comprehensive reporting.
监控性能不应该是手动的。有很多强大的工具提供全面的反馈。
Google Lighthouse is an Open Source project auditing performance, accessibility, progressive web apps, and more. It’s possible to use Lighthouse in the command line or as just recently, directly in Chrome Developer Tools.
Google Lighthouse是一个审核性能,可访问性,渐进式网络应用程序等的开源项目。可以在命令行中或直接在Chrome Developer Tools中使用Lighthouse。
Lighthouse performing a performance audit.
Lighthouse执行性能审计。
For continuous tracking opt-in for Calibre that offers performance budgets, device emulation, distributed monitoring and many other features that are impossible to get without carefully building your own performance suite.
根据Calibre的连续跟踪选项,可以提供性能预算,设备仿真,分布式监控和许多其他功能,无需仔细构建自己的性能套件即可获得。
Comprehensive performance tracking in Calibre.
全面的性能跟踪。
Wherever you’re tracking, make sure to make the data transparent and accessible to the entire team, or in smaller organisations, the whole business.
无论您在跟踪什么地方,请确保使整个团队或整个企业的小型组织能够透明地访问数据。
Performance is a shared responsibility, which spans further than developer teams — we’re all accountable for the user experience we’re creating, no matter role or title.
性能是一项共同责任,甚至高于开发团队,我们对所创建的用户体验负责,无论处于什么样的职位和角色。
It’s incredibly important to advocate for speed and establish collaboration processes to catch possible bottlenecks as early as product decisions or design phases.
倡导速度和建立协作流程,在处理产品决策或设计阶段早期可能遇到的瓶颈是非常重要的。
建立性能意识
Building performance awareness and empathy
Caring about performance isn’t only a business goal (but if you need to sell it through sales statistics do so with PWA Stats). It’s about fundamental empathy and putting the best interest of the users first.
关心性能不仅仅是一个业务目标(但是如果您需要通过销售统计数据来进行销售,那么用PWA统计)。基本的共识和使用者的最大利益是第一位。
As technologists, it’s our responsibility not to hijack attention and time people could be happily spending elsewhere. Our objective is to build tools that are conscious of time and human focus.
作为技术专家,不要过分控制注意力和时间,人们可能会乐意花费时间在其他地方。我们的目标是建立可以节省时间和人性化的工具。
Advocating for performance awareness should be everyone’s goal. Let’s build a better, more mindful future for all of us with performance and empathy in mind.
倡导性能意识应该是每个人的目标。让我们通过性能共识建立一个更好,更有意义的未来。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。