~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/net/instaweb/rewriter/public/critical_images_finder.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2012 Google Inc.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 *
8
 
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
// Author: pulkitg@google.com (Pulkit Goyal)
18
 
 
19
 
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_IMAGES_FINDER_H_
20
 
#define NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_IMAGES_FINDER_H_
21
 
 
22
 
#include <map>
23
 
#include <utility>
24
 
 
25
 
#include "net/instaweb/rewriter/critical_images.pb.h"
26
 
#include "net/instaweb/rewriter/public/critical_finder_support_util.h"
27
 
#include "net/instaweb/util/public/basictypes.h"
28
 
#include "net/instaweb/util/public/property_cache.h"
29
 
#include "net/instaweb/util/public/string.h"
30
 
#include "net/instaweb/util/public/string_util.h"
31
 
 
32
 
namespace net_instaweb {
33
 
 
34
 
class GoogleUrl;
35
 
class RenderedImages;
36
 
class RewriteDriver;
37
 
class RewriteOptions;
38
 
class Statistics;
39
 
class Variable;
40
 
 
41
 
typedef std::map<GoogleString, std::pair<int32, int32> >
42
 
    RenderedImageDimensionsMap;
43
 
 
44
 
// The instantiated CriticalImagesFinder is held by ServerContext, meaning
45
 
// there is only 1 per server. CriticalImagesInfo stores all of the request
46
 
// specific data needed by CriticalImagesFinder, and is held by the
47
 
// RewriteDriver.
48
 
// TODO(jud): Instead of a separate CriticalImagesInfo that gets populated from
49
 
// the CriticalImages protobuf value, we could just store the protobuf value in
50
 
// RewriteDriver and eliminate CriticalImagesInfo. Revisit this when updating
51
 
// this class to support multiple beacon responses.
52
 
struct CriticalImagesInfo {
53
 
  CriticalImagesInfo()
54
 
      : is_critical_image_info_present(false) {}
55
 
  StringSet html_critical_images;
56
 
  StringSet css_critical_images;
57
 
  CriticalImages proto;
58
 
  bool is_critical_image_info_present;
59
 
  RenderedImageDimensionsMap rendered_images_map;
60
 
};
61
 
 
62
 
 
63
 
// Finds critical images i.e. images which are above the fold for a given url.
64
 
// This information may be used by DelayImagesFilter.
65
 
class CriticalImagesFinder {
66
 
 public:
67
 
  enum Availability {
68
 
    kDisabled,   // Data will never be forthcoming
69
 
    kNoDataYet,  // Data is expected but we don't have it yet
70
 
    kAvailable,  // Data is available
71
 
  };
72
 
  static const char kCriticalImagesValidCount[];
73
 
  static const char kCriticalImagesExpiredCount[];
74
 
  static const char kCriticalImagesNotFoundCount[];
75
 
  static const char kCriticalImagesPropertyName[];
76
 
  // Property name for the rendered image dimensions retreived from webkit
77
 
  // render response for the page.
78
 
  static const char kRenderedImageDimensionsProperty[];
79
 
 
80
 
  CriticalImagesFinder(const PropertyCache::Cohort* cohort, Statistics* stats);
81
 
  virtual ~CriticalImagesFinder();
82
 
 
83
 
  static void InitStats(Statistics* statistics);
84
 
 
85
 
  // Checks whether IsHtmlCriticalImage will return meaningful results about
86
 
  // critical images. Users of IsHtmlCriticalImage should check this function
87
 
  // and supply default behaviors when Available != kAvailable.
88
 
  virtual Availability Available(RewriteDriver* driver);
89
 
 
90
 
  // In order to handle varying critical image sets returned by the beacon, we
91
 
  // store a history of the last N critical images, and only declare an image
92
 
  // critical if it appears critical in the last M out of N sets reported. This
93
 
  // function returns what percentage of the sets need to include the image for
94
 
  // it be considered critical.
95
 
  virtual int PercentSeenForCritical() const {
96
 
    return kDefaultPercentSeenForCritical;
97
 
  }
98
 
 
99
 
  // Minimum interval to store support for critical image results. This affects
100
 
  // how long we keep around evidence that an image might be critical; we'll
101
 
  // remember the fact for at least SupportInterval beacon insertions if it only
102
 
  // occurs once, and we'll remember it longer if multiple beacons support image
103
 
  // criticality.  By default, SupportInteval() = 1 and we only store one beacon
104
 
  // result. The beacon critical image finder should override this to store a
105
 
  // larger number of sets.
106
 
