Refresh css without reloading page, css defined in App_themes folder and theme referred through webconfig.
I do not have any reference of CSS file on the page, it is done through referring theme name in webconfig.
Tried many ways but failed to get any output:
not able to use versioning like this:
<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">
Tried CSSrefresh.js to automate the process but failed to get the actual result.
So is there anything which refresh my page with the latest css without reloading the page?
EDIT: When you refresh a page, some of the elements in that page (like CSS and JavaScript files, images, etc.) may not be updated from server, because they are cached by the browser, so you may be unable to see your latest updates. What you need to do is to somehow prevent the browser from using the cached version of the files and request these content again.
One way to do it is to disable caching for your CSS or any frequently updated files. To do it in ASP.NET, you change Web.config file in the directory you want the cache to be disabled (in your example App_themes). If that directory does not contain a Web.config file, you can create one. To disable caching completely, you can add the following lines to Web.config (if some XML elements are already present, append new children to them):
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</configuration>
Instead of disabling cache completely, you can set it to a short time, like 5 minutes. To do this, change the clientCache element in the above example to this:
<clientCache cacheControlMaxAge="00.00:05:00" cacheControlMode="UseMaxAge"/>
Bear in mind that disabling caching is a very bad idea and impacts performance very badly and you shall not do it unless absolutely necessary and if all other solutions fail.
A (better) solution to the problem is using versioning (as you mentioned), and it should work. What you do is change the way you link to your CSS file from <link rel="stylesheet" href="style.css"> to <link rel="stylesheet" href="style.css?v=1"> (a version is appended as a parameter). You do not need to change the name of the actual CSS file on disk. Now, the browser will cache style.css?v=1. If your CSS changes and you want this change to be applied immediately, you manually change all links to your CSS and increment the version (<link rel="stylesheet" href="style.css?v=2">). No browser has style.css?v=2 in its cache, so all browsers send a new request to get the file.
Manually changing all CSS references each time they change is very cumbersome. To automate this process, you can use the bundling and minification plug-in in ASP.NET (it is only available in later versions of ASP.NET). Bundling and minification is a very useful optimization technique that you should be using anyway to improve the performance of your site, so enabling it is a good idea. The bundling plug-in, among other things, automatically changes the version parameter once a file changes.
Enabling bundling is a little different depending on your project type (ASP.NET MVC, Web Forms, etc.). Please see documentation on how to use it for MVC here and for Web Forms here.
If you want the style of page to dynamically change, include all theme CSS files in your initial page load, but each theme CSS rule must be edited so its selector only works if there is a specific class name defined in parent. You can then use JavaScript to add/change the class name in the parent node to use different themes.
For example, your CSS would be
.theme1 body { background: red; font: 'sans-serif'; }
.theme2 body { background: blue; font: 'serif'; }
And your HTML would be:
<html class="theme1">
<body>
</body>
</html>
Then if you want to change theme, change class name on HTML element to 'theme2'.
Related
There are many questions asking how to change the theme in Semantic-UI, but I have not been able to find even a question where it refers to changing the theme dynamically, i.e. after a webpack build.
I want to allow each user of a site to save their own preference for the theme. I have some users who prefer dark themes, and others who are color-blind, and others who have weak eyes and need larger fonts, or more contrast, etc.
I know it's possible to change the theme dynamically since the semantic-ui demos all do it. Unfortunately, the Theming page and all documentation I have seen describes how to change the site-wide theme, and apply that, in a new site-wide build. Or to customize that (still) site-wide build.
I think I'd be happy to just be able to add a class to the class list for an element (e.g. "github") and have it use that theme for that user (even if it was just for that element). But ideally, I'd like to have my page load an extra .less or .css file(s) with site-wide overrides for that user, for the user-selected theme.
I'm still pretty new semantic-ui and to applying dynamic changes to a webpack site. Any suggestions for how to apply additional less variable changes after build, or to reload entire Semantic-UI themes, like the demo does?
Note that demo site is not a link to GitHub; it's a look-alike with a paint can icon near the top-right which brings up a sidebar that allows you to change themes. Dynamically.
Update:
I need to test this now, but I may have an answer for my own question here.
It seems that the gulp build process typically compiles and combines all the less and other files into the dist folder as semantic.css, semantic.js, semantic.min.css and semantic.min.js. It also produces different individual component .css files in the dist/components subfolder, but (I think) if you're loading the full css file (e.g. semantic.min.css), that you don't really need the components subfolder. That this is present for those sites who want to optimize to the point of only including the .css files for the components they use?
So it's already processed and combined, and to swap themes, I think all that is necessary is to swap one semantic.min.css file with the output of the build for another theme. The .js files are the same, at least for default vs github themes.
If this is true, it's a matter of copying the semantic.min.css to an alternative file, for example, semantic.github.min.css and use that .css file instead. Or copy it to a theme subfolder like github/semantic.min.css. Then, in either case, update the DOM with a new href on the stylesheet originally referenced.
Summary: It looks like it's all in the semantic*.css file and swapping the output of different builds allows us to swap themes. I'll test this later tonight.
Update 2:
I updated the theme.config file with all github entries, then rebuilt the dist folder, copied the semantic.min.css as semantic-github.min.css to my static folder with the original, then just updated the href to select it:
// normally: <link rel="stylesheet" type="text/css" href="/static/semantic/semantic.min.css">
// non-default: <link rel="stylesheet" type="text/css" href="/static/semantic/semantic-theme.min.css">
function swapThemeCss (theme) {
console.log('Theme change to "' + theme + '".')
let sheet = document.querySelector('#theme')
if (!sheet) {
return
}
if (theme === 'default') {
sheet.setAttribute('href', '/static/semantic/semantic.min.css')
} else {
sheet.setAttribute('href', '/static/semantic/semantic-' + theme + '.min.css')
}
}
Oh also, in the example above, I gave the link an id of 'theme' to make it easier to find it and replace the href dynamically:
<link id="theme" rel="stylesheet" type="text/css" href="/static/semantic/semantic.min.css">
"So it's already processed and combined, and to swap themes, I think all that is necessary is to swap one semantic.min.css file with the output of the build for another theme."
Correct.
Depending on whether you're having per-user styles, or just multiple themes the user can pick from, you can simply have separate less files with per-theme overrides that can be compiled with webpack but perhaps not inserted into your index.html. Then you can dynamically add/remove the <link>s to depending on the user preference. The dynamic adding will cause a flicker from the default styles to the per-user theme styles if you're inserting the <link> tags via frontend javascript (because it must wait for the frontend JS to load, which will render the page/default styles in the meantime, then inject the new <link> and only show the new styles once those have been loaded). Add the per-user <link> tags serverside to make it seamless.
my platform delivers some similar widgets on the same webpage. These widgets are embedded on iframes, and share the same CSS definition among them.
Current version loads this definition using <link rel="stylesheet"> tag. But, I am thinking to change loading strategy to css inline definition inside <style> tag.
Load base javascript on target page
Create a hidden iframe, and load CSS <link> on it (async document.write call)
Set this CSS content into javascript var on target page context.
Steps 1 and 2 are already implemented and working. Now, how should step 3 be implemented?
After some new tests, I'll post here any positive results.
You don't want to use Javascript for something that can be done (or at least done easily) with pure CSS. There are a lot of people who don't have JS enabled...I don't think you want to limit their access to your site. What you are looking for can be done with the CSS #import rule. It's pretty simple -- all you need to do is place #import "path/to/css/file" above all your other style rules. The path is relative to the current stylesheet; if it's in an HTML file then it's relative to the HTML file.
For example, if you had a domain like stackunderflow.com, a stylesheet in the top-level folder, and a stylesheet called style2.css in a folder called extra-styles, then you could import the stylesheet from extra-styles via a relative path: #import "extra-styles/style2.css" Another good thing about this is that it's supported in almost all browsers.
I have developed a mobile application which loads 3 css and 7 javascript files. Problem is if the wifi signal is very slow, HTML loads before all javascript and stylesheets are loaded. Since stylesheet is not loaded, HTML looks disturbed and after few seconds (i guess after css and js are loaded properly), HTML structure automatically take correct format but I dont want to show the disturbed format and to do that I need to make sure that all js files are loaded first then only HTML should display.
If you have any idea how can this be achieved ?
You can do using Cache manifests. Read these resources:
http://appcachefacts.info/
http://en.wikipedia.org/wiki/Cache_manifest_in_HTML5
https://developer.mozilla.org/en/docs/HTML/Using_the_application_cache
Alternatively - ensure your resources are loaded before the body by placing them in the right place (head tag).
You should link to your external css stylesheet at the top of your webpage in the header like this:
<link rel="stylesheet" type="text/css" href="http://whiterootmedia.com/css/example.css" />
or insert your <style> element in the header. Likewise this should be done for your JavaScript if it effects your initial layout. Keep in mind that if you are using an external JS file, the browser will stop rendering your page at the point in your code where your external JavaScript file is referenced, to load that external JavaScript file. If you're using a lot of JavaScript, place it at the bottom of your page (contrary to what most people do) or use an onload() function.
The webpage is loaded top-to-bottom, so the problems you're having should be related to the order of your css (most likely).
On our site we load stylesheets dynamically based on whether the display is retina or not. Right now, we are using document.write for each <link href="stylesheet.css"> we insert in the page, with different css files if the display is retina.
However, this hurts performance because it causes the css files to load synchronously, as the browser has no way of parsing the javascript to load the next file before the previous one is finished. I believe we can reduce page load time if we take advantage of modern browsers' capability to look ahead and fetch resources asynchronously - in another words, if we load the CSS files in parallel instead.
My current solution is to create a <link id="link-tag-id" href=""> tag for every stylesheet to be loaded, immediately followed by a script which determines the retina status, then fills in the quotations with the appropriate file, along the lines of:
document.getElementById("link-tag-id").setAttribute("href", "retina-stylesheet.css")
This seems to work fine, and when I examine the network waterfalls in Chrome developer tools, as well as on WebPageTest.org (running Chrome, Firefox, and IE), the stylesheets indeed load in parallel. However, it seems a little hacky. I was wondering if there are any dangers to creating a <link> tag with an empty href attribute, and if so, what are they?
On a broader note, are there any other recommendations on how to load CSS dynamically and asynchronously?
Thanks for your help!
EDIT: I just discovered this works too:
document.getElementById("link-tag-id").href = "retina-stylesheet.css"
You could use media queries inside your stylesheet to determine if the display is a retina display, then load in the required CSS.
http://css-tricks.com/snippets/css/retina-display-media-query/
http://mobile.smashingmagazine.com/2010/07/19/how-to-use-css3-media-queries-to-create-a-mobile-version-of-your-website/
If I have an HTML page that includes some JavaScript, for example:
<script type="text/javascript" src="http://example.com/code.js" async></script>
And I want to add some CSS, which of the following 2 options is faster, performance-wise?
Option 1
(More "Network Heavy")
Including the CSS in a separate inline tag, for example:
<link rel="stylesheet" type="text/css" href="http://www.example.com/style.css">
OR
Option 2
(More "JavaScript Execution Heavy", since it requires DOM manipulation) injecting the CSS into the DOM from inside the included JavaScript file, for example (taken from: https://stackoverflow.com/a/707580/1785003]1):
var css = document.createElement("style");
var css = "text/css";
css.innerHTML = "strong { color: red }";
document.body.appendChild(css);
The 2nd option removes a network request from the page, but requires DOM manipulation, which might be costly in Mobile Device browsers.
So which is better?
I do not believe there is much of a difference between a mobile device and regular browser in the way they load and cache pages so I would treat them the same.
Having CSS in your JavaScript is going to be a maintenance nightmare. Probably not worth any tiny (if any) optimisation gain. As Pekka pointed out after initial load it will cached.
You will be better off targeting other performance optimisations first. Like Minify CSS and javascripts, CSS sprites etc . Use a tool such as yslow to help show where performance optimisations can be made.
Also most browsers can make at least 4 concurrent request to the same host so that the CSS and Javascript , HTML can all be downloaded at the same time. See here
Answering from Performance POV:
Using CSS is a better option.
Reason
Performance is not just measured in network bandwidth consumption. JS blocks the rendering of the page till they're completely downloaded.
(Note: html 5 now suports
<script type="text/javascript" src="http://example.com/code.js" async></script>
which frees loading of rest of your markup in parallel.)
Once css is fetched for first time, then it is neither downloaded nor executed (vs javascript). This is delight for returning users.
Solution
Use the external css and keep it at the top of your semantics (in <head> section, preferably).
Use external js and keep it at the bottom of the page (near the </body> tag)
Background:
Have worked with Yahoo! and adhered to their Best Frontend practices.
Put Stylesheets at the Top
Put Scripts at the Bottom
The CSS file will definently render faster, once it's downloaded and processed, since browser are optimised for this. Applying via JS means that you need to wait for the document to load, then seek elements, apply styling, and then allow the browser to do its magic.
In my experience, adding a CSS file for anything more than dynamic behavior by far outweights any "speed" decrease due to maintainability (how easy it is to change something) and because you can actually restyle your page without editing the code part, which can break things (if for instance you change the JS generating the styles and forget a quote, you break the page, and lose all JS for that page).
The only situation where styling via JS is ok for non-dynamic behavior, is when its a few lines all in all, and even then I'm cautious.