// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddScoped <IBrowserOptimizeCssService, BrowserOptimizeCssService>(); services.AddScoped <ICustomOptimizeCssService, CustomOptimizeCssService>(); services.AddMvc(opt => opt.Filters.Add <GlobalExceptionFilter>()); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = ApiName, Version = "v1" }); // UseFullTypeNameInSchemaIds replacement for .NET Core c.CustomSchemaIds(x => x.FullName); }); //just use this to be sure that AngleSharp lib will be loaded var initAngleSharp = AngleSharp.Configuration.Default.GetType(); //Register popular encoding providers (to be able parse response from http client) Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); //Register options var chromeSessionPoolConfig = Configuration.GetSection(ConfigurationConstants.CHROME_SESSION_POOL_CONFIGURATION_SECTION); services.Configure <CacheConfiguration>(Configuration.GetSection(ConfigurationConstants.CACHE_CONFIGURATION_SECTION)); services.Configure <ChromeSessionPoolConfiguration>(chromeSessionPoolConfig); //Don't wait until chrome sessions pool will be initialize. //In production probably will be better to wait. var chromeSessionPoolConfigObject = chromeSessionPoolConfig.Get <ChromeSessionPoolConfiguration>(); if (chromeSessionPoolConfigObject.IsPreInitializeChromeSessionPool) { if (chromeSessionPoolConfigObject.WaitForInitializing) { Task.WaitAll(ChromeSessionPool.InitPool(chromeSessionPoolConfigObject)); } else { ChromeSessionPool.InitPool(chromeSessionPoolConfigObject); } } }
private async Task <string> GetMinCssForUrlAsync(string url) { //Take from cache if exists if (_cache.Get <string>(url) != null) { return(_cache.Get <string>(url)); } //Take available session from pool var chromeSession = ChromeSessionPool.GetInstance(); try { //Navigate to page, enable and start rule usage tracking await chromeSession.InternalSession.DOM.Enable(new DOM.EnableCommand()); await chromeSession.InternalSession.CSS.Enable(new CSS.EnableCommand()); await chromeSession.InternalSession.CSS.StartRuleUsageTracking(new CSS.StartRuleUsageTrackingCommand()); await chromeSession.InternalSession.Page.Navigate(new NavigateCommand { Url = url }); var rules = new List <RuleUsage>(); TakeCoverageDeltaCommandResponse coverageResponse; //TODO: smart logic to wait report, currently just wait when delta == 0 var waitCount = 0; do { //https://chromedevtools.github.io/devtools-protocol/tot/CSS#method-takeCoverageDelta coverageResponse = await chromeSession.InternalSession.CSS.TakeCoverageDelta(new TakeCoverageDeltaCommand()); coverageResponse.Coverage = coverageResponse.Coverage ?? new RuleUsage[0]; //If no found.. sleep and try it again if (coverageResponse.Coverage.Length == 0) { Thread.Sleep(++waitCount * 100); //try again after sleep //timeout 120 seconds coverageResponse = await chromeSession.InternalSession.CSS.TakeCoverageDelta(new TakeCoverageDeltaCommand()); coverageResponse.Coverage = coverageResponse.Coverage ?? new RuleUsage[0]; rules.AddRange(coverageResponse.Coverage); //if found, reset sleep count, because it means that chrome is processing css if (coverageResponse.Coverage.Length > 0) { waitCount = 0; } } }while (coverageResponse.Coverage.Length != 0 || waitCount <= 3); //Stop tacking await chromeSession.InternalSession.CSS.StopRuleUsageTracking(new CSS.StopRuleUsageTrackingCommand()); //Get stylesheets var usedRules = rules.Where(r => r.Used).ToList(); var styleSheetIds = usedRules.Select(r => r.StyleSheetId).Distinct(); var styleSheets = styleSheetIds.Select(s => new { chromeSession.InternalSession.CSS.GetStyleSheetText(new GetStyleSheetTextCommand { StyleSheetId = s }).Result.Text, StyleSheetId = s }).ToList(); //Get only used css, and constrcut it var usedCssStrb = new StringBuilder(); foreach (var rule in usedRules) { var styleSheetText = styleSheets.First(s => s.StyleSheetId.Equals(rule.StyleSheetId)).Text; var ruleString = styleSheetText.Substring((int)rule.StartOffset, (int)rule.EndOffset - (int)rule.StartOffset); usedCssStrb.Append(ruleString); } //minimize CSS var minCss = Uglify.Css(usedCssStrb.ToString()).Code; //Cache it for one hour _cache.Set(url, minCss, TimeSpan.FromSeconds(_cacheConfiguration.UrlCacheTime)); return(minCss); } finally { //Free up resource ChromeSessionPool.ReleaseInstance(chromeSession); } }
private void OnShutdown() { ChromeSessionPool.Dispose(); }
public Task <IEnumerable <ChromeSession> > GetActiveSessions() { return(ChromeSessionPool.GetActiveSessions()); }