  virtual int SupportInterval() const {
107
 
    return kDefaultImageSupportInterval;
108
 
  }
109
 
 
110
 
  // Checks whether the requested image is present in the critical set or not.
111
 
  // Users of this function should also check Available() to see if the
112
 
  // implementation of this function returns meaningful results and provide a
113
 
  // default behavior if it does not.  If no critical set value has been
114
 
  // obtained, returns false (not critical).
115
 
  // TODO(jud): It would be simpler to modify these interfaces to take
116
 
  // HtmlElement* instead of GoogleStrings. This would move some complexity in
117
 
  // getting the correct URL from the caller into this function. For instance,
118
 
  // if an image has been modified by LazyloadImages then the actual src we want
119
 
  // to check is in the pagespeed_lazyload_src attribute, not in src.
120
 
  bool IsHtmlCriticalImage(StringPiece image_url, RewriteDriver* driver);
121
 
 
122
 
  bool IsCssCriticalImage(StringPiece image_url, RewriteDriver* driver);
123
 
 
124
 
  // Returns true if rendered dimensions exist for the image_src_url and
125
 
  // populates dimensions in the std::pair.
126
 
  bool GetRenderedImageDimensions(
127
 
      RewriteDriver* driver,
128
 
      const GoogleUrl& image_src_gurl,
129
 
      std::pair<int32, int32>* dimensions);
130
 
 
131
 
  // Get the critical image sets. Returns an empty set if there is no critical
132
 
  // image information.
133
 
  const StringSet& GetHtmlCriticalImages(RewriteDriver* driver);
134
 
  const StringSet& GetCssCriticalImages(RewriteDriver* driver);
135
 
 
136
 
  // Utility functions for manually setting the critical image sets. These
137
 
  // should only be used by unit tests that need to setup a specific set of
138
 
  // critical images. For normal users of CriticalImagesFinder, the critical
139
 
  // images will be populated from entries in the property cache.  Note that
140
 
  // these always return a non-NULL StringSet value (implying "beacon result
141
 
  // received").
142
 
  StringSet* mutable_html_critical_images(RewriteDriver* driver);
143
 
  StringSet* mutable_css_critical_images(RewriteDriver* driver);
144
 
 
145
 
  // Compute the critical images for the driver's url.
146
 
  virtual void ComputeCriticalImages(RewriteDriver* driver) = 0;
147
 
 
148
 
  // Identifies which cohort in the PropertyCache the critical image information
149
 
  // is located in.
150
 
  // TODO(jud): Make this protected. There is a lingering public usage in
151
 
  // critical_images_beacon_filter.cc.
152
 
  const PropertyCache::Cohort* cohort() const { return cohort_; }
153
 
 
154
 
  // Updates the critical images property cache entry. Returns whether the
155
 
  // update succeeded or not. Note that this base implementation does not call
156
 
  // WriteCohort. This should be called in the subclass if the cohort is not
157
 
  // written elsewhere. NULL is permitted for the critical image sets if only
158
 
  // one of the html or css sets is being updated, but not the other.
159
 
  bool UpdateCriticalImagesCacheEntryFromDriver(
160
 
      const StringSet* html_critical_images_set,
161
 
      const StringSet* css_critical_images_set,
162
 
      RewriteDriver* driver);
163
 
 
164
 
  // Setup the HTML and CSS critical image sets in critical_images_info from the
165
 
  // property_value. Return true if property_value had a value, and
166
 
  // deserialization of it succeeded.  Here because helper code needs access to
167
 
  // it.
168
 
  static bool PopulateCriticalImagesFromPropertyValue(
169
 
      const PropertyValue* property_value, CriticalImages* critical_images);
170
 
 
171
 
  // Alternative interface to update the critical images cache entry. This is
172
 
  // useful in contexts like the beacon handler where the RewriteDriver for the
173
 
  // original request no longer exists.
174
 
  static bool UpdateCriticalImagesCacheEntry(
175
 
      const StringSet* html_critical_images_set,
176
 
      const StringSet* css_critical_images_set,
177
 
      const RenderedImages* rendered_images_set,
178
 
      int support_interval,
179
 
      const PropertyCache::Cohort* cohort,
180
 
      AbstractPropertyPage* page);
181
 
 
182
 
  // Returns true if the critical images are available, false otherwise. This is
183
 
  // virtual only to be overridden in tests.
184
 
  virtual bool IsCriticalImageInfoPresent(RewriteDriver* driver);
185
 
 
186
 
  // Extracts rendered images' dimensions from property cache.
187
 
  virtual RenderedImages* ExtractRenderedImageDimensionsFromCache(
188
 
      RewriteDriver* driver);
189
 
 
190
 
