OLD | NEW |
(Empty) | |
| 1 # Optimizing Chrome Web UIs |
| 2 |
| 3 ## How do I do it? |
| 4 |
| 5 In order to build with a fast configuration, try setting these options in your |
| 6 GN args: |
| 7 |
| 8 ``` |
| 9 use_vulcanize = true |
| 10 is_debug = false |
| 11 ``` |
| 12 |
| 13 If you make local changes, you likely need to re-run: |
| 14 |
| 15 ``` |
| 16 $ chrome/browser/resources/vulcanize.py |
| 17 ``` |
| 18 |
| 19 And rebuild Chrome to see effects. vulcanize.py will result in local changes to |
| 20 *crisper* and *vulcanized* files that you must currently check in. |
| 21 |
| 22 *NOTE: Vuclanize is being integrated directly into |
| 23 [GN/Ninja](https://crbug.com/673825), so this workflow is likely to change |
| 24 soon.* |
| 25 |
| 26 ## How is the code optimized? |
| 27 |
| 28 ### Resource combination |
| 29 |
| 30 [HTML imports](https://www.html5rocks.com/en/tutorials/webcomponents/imports/) |
| 31 are a swell technology, but can be used is slow ways. Each import may also |
| 32 contain additional imports, which must be satisfied before certain things can |
| 33 continue (i.e. script execution may be paused). |
| 34 |
| 35 ```html |
| 36 <!-- If a.html contains more imports... --> |
| 37 <link rel="import" href="a.html"> |
| 38 <!-- This script is blocked until done. --> |
| 39 <script> startThePageUp(); </script> |
| 40 ``` |
| 41 |
| 42 To reduce this latency, Chrome uses a tool created by the Polymer project named |
| 43 [vulcanize](https://github.com/Polymer/polymer-bundler/tree/1.x). It processes |
| 44 a page starting from a URL entry point and inlines resources the first time |
| 45 they're encountered. This greatly decreases latency due to HTML imports. |
| 46 |
| 47 ```html |
| 48 <!-- Contents of a.html and all its dependencies. --> |
| 49 <script> startThePageUp(); </script> |
| 50 ``` |
| 51 |
| 52 ### CSS @apply to --var transformation |
| 53 |
| 54 We also use |
| 55 [polymer-css-build](https://github.com/PolymerLabs/polymer-css-build) to |
| 56 transform CSS @apply mixins (which are not yet natively supported) into faster |
| 57 --css-variables. This turns something like this: |
| 58 |
| 59 ```css |
| 60 :host { |
| 61 --mixin-name: { |
| 62 color: red; |
| 63 display: block; |
| 64 }; |
| 65 } |
| 66 /* In a different place */ |
| 67 .red-thing { |
| 68 @apply(--mixin-name); |
| 69 } |
| 70 ``` |
| 71 |
| 72 into the more performant: |
| 73 |
| 74 ```css |
| 75 :host { |
| 76 --mixin-name_-_color: red; |
| 77 --mixin-name_-_display: block; |
| 78 } |
| 79 /* In a different place */ |
| 80 .red-thing { |
| 81 color: var(--mixin-name_-_color); |
| 82 display: var(--mixin-name_-_display); |
| 83 } |
| 84 ``` |
| 85 |
| 86 ### JavaScript Minification |
| 87 |
| 88 In order to minimize disk size, we run |
| 89 [uglifyjs](https://github.com/mishoo/UglifyJS2) on all combined JavaScript. This |
| 90 reduces installer and the size of resources required to load to show a UI. |
| 91 |
| 92 Code like this: |
| 93 |
| 94 ```js |
| 95 function fizzBuzz() { |
| 96 for (var i = 1; i <= 100; i++) { |
| 97 var fizz = i % 3 == 0 ? 'fizz' : ''; |
| 98 var buzz = i % 5 == 0 ? 'buzz' : ''; |
| 99 console.log(fizz + buzz || i); |
| 100 } |
| 101 } |
| 102 fizzBuzz(); |
| 103 ``` |
| 104 |
| 105 would be minified to: |
| 106 |
| 107 ```js |
| 108 function fizzBuzz(){for(var z=1;100>=z;z++){var f=z%3==0?"fizz":"",o=z%5==0?"buz
z":"";console.log(f+o||z)}}fizzBuzz(); |
| 109 ``` |
| 110 |
| 111 If you'd like to more easily debug minified code, click the "{}" prettify button |
| 112 in Chrome's developer tools, which will beautify the code and allow setting |
| 113 breakpoints on the un-minified version. |
| 114 |
| 115 ### Gzip compression of web resources |
| 116 |
| 117 In certain cases, it might be preferable to leave web resources compressed on |
| 118 disk and inflate them when needed (i.e. when a user wants to see a page). |
| 119 |
| 120 In this case, you can run `gzip --rsyncable` on a resource before it's put into |
| 121 a .pak file via GRIT with this syntax: |
| 122 |
| 123 ```xml |
| 124 <include name="IDR_MY_PAGE" file="my/page.html" type="BINDATA" compress="gzip" /
> |
| 125 ``` |
| 126 |
| 127 Gzip is currently set up to apply to a whole WebUI's data source, though it's |
| 128 possible to exclude specific paths for things like dynamically generated content |
| 129 (i.e. many pages load translations dynamically from a path named "strings.js"). |
| 130 |
| 131 To mark a WebUI's resources compressed, you'll need to do something like: |
| 132 |
| 133 ```c++ |
| 134 WebUIDataSource* data_source = WebUIDataSource::Create(...); |
| 135 data_source->SetDefaultResource(IDR_MY_PAGE); |
| 136 std::unordered_set<std::string> exclusions; |
| 137 exclusions.insert("strings.js"); // if required |
| 138 data_source->UseGzip(exclusions); |
| 139 ``` |
OLD | NEW |