  // Adds the given url to the html critical image set for the driver.
191
 
  void AddHtmlCriticalImage(const GoogleString& url,
192
 
                            RewriteDriver* driver);
193
 
 
194
 
  // Parses Json map returned from beacon js and populates RenderedImages proto.
195
 
  // Caller takes ownership of the returned pointer.
196
 
  RenderedImages* JsonMapToRenderedImagesMap(const GoogleString& str,
197
 
                                             const RewriteOptions* options);
198
 
 
199
 
  // Returns true if it's time to inject a beacon onto the page. The default
200
 
  // finder doesn't use beaconing, so it always returns false.
201
 
  virtual bool ShouldBeacon(RewriteDriver* driver) { return false; }
202
 
 
203
 
  // Check property cache state and prepare to insert beacon.  Returns the
204
 
  // metadata where result.status == kDoNotBeacon if no beaconing should occur,
205
 
  // and result.nonce contains the nonce if required (default implementation
206
 
  // always beacons without a nonce).
207
 
  virtual BeaconMetadata PrepareForBeaconInsertion(RewriteDriver* driver) {
208
 
    BeaconMetadata result;
209
 
    result.status = kBeaconNoNonce;
210
 
    return result;
211
 
  }
212
 
 
213
 
  // For implementations that use beaconing, update the candidate images in the
214
 
  // property cache. New images are a signal that we should beacon more often
215
 
  // for a few requests. The beaconing argument should indicate if the current
216
 
  // request is injecting a beacon. If so, we don't need to trigger a beacon on
217
 
  // the next request even if the candidate images have changed.
218
 
  virtual void UpdateCandidateImagesForBeaconing(const StringSet& images,
219
 
                                                 RewriteDriver* driver,
220
 
                                                 bool beaconing) {}
221
 
 
222
 
 protected:
223
 
  // Completes a critical image set update operation and writes the data back to
224
 
  // the property cache.
225
 
  static bool UpdateAndWriteBackCriticalImagesCacheEntry(
226
 
      const StringSet* html_critical_images_set,
227
 
      const StringSet* css_critical_images_set,
228
 
      const RenderedImages* rendered_images_set,
229
 
      int support_interval,
230
 
      const PropertyCache::Cohort* cohort,
231
 
      AbstractPropertyPage* page,
232
 
      CriticalImages* critical_images);
233
 
 
234
 
  // Gets critical images if present in the property cache and updates the
235
 
  // critical_images set in RewriteDriver with the obtained set.  If you
236
 
  // override this method, driver->critical_images_info() must not return NULL
237
 
  // after this function has been called.
238
 
  virtual void UpdateCriticalImagesSetInDriver(RewriteDriver* driver);
239
 
 
240
 
  virtual GoogleString GetKeyForUrl(StringPiece url) { return url.as_string(); }
241
 
 
242
 
  // Extracts the critical images from the given property_value into
243
 
  // critical_images_info, after checking if the property value is still valid
244
 
  // using the provided TTL.  It also updates stats variables.
245
 
  CriticalImagesInfo* ExtractCriticalImagesFromCache(
246
 
      RewriteDriver* driver,
247
 
      const PropertyValue* property_value);
248
 
 
249
 
 private:
250
 
  friend class CriticalImagesFinderTestBase;
251
 
 
252
 
  // Update a CriticalImages protobuf value with new critical image sets. If
253
 
  // either of the html or css sets are NULL, those fields in critical_images
254
 
  // will not be updated. Returns true if either of the critical image sets in
255
 
  // critical_images was updated.
256
 
  static bool UpdateCriticalImages(const StringSet* html_critical_images,
257
 
                                   const StringSet* css_critical_images,
258
 
                                   int support_interval,
259
 
                                   CriticalImages* critical_images);
260
 
 
261
 
  // By default, store 1 critical image set and require an image to be in that
262
 
  // set for it to be critical.
263
 
  static const int kDefaultPercentSeenForCritical = 100;
264
 
  static const int kDefaultImageSupportInterval = 1;
265
 
 
266
 
  const PropertyCache::Cohort* cohort_;
267
 
 
268
 
  Variable* critical_images_valid_count_;
269
 
  Variable* critical_images_expired_count_;
270
 
  Variable* critical_images_not_found_count_;
271
 
 
272
 
  DISALLOW_COPY_AND_ASSIGN(CriticalImagesFinder);
273
 
};
274
 
 
275
 
}  // namespace net_instaweb
276
 
 
277
 
#endif  // NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_IMAGES_FINDER_H_